PayPal 实现自动订阅的步骤
自动续费的实现分为五个主要步骤。需要注意的是,实际开发中还需处理支付结果和订阅管理等其他事项:
- 事先创建并激活付款计划;
- 用户创建订阅,并跳转到 PayPal 网站以等待用户同意;
- 用户同意后,跳转回网站并执行订阅;
- 获取用户账单,包括支付结果通知的接收或主动查询支付结果;
- 处理用户取消订阅等通知。
使用 PayPal SDK
要使用 PayPal SDK,请首先安装:
bash
composer require paypal/rest-api-sdk-php
官方提供了完整的 Samples 供开发者参考。
您可以通过 PayPal Sandbox 进行方便的调试。
创建并激活订阅计划
- 订阅计划(Billing Plan)相当于产品,对于不同商品需要创建不同价格的计划。但在创建协议时可以根据用户类型进行调整。
- 在创建
TRIAL
类型支付时,必须提供REGULAR
支付选项。TRIAL
无法自动判断用户是否为新用户,因此首次的新用户优惠需要用业务代码自行实现。 - 创建用户订阅协议时,协议生效时间必须设置在当前时间的24小时以后,这样循环扣款的设置无法立即生效。通常,首次扣款可以通过
MerchantPreferences
中的setSetupFee
来设置。 - PayPal SDK 可能会抛出错误
"NotifyUrl" value is NULL
,这是 PayPal 服务端的问题,解决方法可以参考 issue。
创建订阅
用户可以为同一订阅计划创建多个订阅协议(Billing Agreement),创建后会跳转至 PayPal 网站以等待用户同意协议。
协议的开始时间
start_date
最早可以设置为24小时后,因此实际的设置会影响第二次的扣款时间。如果设置按月付款,start_date
应当设为一个月之后,同时通过setSetupFee
设置首次扣款费用。
创建订阅后,生成 Agreement.id
前需要从跳转链接中提取 token
,以便将创建的订阅和用户同意后跳转回来的协议信息对应起来。
php
$link = $agreement->getApprovalLink();
parse_str(parse_url($link, PHP_URL_QUERY), $params);
$token = $params['token'];
- 同一订阅计划可以被同一用户多次订阅,因此在执行新协议前需要手动取消之前的协议。
- 实际的扣款时间可能会有延迟,每次循环扣款的执行时间通常会比
AgreementDetail.next
显示的时间晚几个小时。因此,为确保连续性,建议提前一天扣款。
此外,您可以在 My Apps -> REST API apps -> WEBHOOKS
中设置 webhook
通知。当每次循环扣款成功时,PayPal 会发送 PAYMENT.SALE.COMPLETED
事件通知,您可以通过其中的 billing_agreement_id
字段与已创建的订阅相匹配,从而找到对应的付款协议。每次 AgreementDetail
也会返回下次收款时间的 next
参数。如果超过该时间,您可以通过 Agreement::searchTransactions
方法查询该协议的所有交易。需要注意的是,PayPal 实际的扣款时间通常会有延迟,因此需要多次重试。