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

如何在PHP环境下的PayPal订阅中为首次循环付款应用折扣码

嘿,这个需求我之前做PayPal订阅功能的时候刚好实现过,其实有两种很靠谱的方式,都是基于PayPal REST API来做的(毕竟老的NVP接口现在基本没人用了),给你详细说说:

方法一:创建包含首次优惠的订阅计划

这种方式是预先定义一个订阅计划,把首次付款的优惠直接嵌入到计划的计费周期里,用户订阅这个计划就自动享受首次折扣,后续按原价扣费。

首先,你需要先安装PayPal的PHP SDK:

composer require paypal/rest-api-sdk-php

然后是具体的代码实现,先初始化API上下文(记得替换成你的客户端ID和密钥):

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

$apiContext = new \PayPal\Rest\ApiContext(
    new \PayPal\Auth\OAuthTokenCredential(
        '你的客户端ID',
        '你的客户端密钥'
    )
);

// 沙箱环境配置,生产环境可以去掉
$apiContext->setConfig([
    'mode' => 'sandbox',
    'log.LogEnabled' => true,
    'log.FileName' => '../PayPal.log',
    'log.LogLevel' => 'DEBUG',
    'cache.enabled' => true,
]);

接下来创建带有首次优惠的计划:

// 定义常规计费周期(每月20美元,无限期)
$regularCycle = new \PayPal\Api\BillingCycle();
$regularCycle->setFrequency('MONTH')
    ->setFrequencyInterval('1')
    ->setCycles('INFINITE')
    ->setAmount(new \PayPal\Api\Currency(['value' => '20.00', 'currency' => 'USD']));

// 定义首次优惠周期(第一个月15美元,仅1次)
$firstCycle = new \PayPal\Api\BillingCycle();
$firstCycle->setFrequency('MONTH')
    ->setFrequencyInterval('1')
    ->setCycles('1')
    ->setAmount(new \PayPal\Api\Currency(['value' => '15.00', 'currency' => 'USD']))
    ->setTenureType('TRIAL'); // 用TRIAL标记这个是优惠周期

// 把两个周期组合成付款规则
$paymentDefinition = new \PayPal\Api\PaymentDefinition();
$paymentDefinition->setName('首月优惠订阅')
    ->setType('REGULAR')
    ->setPaymentCycles('INFINITE')
    ->setAmount(new \PayPal\Api\Currency(['value' => '20.00', 'currency' => 'USD']))
    ->setBillingCycles([$firstCycle, $regularCycle]);

// 创建并激活计划
$plan = new \PayPal\Api\Plan();
$plan->setName('高级订阅套餐')
    ->setDescription('高级订阅,首月立减5美元')
    ->setType('INFINITE')
    ->setPaymentDefinitions([$paymentDefinition]);

try {
    // 创建计划
    $plan->create($apiContext);
    // 激活计划(默认创建的计划是草稿状态,必须激活才能使用)
    $patch = new \PayPal\Api\Patch();
    $patch->setOp('replace')
        ->setPath('/')
        ->setValue(['state' => 'ACTIVE']);
    $patchRequest = new \PayPal\Api\PatchRequest();
    $patchRequest->addPatch($patch);
    $plan->update($patchRequest, $apiContext);

    echo "计划创建成功,ID:" . $plan->getId();
} catch (\PayPal\Exception\PayPalConnectionException $ex) {
    // 处理API连接错误
    echo $ex->getCode() . "<br>" . $ex->getData();
    die($ex);
} catch (Exception $ex) {
    die($ex);
}

用户订阅的时候,直接使用这个计划创建订阅即可:

$subscription = new \PayPal\Api\Subscription();
$subscription->setPlanId($plan->getId())
    ->setStartDate(date('c', strtotime('+1 day'))) // 订阅开始日期(可以设为当前时间或未来某一天)
    ->setSubscriber([
        'name' => ['given_name' => '张三', 'surname' => '李四'],
        'email_address' => 'user@example.com'
    ]);

try {
    $subscription->create($apiContext);
    // 获取PayPal的批准链接,跳转到这里让用户确认订阅
    $approvalUrl = $subscription->getLinks()[0]->getHref();
    header("Location: $approvalUrl");
} catch (\PayPal\Exception\PayPalConnectionException $ex) {
    echo $ex->getCode() . "<br>" . $ex->getData();
    die($ex);
} catch (Exception $ex) {
    die($ex);
}

方法二:使用一次性优惠券实现首月优惠

这种方式是先创建一个常规的20美元订阅计划,然后生成一个仅适用于首次付款的优惠券,用户订阅时应用这个优惠券,首月自动减5美元,后续恢复原价。

创建优惠券的代码:

$coupon = new \PayPal\Api\Coupon();
$coupon->setName('首月立减5美元')
    ->setDescription('订阅高级套餐首月享受5美元折扣')
    ->setDiscountType('FIXED_AMOUNT')
    ->setAmount(new \PayPal\Api\Currency(['value' => '5.00', 'currency' => 'USD']))
    ->setMaxRedemptions(100) // 设置优惠券最大使用次数
    ->setValidFrom(date('c'))
    ->setValidUntil(date('c', strtotime('+30 days'))); // 设置优惠券有效期

try {
    $coupon->create($apiContext);
    echo "优惠券创建成功,ID:" . $coupon->getId();
} catch (\PayPal\Exception\PayPalConnectionException $ex) {
    echo $ex->getCode() . "<br>" . $ex->getData();
    die($ex);
} catch (Exception $ex) {
    die($ex);
}

然后在创建订阅的时候应用这个优惠券:

$subscription = new \PayPal\Api\Subscription();
$subscription->setPlanId('你的常规20美元计划ID')
    ->setStartDate(date('c', strtotime('+1 day')))
    ->setSubscriber([
        'name' => ['given_name' => '张三', 'surname' => '李四'],
        'email_address' => 'user@example.com'
    ])
    ->setAppliedCoupon(['coupon_id' => $coupon->getId()]); // 应用优惠券

// 后续创建订阅和跳转的代码和方法一一致

两种方法的对比

  • 方法一(嵌入优惠的计划):优点是配置好后不用额外管理优惠券,用户订阅直接生效;缺点是如果优惠规则变了,需要重新创建计划。
  • 方法二(优惠券):优点是灵活,同一个常规计划可以搭配不同优惠券,还能设置有效期和使用次数;缺点是需要额外维护优惠券资源。

注意事项

  1. 确保你的PayPal账号已经开启了订阅功能(新账号默认开启,老账号如果没开可以去后台设置)。
  2. 一定要先在沙箱环境测试,用PayPal沙箱账号模拟订阅,确认首次付款是15美元,后续账单是20美元。
  3. 如果用的是最新的PayPal Checkout SDK,代码结构会有点不一样,但核心逻辑是相同的——要么设置多周期金额,要么应用首次有效的优惠券。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:04:00