綁卡/快捷/定期付款串接
場景介紹
本模式支援四種業務場景:
| 場景 | 說明 | 顧客是否在場 |
|---|---|---|
| 純綁卡(CardBind) | 顧客只綁定信用卡,不做付款。特店可傳入任意金額,系統固定以 1 元進行綁卡作業 | ✅ 在場 |
| 付款並綁卡(CardBindPayment) | 顧客一邊付款,一邊儲存卡片,下次無需再輸入卡號 | ✅ 在場 |
| 快捷付款(QuickPayment) | 已綁卡的顧客再次購物,直接使用已儲存的卡片快速結帳 | ✅ 在場 |
| 定期扣款(Recurring) | 特店在顧客離場後,透過已儲存的卡片定期主動發起扣款 | ❌ 不在場 |
同一顧客重複綁定相同卡片時,SHOPLINE Payments 不會產生重複的付款工具 ID,會回覆第一次綁定的付款工具資訊。
前置準備:必讀參數對照表
SDK 和 API 是聯動的,兩側各有自己的參數。以下是綁卡場景下的核心對照關係:
| 術語 | 屬於 | 說明 |
|---|---|---|
referenceCustomerId | API 請求 | 特店側顧客的唯一標識(由特店自行定義) |
customerId / paymentCustomerId | API 回應 / 請求 | SLP 會員 ID。綁卡交易成功後由 SLP 自動建立並在回應中提供,後續快捷付款和定期扣款時需作為 paymentCustomerId 傳入 |
customerToken | SDK 初始化 | 臨時授權 token,由 customerId 透過會員 API 生成,有一定有效時間限制。傳入 SDK 後,SDK 自動載入該會員的已綁卡片列表,供顧客選擇後付款 |
三者的關係:referenceCustomerId(特店自訂)→ 查詢會員 API → 取得 customerId(SLP 會員 ID)→ 生成 customerToken(臨時 token,有時間限制)→ 傳給 SDK。三個是完全不同的東西,不可混用。
SDK 綁卡參數說明
在 SDK 初始化時,可透過 paymentInstrument.bindCard 控制綁卡行為:
ShoplinePayments({
// ... 其餘參數
paymentInstrument: {
bindCard: {
enable: true, // 啟用綁卡功能
protocol: {
switchVisible: false, // 是否顯示綁卡勾選框
// true = 顯示,顧客可自行選擇是否綁卡
// false = 不顯示,顧客無法取消綁卡
defaultSwitchStatus: true, // 當 switchVisible: true 時有效
// true = 預設勾選
// false = 預設不勾選
mustAccept: false, // 當 switchVisible: true 時有效
// true = 顧客必須勾選才能提交付款
// false = 不勾選也可以提交付款(即顧客可以自行選擇不綁卡付款)
textType: {
paymentAgreement: false, // 是否顯示「信用卡交易協議」文字
subscribeAgreement: false, // 是否顯示「定期購物信用卡代扣協議」文字
},
},
},
},
})
常見組合
| 特店需求 | switchVisible | defaultSwitchStatus | mustAccept | 顧客行為 |
|---|---|---|---|---|
| 顧客可自行選擇是否綁卡(預設勾選) | true | true | false | SDK 顯示勾選框,預設勾選,顧客可取消 |
| 顧客可自行選擇是否綁卡(預設不勾) | true | false | false | SDK 顯示勾選框,預設不勾,顧客可主動勾選 |
| 強制綁卡,顧客無法取消 | false | — | — | SDK 不顯示勾選框,顧客提交時自動綁卡,無法選擇不綁 |
| 強制綁卡,且必須勾選才能提交 | true | true | true | SDK 顯示勾選框,顧客必須勾選才能提交 |
技術串接過程
Step 1:取得串接金鑰
- 在 SHOPLINE Payments 後台查看特店的 MerchantId
- 在後台「設定 → 開發者管理」產生 clientKey(用於 SDK)和 apiKey(用於 Server-API)
Step 2:串接 Server-API
| 介面 | 用途 |
|---|---|
| 建立付款交易 | 建立交易、觸發授權。所有場景必接 |
| 交易通知 Event | 接收交易結果 Webhook。所有場景必接 |
| 付款交易查詢 | 主動查詢交易結果(對 Webhook 做兜底) |
| 建立退款交易 | 對已成功交易發起退款 |
| 會員查詢 | 根據 referenceCustomerId 查詢 SLP 會員 ID(快捷付款 / 定期扣款場景) |
| 付款工具列表 | 查詢顧客已綁定的卡片資訊 |
| 解綁付款工具 | 解除顧客已綁定的卡片 |
Step 3:引入 JS SDK
參照 SDK 串接 引入 SDK 並準備容器。
場景一:純綁卡(CardBind)
業務場景:顧客只提交信用卡資訊進行身分驗證和綁卡,不實際扣款。無論特店傳入什麼金額,系統固定以 1 元進行綁卡作業,授權成功後自動取消授權。綁卡成功後,該卡儲存到 SLP 會員下,可用於後續快捷付款或定期扣款。
特店串接流程
1. 特店頁面 → 初始化 SDK(可設 bindCard 相關參數控制顧客是否可自行選擇是否綁卡)
2. SDK 渲染收銀台
3. 顧客點擊結帳 → SDK.createPayment() → 取得 paySession
4. 特店 Server 呼叫建立付款交易
5. SLP 完成卡片驗證(以 1 元作業,授權成功後自動取消),返回 tradeOrderId + nextAction
6. SDK.pay(nextAction) → SDK 顯示結果頁
7. Webhook / 查詢 → 拿到 customerId(SLP 會員 ID)
建立付款交易請求參數要點
{
"amount": {
"value": 10000,
"currency": "TWD"
},
"confirm": {
"paymentMethod": "CreditCard",
"paymentBehavior": "CardBind",
"paymentInstrument": {
"savePaymentInstrument": true
}
},
"customer": {
"referenceCustomerId": "CUST_123456"
}
}
| 參數 | 值 | 說明 |
|---|---|---|
paymentBehavior | CardBind | 告訴 SLP 這是一筆純綁卡交易 |
paymentInstrument.savePaymentInstrument | true | 必填。告知 SLP 需要把這張卡存到會員下 |
amount | 任意金額 | 系統固定以 1 元進行綁卡作業,傳什麼金額不影響綁卡結果 |
customer.referenceCustomerId | 特店自訂 | 特店側顧客唯一識別碼,用於關聯特店顧客與 SLP 會員 |
綁卡成功後
API 回應中的 customer.customerId 即為 SLP 會員 ID,請儲存到特店系統中,後續快捷付款和定期扣款都必須傳入。
場景二:付款並綁卡(CardBindPayment)
業務場景:顧客在付款的同時勾選「儲存此卡」,付款成功後卡片自動存入會員,一次操作完成兩件事。
特店串接流程
1. 特店頁面 → 初始化 SDK(可設 bindCard 相關參數控制顧客是否可自行選擇是否綁卡)
2. SDK 渲染收銀台(若 switchVisible: false 則不顯示勾選框,強制綁卡)
3. 顧客輸入卡號 → 勾選(或由 SDK 強制)→ 點擊結帳
4. SDK.createPayment() → 取得 paySession
5. 特店 Server 呼叫建立付款交易
6. SLP 完成授權 + 請款 + 儲存卡片
7. SDK.pay(nextAction) → SDK 顯示結果頁
8. Webhook / 查詢 → 拿到 customerId
建立付款交易請求參數要點
{
"amount": {
"value": 10000,
"currency": "TWD"
},
"confirm": {
"paymentMethod": "CreditCard",
"paymentBehavior": "CardBindPayment",
"paymentInstrument": {
"savePaymentInstrument": true
}
},
"customer": {
"referenceCustomerId": "CUST_123456"
}
}
| 參數 | 值 | 說明 |
|---|---|---|
paymentBehavior | CardBindPayment | 這是一筆帶綁卡的付款 |
paymentInstrument.savePaymentInstrument | true | 必填。付款同時儲存卡片 |
場景三:快捷付款(QuickPayment)
業務場景:顧客已是 SLP 會員且已綁卡,再次購物時無需重新輸入卡號,直接選擇已儲存的卡片完成付款。
前置條件
特店需已儲存顧客的 paymentCustomerId(SLP 會員 ID),此 ID 在首次綁卡成功後由 SLP 回應中提供。
Step 1:查詢 SLP 會員 ID(如特店尚未儲存)
// GET /api/v1/customer/query?referenceCustomerId=CUST_123456
// Header: merchantId, apiKey
// 回應
{
"customerId": "MEMBER_987654",
"referenceCustomerId": "CUST_123456",
"status": "ACTIVE"
}
若查不到,說明該顧客尚未完成首次綁卡,需先走 場景一 或 場景二。
Step 2:生成 customerToken
透過會員 API 以 customerId 生成臨時授權 token,該 token 有時間限制,需在有效期內傳給 SDK:
// POST /api/v1/customer/token
// Header: merchantId, apiKey
{
"customerId": "MEMBER_987654"
}
// 回應
{
"customerToken": "eyJhbGciOi..."
}
Step 3:初始化 SDK(帶入 customerToken)
const { payment, error } = await ShoplinePayments({
clientKey: 'YOUR_CLIENT_KEY',
merchantId: 'YOUR_MERCHANT_ID',
paymentMethod: 'CreditCard',
currency: 'TWD',
amount: 10000,
element: '#paymentContainer',
customerToken: 'eyJhbGciOi...', // Step 2 生成的臨時 token
env: 'sandbox',
})
customerToken 傳入後,SDK 會自動載入該會員的已綁卡片列表,顧客可直接選擇一張卡完成付款,無需重新輸入卡號。
Step 4:建立付款交易
{
"amount": {
"value": 10000,
"currency": "TWD"
},
"confirm": {
"paymentMethod": "CreditCard",
"paymentBehavior": "QuickPayment",
"paymentCustomerId": "MEMBER_987654"
},
"customer": {
"referenceCustomerId": "CUST_123456"
}
}
| 參數 | 值 | 說明 |
|---|---|---|
paymentBehavior | QuickPayment | 使用已儲存的卡片快捷付款 |
paymentCustomerId | SLP 會員 ID | 必填。告知 SLP 使用哪位會員下的哪張卡 |
savePaymentInstrument | 不傳 | 快捷付款場景無需傳 |
快捷付款完整流程總結
1. 特店 Server:referenceCustomerId → 會員查詢 API → customerId
2. 特店 Server:customerId → 生成 token API → customerToken(臨時,有時間限制)
3. 特店頁面:初始化 SDK,傳入 customerToken → SDK 載入卡片列表
4. 顧客選擇一張已儲存的卡片 → 點擊結帳
5. SDK.createPayment() → 取得 paySession
6. 特店 Server 呼叫建立付款交易(傳入 paymentCustomerId)
7. SLP 使用已儲存的卡片完成授權
8. SDK.pay(nextAction) → 顯示結果頁
場景四:定期扣款(Recurring)
業務場景:顧客已綁卡離場後,特店在幕後主動發起扣款,全程不需要顧客在場。常用於訂閱制、會費等場景。
前置條件
- 顧客已完成首次綁卡(場景一 或 場景二)
- 特店已儲存顧客的
paymentCustomerId(SLP 會員 ID)及paymentInstrumentId(付款工具 ID),可透過 付款工具列表查詢 取得
與其他場景的核心差異
| 差異點 | CardBind / CardBindPayment / QuickPayment | Recurring |
|---|---|---|
| 顧客是否在場 | ✅ 在場 | ❌ 不在場 |
| 觸發方式 | 顧客在頁面主動發起 | 特店 Server 主動發起 |
autoConfirm | false(顧客在場,無需自動確認) | true(必填) |
| 是否需要 SDK | ✅ 需要 | ❌ 不需要 |
建立付款交易
{
"amount": {
"value": 10000,
"currency": "TWD"
},
"confirm": {
"paymentMethod": "CreditCard",
"paymentBehavior": "Recurring",
"autoConfirm": true,
"paymentCustomerId": "MEMBER_987654",
"paymentInstrument": {
"paymentInstrumentId": "PI_001"
}
},
"customer": {
"referenceCustomerId": "CUST_123456"
},
"client": {
"ip": "特店伺服器 IP"
}
}
| 參數 | 值 | 說明 |
|---|---|---|
paymentBehavior | Recurring | 定期扣款場景 |
autoConfirm | true | 必填。顧客不在場,必須自動確認,否則交易會停在待確認狀態 |
paymentCustomerId | SLP 會員 ID | 必填 |
paymentInstrument.paymentInstrumentId | 付款工具 ID | 必填。指定使用哪張已儲存的卡片扣款,可透過 付款工具列表查詢 取得 |
savePaymentInstrument | 不傳 | Recurring 場景無需傳 |
client.ip | 特店伺服器 IP | 定期扣款無顧客在場,填特店伺服器 IP 即可 |
各場景參數組合總覽
| 場景 | paymentBehavior | paymentInstrument.savePaymentInstrument | autoConfirm | paymentCustomerId | paymentInstrument.paymentInstrumentId | 是否需要 SDK |
|---|---|---|---|---|---|---|
| 純綁卡 | CardBind | true(必填) | false | 不傳 | 不傳 | ✅ |
| 付款並綁卡 | CardBindPayment | true(必填) | false | 不傳 | 不傳 | ✅ |
| 快捷付款 | QuickPayment | 不傳 | false | 必填 | 不傳 | ✅ |
| 定期扣款 | Recurring | 不傳 | true(必填) | 必填 | 必填 | ❌ |
交易結果與 customerId 儲存
特店 Server 透過 Webhook 被動接收或主動查詢取得交易結果:
{
"status": "SUCCEEDED",
"customer": {
"referenceCustomerId": "CUST_123456",
"customerId": "MEMBER_987654"
},
"payment": {
"paymentCustomerId": "MEMBER_987654"
}
}
customerId(SLP 會員 ID)由 SLP 系統自動生成,不是 customerToken,也不是 referenceCustomerId。請在收到交易成功的 Webhook 後,主動從回應中取出 customerId,並關聯到特店自己的顧客系統,以便後續快捷付款和定期扣款使用。
Webhook 通知最多重試 16 次,間隔從 15 秒逐步拉長到 12 小時。請確保介面正確回覆 200。
退款
透過 建立退款交易 介面發起。可退款時效為交易成功後 180 天內。
付款工具維護
| 操作 | 介面 |
|---|---|
| 查詢已綁卡 | 付款工具列表查詢(傳入 paymentCustomerId) |
| 解除綁定 | 解綁付款工具(傳入 paymentInstrumentId) |
付款工具狀態與 Webhook 通知
綁卡成功後,付款工具的狀態可能隨時發生變化(例如卡片過期、顧客主動解綁、發卡行停用等)。只有當付款工具處於可用狀態時,才支援快捷付款和定期扣款。 特店應透過 Webhook 即時感知狀態變更,避免對不可用的付款工具發起扣款而導致交易失敗。
付款工具狀態說明
| 狀態 | 說明 | 是否支援快捷付款 / 定期扣款 |
|---|---|---|
SUCCESSED | 綁定成功,付款工具可用 | ✅ 支援 |
CREATED | 建立中,尚未完成綁定 | ❌ 不支援 |
DISABLED | 已解綁,付款工具不可用 | ❌ 不支援 |
FAILED | 綁定失敗 | ❌ 不支援 |
Webhook 事件類型
SLP 會透過以下 Webhook 事件通知特店付款工具的狀態變更:
| event.type | 觸發時機 | 說明 |
|---|---|---|
customer.instrument.binded | 顧客完成綁卡 | 付款工具建立成功,可用於快捷付款 / 定期扣款 |
customer.instrument.updated | 付款工具資訊更新 | 例如卡片即將過期、發卡行更新等,特店應同步更新本地儲存的卡片資訊 |
customer.instrument.unbinded | 顧客解綁或系統解綁 | 付款工具已不可用,特店應停止對該付款工具發起快捷付款 / 定期扣款 |
Webhook 電文結構
{
"id": "事件 ID",
"type": "customer.instrument.binded",
"created": 1718551769058,
"data": {
"customerId": "MEMBER_987654",
"referenceCustomerId": "CUST_123456",
"paymentInstrument": {
"instrumentId": "PI_001",
"instrumentType": "CreditCard",
"instrumentStatus": "SUCCESSED",
"instrumentCard": {
"type": "CREDIT",
"brand": "Visa",
"first": "400000",
"last": "1234",
"expireYear": "2027",
"expireMonth": "12",
"expired": false,
"issuer": "XX Bank"
}
}
}
}
特店處理建議
特店在收到 customer.instrument.unbinded 或 instrumentStatus 變為 DISABLED / FAILED 時,應立即停止對該付款工具發起快捷付款和定期扣款,並通知顧客重新綁卡。對不可用的付款工具發起扣款會導致交易失敗。
建議特店在每次發起快捷付款或定期扣款前,先透過 付款工具列表查詢 確認付款工具狀態為可用(SUCCESSED 且 expired 為 false),再發起交易。