PAYATHON 2026

Authorize.net 延迟付款与 recurring 扣款如何设置

支付老李

结论

不要把 $20 membership 费用并入月度订阅的常规扣款。建议在用户注册时分别设置三笔交易:

  1. 立即执行一笔 $5 的普通交易。
  2. 创建一份两周后开始、每月扣款 $30 的 ARB 订阅。
  3. 创建另一份两周后执行的 ARB 订阅,金额为 $20,并将 totalOccurrences 设为 1。

按此设置,两周后的首次扣款合计为 $50,此后每月只扣 $30。

不建议使用 ARB 的 trialAmount 表示首次收取的 $50,因为部分 Authorize.net ARB 接口要求 trialAmount 不得高于正常订阅金额。即使某个接口版本允许这样设置,也容易让人把这笔首期附加费误认为试用优惠价。

支付安排

最终会有以下三项交易:

时间金额实现方式
注册时$5createTransactionRequest 普通支付
两周后$20单次 ARB 订阅,totalOccurrences = 1
两周后及以后每月$30月度 ARB 订阅

两份 ARB 订阅可以共用同一个 customerProfileId 和 customerPaymentProfileId,不必再次收集信用卡信息。

创建月度订阅

下面是 ARBCreateSubscriptionRequest 的核心结构。示例省略了完整命名空间,只保留认证信息和计费计划相关内容:

<ARBCreateSubscriptionRequest>
  <merchantAuthentication>
    <name>API_LOGIN_ID</name>
    <transactionKey>TRANSACTION_KEY</transactionKey>
  </merchantAuthentication>

  <subscription>
    <name>Monthly product subscription</name>

    <paymentSchedule>
      <interval>
        <length>1</length>
        <unit>months</unit>
      </interval>
      <startDate>2026-09-12</startDate>
      <totalOccurrences>9999</totalOccurrences>
      <trialOccurrences>0</trialOccurrences>
    </paymentSchedule>

    <amount>30.00</amount>

    <profile>
      <customerProfileId>CUSTOMER_PROFILE_ID</customerProfileId>
      <customerPaymentProfileId>PAYMENT_PROFILE_ID</customerPaymentProfileId>
    </profile>
  </subscription>
</ARBCreateSubscriptionRequest>

startDate 应按注册日期加 14 天计算。9999 通常表示持续订阅,实际使用时仍需确认当前账户和 API 文档允许的取值。

创建一次性的 membership 扣款

另建一份金额为 $20、仅执行一次的订阅:

<ARBCreateSubscriptionRequest>
  <merchantAuthentication>
    <name>API_LOGIN_ID</name>
    <transactionKey>TRANSACTION_KEY</transactionKey>
  </merchantAuthentication>

  <subscription>
    <name>One-time membership fee</name>

    <paymentSchedule>
      <interval>
        <length>1</length>
        <unit>months</unit>
      </interval>
      <startDate>2026-09-12</startDate>
      <totalOccurrences>1</totalOccurrences>
      <trialOccurrences>0</trialOccurrences>
    </paymentSchedule>

    <amount>20.00</amount>

    <profile>
      <customerProfileId>CUSTOMER_PROFILE_ID</customerProfileId>
      <customerPaymentProfileId>PAYMENT_PROFILE_ID</customerPaymentProfileId>
    </profile>
  </subscription>
</ARBCreateSubscriptionRequest>

这里仍需填写月度间隔,但 totalOccurrences 为 1,所以该计划只会执行一次。

如果当前 Authorize.net 账户或使用的 SDK 不允许创建单次 ARB 计划,就无法只靠 ARB 完成这笔延迟的一次性扣款。此时需要保存支付档案 ID,再由服务端定时任务在两周后调用 createTransactionRequest。Authorize.net 的 Customer Profiles API 可以保存支付方式,但不会在指定日期自动替应用程序发起普通交易。

注册时的处理顺序

可以按以下顺序处理:

1. 创建或取得 Customer Profile
2. 创建 Customer Payment Profile
3. 使用 Payment Profile 立即收取 $5
4. 创建两周后开始的 $30/月 ARB 订阅
5. 创建两周后执行一次的 $20 ARB 订阅
6. 保存两个 subscriptionId

两份订阅会分别生成一个 subscriptionId。如果用户在两周内取消,应同时取消:

  • $30/月 的订阅;
  • 尚未执行的 $20 membership 订阅。

PHP 伪代码

下面的示例用于说明业务结构。具体类名和方法可能随 Authorize.net PHP SDK 版本变化:

$startDate = (new DateTimeImmutable('today'))
    ->modify('+14 days')
    ->format('Y-m-d');

// 注册时立即扣款
chargeCustomerProfile(
    customerProfileId: $customerProfileId,
    paymentProfileId: $paymentProfileId,
    amount: '5.00'
);

// 长期月度订阅
$monthlySubscriptionId = createArbSubscription(
    name: 'Monthly product subscription',
    customerProfileId: $customerProfileId,
    paymentProfileId: $paymentProfileId,
    startDate: $startDate,
    amount: '30.00',
    intervalLength: 1,
    intervalUnit: 'months',
    totalOccurrences: 9999
);

// 只执行一次的 membership 费用
$membershipSubscriptionId = createArbSubscription(
    name: 'One-time membership fee',
    customerProfileId: $customerProfileId,
    paymentProfileId: $paymentProfileId,
    startDate: $startDate,
    amount: '20.00',
    intervalLength: 1,
    intervalUnit: 'months',
    totalOccurrences: 1
);

注意事项

ARB 不能精确到分钟调度任务

ARB 的 startDate 只能指定日期,不能指定具体时间。Authorize.net 会通过批处理机制执行订阅扣款,因此无法保证交易恰好发生在注册时间的 14 天后。

订阅创建成功不等于后续扣款一定成功

创建 ARB 订阅时支付资料验证成功,并不能保证两周后的扣款也会成功。信用卡届时可能已经过期、被冻结,或因余额不足而被拒绝。系统至少应接收 Authorize.net Webhooks,并处理付款成功、付款失败及订阅状态变化。

完全不保存数据会影响取消操作

即使注册时已经创建所有扣款计划,也建议至少保存以下信息:

customerProfileId
customerPaymentProfileId
monthlySubscriptionId
membershipSubscriptionId
内部用户或订单编号

缺少这些信息时,用户取消订阅后,很难可靠地找到并取消两份计划。如果确实不能使用数据库,可以将这些 ID 保存到现有用户系统、订单元数据或其他持久化存储中。只保存在浏览器会话中并不可靠。

两笔同时扣款可能显示为两条账单记录

两周后,用户通常会看到 $20 和 $30 两笔交易,而不是一笔 $50。如果业务要求信用卡账单上只能出现一笔 $50,应用程序就需要在两周后主动收取 $50,之后再创建或启用 $30/月 的订阅。该方案需要服务端定时任务和持久化状态,仅靠 ARB 后台很难安全实现。

在“不使用数据库、所有计划必须在购买时配置”的限制下,创建两份同日起始的 ARB 计划是最直接的做法。

备注:内容仅供参考。