PayPal 提供了一个强大的自动续费功能,官方文档将其分为五个主要步骤。在实际开发中,还需要处理支付结果和订阅管理。以下是实现自动订阅的详细流程:
- 创建并激活订阅计划;
- 用户创建订阅并跳转至 PayPal 网站等待用户同意;
- 用户同意后,跳转回网站并执行订阅;
- 获取用户账单信息,包括扣款结果通知的接收或主动查询;
- 处理用户取消订阅等通知。
使用 PayPal SDK
开始之前,首先需要安装 PayPal 的 PHP SDK:
bash
composer require paypal/rest-api-sdk-php
官方提供了完整的 Samples,帮助开发者快速上手。此外,PayPal 提供了 Sandbox 环境,方便进行调试。
创建并激活订阅计划
- 订阅计划(Billing Plan):相当于产品,每个商品的不同价格需要创建不同的计划。不过,可以在创建协议时针对不同用户进行调整;
- 试用期支付:在创建
TRIAL
类型支付时,必须同时存在REGULAR
支付。TRIAL
不会自动判断新用户等条件,因此新用户的首次优惠需要业务代码自行实现; - 协议生效时间:创建用户订阅协议时,协议生效时间必须在当前时间 24 小时之后。因此,循环扣款无法立即执行,最早也需要 24 小时后。如果业务需要立即进行首次扣款,可以通过
MerchantPreferences
的setSetupFee
来设置首次扣款费用; - 常见错误:PayPal SDK 可能会报错
"NotifyUrl" value is NULL
,这是 PayPal 服务端的一个未修复的 bug,解决办法见 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
显示的时间晚几个小时。为确保连续性,可以设置提前一天扣款。
处理扣款通知
- Webhook 设置:在
My Apps -> REST API apps -> WEBHOOKS
中可以设置webhook
通知。每次循环扣款成功后,PayPal 都会发送PAYMENT.SALE.COMPLETED
事件通知,通过其中的billing_agreement_id
字段与已创建的订阅匹配; - 查询交易:每次
AgreementDetail
都会返回下次收款时间next
参数。可以在超过这个时间后,通过Agreement::searchTransactions
方法查询该协议的所有交易。需要注意的是,PayPal 实际扣款时间通常会有延迟,因此需要多次重试。