ลิงก์ติดตั้งและ Deep Link
ลิงก์ติดตั้งช่วยให้คุณแจกจ่าย Stripe App ของคุณนอกมาร์เก็ตเพลสได้ ส่วน deep link จะพาผู้ใช้ไปยังหน้าที่ต้องการภายในแอปที่ติดตั้งไว้แล้วโดยตรง ทั้งสองอย่างจำเป็นต่อการเริ่มต้นใช้งานและขั้นตอนการเชื่อมต่อที่ราบรื่น
ลิงก์ติดตั้ง
ลิงก์ติดตั้งคือ URL ที่ร้านค้าใช้ติดตั้งแอปของคุณได้โดยตรง เมื่อผู้ใช้คลิกลิงก์ติดตั้ง Stripe จะจัดการขั้นตอนการติดตั้งให้ แล้วรีไดเรกต์กลับมายัง URI ที่คุณระบุไว้
สิ่งที่ต้องเตรียม
ก่อนใช้ลิงก์ติดตั้ง ให้กำหนดค่า allowed_redirect_uris ใน manifest ของแอป:
{ "id": "com.tajo.brevo-integration", "allowed_redirect_uris": [ "https://tajo.io/stripe/callback", "https://tajo.io/stripe/oauth/complete" ]}รูปแบบของลิงก์ติดตั้ง
https://marketplace.stripe.com/oauth/v2/authorize?client_id=APP_ID&redirect_uri=REDIRECT_URI&state=STATE_VALUE| พารามิเตอร์ | จำเป็น | คำอธิบาย |
|---|---|---|
client_id | ใช่ | ID ของแอปคุณ (เช่น com.tajo.brevo-integration) |
redirect_uri | ใช่ | ต้องตรงกับค่าใดค่าหนึ่งใน allowed_redirect_uris |
state | แนะนำ | สตริงสุ่มสำหรับป้องกัน CSRF |
พารามิเตอร์ในการรีไดเรกต์
หลังการติดตั้งสำเร็จ Stripe จะรีไดเรกต์ผู้ใช้ไปยัง redirect_uri ของคุณพร้อม query parameter เหล่านี้:
| พารามิเตอร์ | คำอธิบาย |
|---|---|
user_id | Stripe user ID ของบัญชีที่ทำการติดตั้ง |
account_id | Stripe account ID (เช่น acct_xxxxx) |
state | ค่า state ที่คุณส่งไป (ใช้ตรวจสอบ CSRF) |
install_signature | ลายเซ็น HMAC สำหรับยืนยันว่าการติดตั้งนั้นถูกต้อง |
ตัวอย่าง URL ที่รีไดเรกต์กลับมา:
https://tajo.io/stripe/callback ?user_id=usr_xxxxx &account_id=acct_xxxxx &state=abc123random &install_signature=sig_xxxxxการป้องกัน CSRF
ใช้พารามิเตอร์ state เสมอเพื่อป้องกันการโจมตีแบบ cross-site request forgery:
import crypto from 'crypto';
// Generate a random state value and store it in the sessionconst generateInstallLink = (req, res) => { const state = crypto.randomBytes(32).toString('hex');
// Store state in session for later verification req.session.stripeInstallState = state;
const installUrl = new URL('https://marketplace.stripe.com/oauth/v2/authorize'); installUrl.searchParams.set('client_id', 'com.tajo.brevo-integration'); installUrl.searchParams.set('redirect_uri', 'https://tajo.io/stripe/callback'); installUrl.searchParams.set('state', state);
res.redirect(installUrl.toString());};
// Handle the redirect callbackconst handleInstallCallback = async (req, res) => { const { state, user_id, account_id, install_signature } = req.query;
// Verify state matches what we stored if (state !== req.session.stripeInstallState) { return res.status(403).json({ error: 'Invalid state parameter' }); }
// Clear the stored state delete req.session.stripeInstallState;
// Verify the install signature if (!verifyInstallSignature(install_signature, account_id)) { return res.status(403).json({ error: 'Invalid install signature' }); }
// Process the successful installation await processInstallation(user_id, account_id);
res.redirect('/dashboard/stripe-connected');};การตรวจสอบลายเซ็น
ตรวจสอบ install_signature ด้วย signing secret ของแอปคุณ:
import crypto from 'crypto';
const verifyInstallSignature = (signature, accountId) => { const signingSecret = process.env.STRIPE_APP_SIGNING_SECRET;
const expectedSignature = crypto .createHmac('sha256', signingSecret) .update(accountId) .digest('hex');
return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) );};Caution
ใช้ crypto.timingSafeEqual ในการเปรียบเทียบลายเซ็นเสมอ เพื่อป้องกันการโจมตีแบบ timing attack อย่าใช้การเปรียบเทียบสตริงแบบธรรมดา (===)
Signing secret
Signing secret ของแอปคุณดูได้ใน Stripe Dashboard ที่หน้าการตั้งค่าของแอป ใช้สำหรับ:
- ตรวจสอบลายเซ็นการติดตั้งจาก redirect callback
- ตรวจสอบความถูกต้องของ webhook payload จาก Stripe
- ยืนยันตัวตนของคำขอระหว่างแบ็กเอนด์ของคุณกับ Stripe
จัดเก็บ signing secret อย่างปลอดภัย:
# Set as environment variableexport STRIPE_APP_SIGNING_SECRET="whsec_xxxxx"อย่าฝัง signing secret ไว้ในซอร์สโค้ด และอย่าคอมมิตเข้าระบบควบคุมเวอร์ชัน
Deep Link
Deep link พาผู้ใช้ไปยังหน้าที่ต้องการภายใน Stripe App ที่ติดตั้งไว้แล้วโดยตรง ใช้เพื่อนำผู้ใช้จากช่องทางสื่อสารภายนอก (อีเมล การแจ้งเตือน หน้าสนับสนุน) มายังบริบทที่เกี่ยวข้องในแอป
รูปแบบ URL ของ deep link
https://dashboard.stripe.com/MODE/acct_ID/PAGE?apps[APP_ID][TARGET]=VIEWPORT_ID| ส่วนประกอบ | คำอธิบาย | ตัวอย่าง |
|---|---|---|
MODE | live หรือ test | live |
acct_ID | Stripe account ID ปลายทาง | acct_1234567890 |
PAGE | พาธของหน้าในแดชบอร์ด | customers/cus_xxxxx |
APP_ID | ID ของแอปคุณ | com.tajo.brevo-integration |
TARGET | drawer หรือ modal | drawer |
VIEWPORT_ID | viewport ที่ต้องการเปิด | stripe.dashboard.customer.detail |
เป้าหมายแบบ drawer และ modal
| เป้าหมาย | พฤติกรรม | กรณีใช้งาน |
|---|---|---|
drawer | เปิดแอปในแผงด้านข้าง (drawer) | การใช้งานแอปแบบปกติ ดูบริบทควบคู่ไปกับหน้าเดิม |
modal | เปิดแอปเป็น modal เต็มหน้าจอ | เวิร์กโฟลว์ที่ต้องโฟกัส การเริ่มต้นใช้งาน ฟอร์มที่ซับซ้อน |
ตัวอย่าง deep link
เปิดหน้ารายละเอียดลูกค้าใน drawer
https://dashboard.stripe.com/live/acct_xxxxx/customers/cus_xxxxx ?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.customer.detailเปิดการตั้งค่าใน modal
https://dashboard.stripe.com/live/acct_xxxxx/settings ?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.settingsเปิดขั้นตอนการเริ่มต้นใช้งาน
https://dashboard.stripe.com/live/acct_xxxxx/dashboard ?apps[com.tajo.brevo-integration][modal]=stripe.dashboard.onboardingเปิดหน้ารายละเอียดการชำระเงินในโหมดทดสอบ
https://dashboard.stripe.com/test/acct_xxxxx/payments/pi_xxxxx ?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.payment.detailสร้าง deep link ด้วยโค้ด
const generateDeepLink = ({ accountId, mode = 'live', page, appId = 'com.tajo.brevo-integration', target = 'drawer', viewport,}) => { const baseUrl = `https://dashboard.stripe.com/${mode}/${accountId}/${page}`; const params = new URLSearchParams(); params.set(`apps[${appId}][${target}]`, viewport);
return `${baseUrl}?${params.toString()}`;};
// Generate a link to view a customer's Brevo profileconst customerLink = generateDeepLink({ accountId: 'acct_xxxxx', page: 'customers/cus_xxxxx', viewport: 'stripe.dashboard.customer.detail',});
// Generate a link to app settingsconst settingsLink = generateDeepLink({ accountId: 'acct_xxxxx', page: 'settings', viewport: 'stripe.dashboard.settings', target: 'modal',});ใช้ deep link ในการสื่อสาร
Deep link มีประโยชน์เป็นพิเศษใน:
- อีเมลแจ้งเตือน: “ดูสถานะการซิงค์ Brevo ของลูกค้ารายนี้”
- การตอบกลับของฝ่ายสนับสนุน: “คลิกที่นี่เพื่อตรวจสอบการตั้งค่าการเชื่อมต่อของคุณ”
- อีเมลเริ่มต้นใช้งาน: “ตั้งค่า Brevo ของคุณให้เสร็จสมบูรณ์”
- การแจ้งเตือนข้อผิดพลาด: “ตรวจสอบปัญหาการซิงค์ของลูกค้า X”
<!-- Example in an email template --><a href="https://dashboard.stripe.com/live/acct_xxxxx/customers/cus_xxxxx?apps[com.tajo.brevo-integration][drawer]=stripe.dashboard.customer.detail"> View Brevo Profile in Stripe</a>ใช้ลิงก์ติดตั้งร่วมกับ deep link
เพื่อประสบการณ์เริ่มต้นใช้งานที่ดีที่สุด ให้ใช้ลิงก์ติดตั้งควบคู่กับ deep link หลังการติดตั้ง:
- ผู้ใช้คลิกลิงก์ติดตั้งจากเว็บไซต์หรืออีเมลของคุณ
- ผู้ใช้ติดตั้งแอปแล้วถูกรีไดเรกต์ไปยัง callback URL ของคุณ
- callback ของคุณประมวลผลการติดตั้ง แล้วรีไดเรกต์ผู้ใช้ไปยัง deep link ที่เปิด viewport สำหรับการเริ่มต้นใช้งาน
const handleInstallCallback = async (req, res) => { const { account_id, install_signature, state } = req.query;
// Verify state and signature // ... (verification code)
// Process installation await processInstallation(account_id);
// Redirect to the app's onboarding view via deep link const onboardingLink = generateDeepLink({ accountId: account_id, page: 'dashboard', viewport: 'stripe.dashboard.onboarding', target: 'modal', });
res.redirect(onboardingLink);};Tip
ทดสอบลิงก์ติดตั้งและ deep link ทั้งในโหมด live และ test เสมอ เพื่อให้มั่นใจว่าทำงานได้ถูกต้องในทุกสภาพแวดล้อม