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

如何通过PayPal REST API实现单次购买与定期付款的合并交易

嘿,我之前刚好帮人实现过一模一样的场景!PayPal REST API确实没有专门的“混合单次+订阅交易”的直接示例,但其实可以通过创建包含多种购买单元的Order来实现——Order支持同时包含一次性付款项目和订阅计划,让用户一次完成授权付款。

下面是具体的实现步骤和PHP代码示例(基于PayPal PHP SDK v2):

核心思路

PayPal的Orders API允许在同一个订单的purchase_units数组中添加不同类型的购买项:

  • 用常规金额单元处理一次性购买(付款后直接捕获金额)
  • 用关联了plan_id的单元处理订阅(用户授权后自动创建订阅并扣取首次费用)
步骤1:初始化PayPal客户端

首先确保你已经通过Composer安装了PayPal PHP SDK(执行composer require paypal/paypal-checkout-sdk),然后初始化客户端:

require __DIR__ . '/vendor/autoload.php';

// 沙箱环境,生产环境替换为ProductionEnvironment
$environment = new \PayPalCheckoutSdk\Core\SandboxEnvironment(
    '你的客户端ID',
    '你的客户端密钥'
);
$client = new \PayPalCheckoutSdk\Core\PayPalHttpClient($environment);
步骤2:创建包含混合购买项的订单

构建订单请求,同时加入一次性购买和订阅单元:

use PayPalCheckoutSdk\Orders\OrdersCreateRequest;

$createOrderRequest = new OrdersCreateRequest();
$createOrderRequest->prefer('return=representation');
$createOrderRequest->body = [
    "intent" => "CAPTURE",
    "purchase_units" => [
        // 1. 一次性购买产品
        [
            "reference_id" => "single_product_001", // 自定义标识,后续回调区分用
            "amount" => [
                "currency_code" => "USD",
                "value" => "29.99" // 一次性产品价格
            ],
            "description" => "年度高级版电子书"
        ],
        // 2. 订阅产品(需预先在PayPal后台创建订阅计划)
        [
            "reference_id" => "subscription_monthly_001",
            "amount" => [
                "currency_code" => "USD",
                "value" => "9.99" // 订阅每月费用
            ],
            "description" => "月度会员服务",
            "plan_id" => "P-XXXXXXXXX" // 替换为你创建的订阅计划ID
        ]
    ],
    "application_context" => [
        "return_url" => "https://你的域名.com/paypal-success", // 付款成功跳转地址
        "cancel_url" => "https://你的域名.com/paypal-cancel" // 取消跳转地址
    ]
];

try {
    $response = $client->execute($createOrderRequest);
    // 获取PayPal的授权链接,引导用户跳转付款
    $approveLink = null;
    foreach ($response->result->links as $link) {
        if ($link->rel === 'approve') {
            $approveLink = $link->href;
            break;
        }
    }
    // 保存订单ID到数据库,后续回调验证用
    $orderId = $response->result->id;
    // 跳转到PayPal付款页面
    header("Location: {$approveLink}");
    exit;
} catch (\Exception $e) {
    // 处理创建订单失败的情况
    error_log("创建PayPal订单失败: " . $e->getMessage());
    echo "付款创建失败,请稍后重试";
}
步骤3:处理付款成功后的回调

用户在PayPal完成付款后,会跳转到你的return_url,同时携带token参数(即订单ID)。此时你需要捕获一次性付款的金额,并确认订阅已创建:

use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;

if (!isset($_GET['token'])) {
    die("无效的付款回调");
}

$orderId = $_GET['token'];
$captureRequest = new OrdersCaptureRequest($orderId);
$captureRequest->prefer('return=representation');

try {
    $response = $client->execute($captureRequest);
    // 遍历购买单元,分别处理一次性付款和订阅
    foreach ($response->result->purchase_units as $unit) {
        switch ($unit->reference_id) {
            case "single_product_001":
                // 一次性付款已成功捕获,处理业务逻辑(比如发货、生成订单记录)
                $captureId = $unit->payments->captures[0]->id;
                echo "一次性购买已完成,捕获ID: {$captureId}";
                break;
            case "subscription_monthly_001":
                // 订阅已成功创建,获取订阅ID并关联到用户
                $subscriptionId = $unit->payments->subscriptions[0]->id;
                echo "订阅已创建,订阅ID: {$subscriptionId}";
                break;
        }
    }
} catch (\Exception $e) {
    error_log("捕获PayPal付款失败: " . $e->getMessage());
    echo "付款处理失败,请联系客服";
}
关键注意事项
  • 预先创建订阅计划:订阅单元需要关联你在PayPal商家后台(或通过API)创建的订阅计划,计划需设置好周期(月度/季度)、金额、免费试用期等参数。
  • 依赖Webhook而非仅return_url:用户可能在付款后关闭页面,所以一定要配置PayPal Webhook,监听PAYMENT.CAPTURE.COMPLETED(一次性付款完成)和BILLING.SUBSCRIPTION.CREATED(订阅创建)事件,确保业务逻辑的可靠性。
  • 金额展示:用户在PayPal付款页面会看到一次性付款+订阅首次费用的总金额,以及明细,确认后才会完成付款。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:25:04