# 使用 PayPal 实现自动订阅功能

By [midjourney注册](https://paragraph.com/@midjourney) · 2025-03-03

---

PayPal 的自动续费功能为开发者提供了便捷的订阅管理方案。本文将详细介绍如何通过 PayPal 实现自动订阅，并优化开发流程。

自动订阅的实现步骤
---------

官方文档将自动续费流程分为五个主要步骤。在实际开发中，还需要处理支付结果和订阅管理。以下是具体步骤：

1.  **创建并激活订阅计划**：首先需要创建一个订阅计划，并确保其处于激活状态。
    
2.  **用户创建订阅**：用户创建订阅后，系统会跳转到 PayPal 网站等待用户确认。
    
3.  **用户确认订阅**：用户同意订阅后，系统会跳转回网站，执行订阅操作。
    
4.  **获取用户账单**：包括接收每次扣款结果的通知，或主动查询支付结果。
    
5.  **处理订阅取消等通知**：当用户取消订阅时，系统需要及时处理相关通知。
    

使用 PayPal SDK
-------------

为了简化开发流程，可以使用 PayPal 提供的 PHP SDK。通过以下命令安装：

bash composer require paypal/rest-api-sdk-php

官方提供了完整的 [示例代码](https://paypal.github.io/PayPal-PHP-SDK/sample/#billing)，开发者可以参考。此外，可以通过 [PayPal Sandbox](https://www.sandbox.paypal.com/) 进行便捷的调试。

创建并激活订阅计划
---------

在创建订阅计划时，需要注意以下几点：

*   **订阅计划与产品关联**：每个商品的不同价格需要创建不同的订阅计划，但可以在创建协议时针对不同用户进行调整。
    
*   **试用期支付设置**：在创建 `TRIAL` 类型支付时，必须同时存在 `REGULAR` 支付。试用期无法自动判断新用户等条件，因此首次优惠需要业务代码自行实现。
    
*   **协议生效时间**：创建用户订阅协议时，协议生效时间必须在当前时间的 24 小时之后。因此，首次扣款无法立即执行。可以通过 `MerchantPreferences` 的 `setSetupFee` 设置首次扣款费用。
    
*   **常见错误处理**：PayPal SDK 可能会报错 `"NotifyUrl" value is NULL`，这是 PayPal 服务端的已知问题，开发者可以参考 [GitHub issue](https://github.com/paypal/PayPal-PHP-SDK/pull/1152/files) 进行修复。
    

创建订阅
----

用户在创建订阅时，可以针对同一订阅计划创建多个订阅协议。创建后，系统会跳转到 PayPal 网站等待用户确认。以下是创建订阅时的注意事项：

*   **协议开始时间**：协议的开始时间 `start_date` 最早为当前时间的 24 小时之后，因此该值实际上是第二次扣款的时间。若按月付款，`start_date` 应设置为一个月之后，并通过 `setSetupFee` 设置首次扣款费用。
    
*   **获取 token**：创建订阅后，系统尚未生成 `Agreement.id`，需要从跳转链接中提取 `token`，以便与用户确认后的协议信息匹配。
    

php $link = $agreement->getApprovalLink(); parse\_str(parse\_url($link, PHP\_URL\_QUERY), $params); $token = $params\['token'\];

*   **重复订阅处理**：同一个用户可以对同一订阅计划进行多次订阅。因此，在执行新协议时，可能需要手动取消之前的协议。
    
*   **扣款时间延迟**：实际扣款时间会有延迟，建议设置提前一天扣款，以确保连续性。
    

订阅管理与通知
-------

为了更高效地管理订阅，可以通过以下方式优化：

*   **设置 Webhook**：在 `My Apps -> REST API apps -> WEBHOOKS` 中设置 Webhook 通知。每次循环扣款成功时，PayPal 会发送 `PAYMENT.SALE.COMPLETED` 事件通知，开发者可以通过 `billing_agreement_id` 字段匹配已创建的订阅。
    
*   **查询交易记录**：每次 `AgreementDetail` 都会返回下次收款时间 `next` 参数。可以在超过该时间后，通过 `Agreement::searchTransactions` 方法查询该协议的所有交易。需要注意的是，PayPal 的实际扣款时间可能会有延迟，因此需要多次重试。
    

👉 [野卡 WildCard | 一分钟注册，轻松订阅海外线上服务](https://bit.ly/yekapay)

---

*Originally published on [midjourney注册](https://paragraph.com/@midjourney/paypal)*
