You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP Braintree 无需订阅功能实现定期计费的方案及问题处理

问题解答

1. 方案可行性确认

Braintree完全支持不使用内置订阅功能实现自定义定期计费,你预想的核心逻辑(保存支付凭证令牌、后续自主发起交易)是官方允许的合法使用场景。

2. 报错原因及解决方案

你遇到的nonce重复使用报错,是因为当前流程顺序有误:payment_method_nonce是一次性凭证,只要调用过一次接口(不管是做交易还是创建客户/支付方式)就会失效,你先拿它做了Transaction Sale,再用它创建客户自然会报错。
你可以选择任意一种方案解决该问题:

方案一:调整操作顺序

  • 用户提交支付信息生成nonce后,先调用客户创建接口,传入nonce完成Braintree客户和支付方式的创建,同时获取到Braintree客户ID和支付方式令牌,存入你的数据库
  • 第一次的套餐付费交易,直接使用刚拿到的支付方式令牌调用Transaction Sale接口完成扣款,不需要再使用nonce
  • 后续定期扣费逻辑和你原来的设计一致,直接从数据库取出保存的支付方式令牌发起交易即可

对应代码示例

步骤1:先创建Braintree客户并获取支付令牌
// 拿到前端传来的nonce后先执行客户创建
$result = $gateway->customer()->create([
    'firstName' => $customer['name'],
    'company' => $customer['company'],
    'email' => $customer['email'],
    'paymentMethodNonce' => $customer['payment_method_nonce']
]);

// 验证创建成功后保存凭证到数据库
$braintreeCustomer = $result->customer;
$db->braintree_customer_id = $braintreeCustomer->id;
$db->braintree_payment_token = $braintreeCustomer->paymentMethods[0]->token;
$db->save();
步骤2:使用保存的令牌完成首次扣款
// 首次交易直接用刚获取的支付令牌
$firstSaleResult = $gateway->transaction()->sale([
    'amount' => $firstPaymentPrice,
    'paymentMethodToken' => $db->braintree_payment_token,
    'options' => [
        'submitForSettlement' => true
    ]
]);
步骤3:后续定期扣费逻辑
// 次月/指定扣费时间发起交易
$recurringSaleResult = $gateway->transaction()->sale([
    'amount' => $currentBillingPrice,
    'paymentMethodToken' => $db->braintree_payment_token,
    'options' => [
        'submitForSettlement' => true
    ]
]);

方案二:交易时自动存储支付凭证

如果不想调整现有流程的先后顺序,也可以在首次调用Transaction Sale接口时,添加storeInVaultOnSuccess参数,交易成功后Braintree会自动把支付方式存入加密保管库,你可以直接从交易返回结果中获取支付令牌和客户ID,不需要再额外调用客户创建接口,示例:

$firstSaleResult = $gateway->transaction()->sale([
    'amount' => $firstPaymentPrice,
    'paymentMethodNonce' => $customer['payment_method_nonce'],
    'options' => [
        'submitForSettlement' => true,
        'storeInVaultOnSuccess' => true // 交易成功后自动存储支付方式
    ]
]);

// 交易成功后直接从返回结果取凭证
if ($firstSaleResult->success) {
    $transaction = $firstSaleResult->transaction;
    $db->braintree_customer_id = $transaction->customerDetails->id;
    $db->braintree_payment_token = $transaction->paymentMethodToken;
    $db->save();
}

内容的提问来源于stack exchange,提问作者Linesofcode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 06:36:05