保存卡与 off-session 扣款

买家只需保存一次卡片,之后即可在其不在场时扣款(off-session)——适用于续费、充值或一键购买。卡号不经过你的服务器,也不经过 FastStar 服务器;你只持有 FastStar 令牌(pm_xxx)与脱敏卡信息。

服务端时序

  1. 创建 Customer

    保存的支付方式归属于 Customer,email 为必填:

    curl https://api.faststarpay.com/api/v1/public/customers \
      -H "X-API-Key: 你的_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "email": "[email protected]", "name": "张三" }'
  2. 创建 SetupIntent

    curl -X POST https://api.faststarpay.com/api/v1/public/customers/cus_xxx/setup-intent \
      -H "X-API-Key: 你的_API_KEY"

    响应 data

    { "client_secret": "seti_xxx_secret_xxx", "publishable_key": "pk_live_xxx", "setup_intent_id": "seti_xxx" }
  3. 浏览器中收集卡片

    把 SetupIntent 结果下发给前端,用 FastStar.cards.add(session, callbacks) 打开安全加卡弹层。买家保存卡片后,加卡页通过以下调用完成绑定:

    curl -X POST https://api.faststarpay.com/api/v1/public/customers/cus_xxx/payment-methods \
      -H "X-API-Key: 你的_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{ "setup_intent_id": "seti_xxx" }'

    响应 data 为脱敏支付方式——保存其 id

    { "id": "pm_xxx", "brand": "visa", "last4": "4242", "exp_month": 12, "exp_year": 2030 }
  4. off-session 扣款

    curl -X POST https://api.faststarpay.com/api/v1/public/customers/cus_xxx/charge \
      -H "X-API-Key: 你的_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "payment_method_id": "pm_xxx",
        "amount": 1999,
        "currency": "USD",
        "off_session": true
      }'

    响应 data

    {
      "payment_intent_id": "pi_xxx",
      "status": "succeeded",
      "amount": 1999,
      "currency": "USD",
      "payment_method_id": "pm_xxx"
    }

处理 SCA:HTTP 402

部分银行即使在 off-session 扣款时也要求强客户认证(如 3DS)。当银行要求二次验证时,扣款端点返回 HTTP 402 Payment Required

{ "success": false, "message": "Payment requires additional authentication" }

处理方式:

  • 这笔扣款没有完成——不要履约。
  • 把客户带回 on-session 流程完成验证:例如创建一个 Checkout Session,让客户在托管收银台中完成支付,3DS 挑战会在那里进行。
  • 订阅类扣款可通过邮件 / 站内信通知客户,附上该 on-session 流程的链接。

服务端示例(Node)

const BASE = 'https://api.faststarpay.com/api/v1';
const HEADERS = {
  'Content-Type': 'application/json',
  'X-API-Key': process.env.FASTSTAR_API_KEY,
};

// 扣已存卡;返回支付结果,或标记需要 SCA 验证
async function chargeSavedCard(customerId, paymentMethodId, amount, currency) {
  const r = await fetch(`${BASE}/public/customers/${customerId}/charge`, {
    method: 'POST',
    headers: HEADERS,
    body: JSON.stringify({
      payment_method_id: paymentMethodId,
      amount,                 // 最小货币单位
      currency,
      off_session: true,
    }),
  });

  if (r.status === 402) {
    // 需要 SCA:引导客户走 on-session 流程完成验证
    return { requiresAction: true };
  }

  const { data } = await r.json();
  return { requiresAction: false, payment: data };
}

相关端点:列出已存卡用 GET /public/customers/:id/payment-methods,设默认卡用 POST /public/payment-methods/:id/default,解绑用 DELETE /public/payment-methods/:id。详见 API 参考