跳到主要内容

折扣

PaymentKit 提供了一套使用 Coupons 和 Promotion Codes 的灵活折扣系统。这使您能够为客户提供各种类型的折扣,例如百分比折扣、固定金额折扣和限时优惠。

  • Coupons:定义核心折扣规则,例如折扣百分比或金额、持续时间(例如,一次性、永久、重复)以及最大总兑换次数。
  • Promotion Codes:这些是面向客户的代码,与 Coupon 相关联。它们可以有自己的一套规则,例如单个兑换限制、到期日期和限制条件(例如,仅限首次使用的客户)。

您可以将 Coupon 视为折扣的模板,而 Promotion Codes 则是客户可以使用的该折扣的具体实例。

有关所有可用 API 操作的详细说明,请参阅 Coupons API 参考Promotion Codes API 参考

折扣如何运作

下图说明了 Coupons、Promotion Codes 及其在交易过程中的应用关系。

Discounts

创建 Coupons

Coupon 对象包含有关折扣的信息,例如是百分比折扣还是固定金额折扣。您可以创建 Coupons,然后将 Promotion Codes 附加到它们上面。

创建带有 Promotion Codes 的 Coupon

您可以在一次 API 调用中创建一个 Coupon 和一个或多个关联的 Promotion Codes。这对于快速建立新的营销活动非常有用。

创建带有促销代码的 Coupon

javascript
import payment from '@blocklet/payment-js';

async function createDiscountCampaign() {
  try {
    const result = await payment.coupons.create({
      name: '新用户折扣',
      percent_off: 20,
      duration: 'once',
      max_redemptions: 1000, // Coupon 本身的最大兑换次数
      promotion_codes: [
        {
          code: 'WELCOME20',
          description: '新用户欢迎折扣',
          max_redemptions: 100, // 此特定代码的最大兑换次数
          expires_at: Math.floor(Date.now() / 1000) + (30 * 24 * 60 * 60) // 从现在起 30 天
        }
      ]
    });

    console.log('Coupon 已创建:', result.coupon);
    console.log('Promotion codes 已创建:', result.promotion_codes);
  } catch (error) {
    console.error('创建 Coupon 时出错:', error.message);
  }
}

createDiscountCampaign();

参数

  • name string (required) — Coupon 的名称,用于内部显示。
  • percent_off number — 从小计金额中扣除的百分比(0-100)。如果设置了 amount_off,则不得提供此项。
  • amount_off string — 从小计金额中扣除的固定金额。如果设置了 percent_off,则不得提供此项。
  • currency_id string — 如果设置了 amount_off,则此项为必需。固定金额折扣的货币 ID。
  • duration string (required) — 描述折扣应用的持续时间。可以是 once(一次性)、forever(永久)或 repeating(重复)。
  • duration_in_months number — 如果 duration 是 repeating,则为 Coupon 生效的月数。
  • max_redemptions number — Coupon 可以被兑换的最大次数。
  • redeem_by number — 一个 Unix 时间戳,指定 Coupon 的到期日期。
  • promotion_codes array — 一个 Promotion Code 对象数组,用于创建并附加到此 Coupon。
    • code string — 面向客户的代码。如果省略,将生成一个随机代码。
    • max_redemptions number — 此特定 Promotion Code 可以使用的最大次数。
    • expires_at number — 此 Promotion Code 过期的 Unix 时间戳。
    • description string — Promotion Code 的可选描述。
  • metadata object — 一组用于存储附加信息的键值对。

创建 Promotion Codes

虽然您可以在创建 Coupon 的同时创建 Promotion Codes,但也可以单独创建它们并附加到现有的 Coupon 上。这对于为单个营销活动生成多个唯一代码非常有用。

创建独立的 Promotion Code

创建 Promotion Code

javascript
import payment from '@blocklet/payment-js';

async function createPromoCode(couponId) {
  try {
    const promotionCode = await payment.promotionCodes.create({
      coupon_id: couponId, // 现有 Coupon 的 ID
      code: 'SAVE15NOW',
      description: '下次购买可享八五折优惠',
      max_redemptions: 500,
      restrictions: {
        first_time_transaction: true, // 仅限新客户
      }
    });
    console.log('Promotion code 已创建:', promotionCode);
  } catch (error) {
    console.error('创建 Promotion Code 时出错:', error.message);
  }
}

createPromoCode('coupon_xxx'); // 替换为您的实际 Coupon ID

参数

  • coupon_id string (required) — 此 Promotion Code 应附加到的 Coupon 的 ID。
  • code string — 面向客户的代码。如果省略,将生成一个随机代码。
  • active boolean (default: true) — Promotion Code 当前是否有效。
  • max_redemptions number — 此特定 Promotion Code 可以使用的最大次数。
  • expires_at number — 此 Promotion Code 过期的 Unix 时间戳。
  • restrictions object — 对此 Promotion Code 应用限制。
    • first_time_transaction boolean — 如果为 true,则该 Promotion Code 只能由之前没有任何付款记录的客户兑换。
    • minimum_amount number — 使用此代码所需的最低交易金额。
    • minimum_amount_currency string — 最低金额的货币。
  • metadata object — 一组用于存储附加信息的键值对。

在结账时应用折扣

要允许客户在结账页面输入 Promotion Code,您必须在创建 Checkout Session 或 Payment Link 时明确启用此选项。

在 Checkout Session 上启用

在创建 Checkout Session 时,将 allow_promotion_codes 参数设置为 true。这将在支付页面上添加一个字段,供客户输入他们的代码。

启用 Promotion Codes

javascript
import payment from '@blocklet/payment-js';

async function createCheckoutWithDiscounts() {
  try {
    const session = await payment.checkout.sessions.create({
      success_url: 'https://example.com/success',
      cancel_url: 'https://example.com/cancel',
      mode: 'payment',
      line_items: [
        { price_id: 'price_xxx', quantity: 1 }
      ],
      allow_promotion_codes: true // 这将启用优惠码字段
    });
    console.log('已创建启用 Promotion Codes 的结账会话:', session.url);
  } catch (error) {
    console.error('创建结账会话时出错:', error.message);
  }
}

createCheckoutWithDiscounts();

同样的逻辑也适用于可重复使用的 Payment Links。将 allow_promotion_codes 设置为 true 可确保任何使用该链接的人都可以应用有效的 Promotion Code。

在支付链接上启用

javascript
import payment from '@blocklet/payment-js';

async function createPaymentLinkWithDiscounts() {
  try {
    const paymentLink = await payment.paymentLinks.create({
      line_items: [{
        price_id: 'price_xxx',
        quantity: 1,
      }],
      allow_promotion_codes: true,
    });
    console.log('已创建启用 Promotion Codes 的支付链接:', paymentLink.url);
  } catch (error) {
    console.error('创建支付链接时出错:', error.message);
  }
}

createPaymentLinkWithDiscounts();

管理折扣

SDK 提供了多种方法来管理和跟踪您的折扣。

通过代码检索 Promotion Code

您可以直接使用面向客户的代码字符串来获取 Promotion Code 的详细信息。

通过代码获取 Promotion Code

javascript
import payment from '@blocklet/payment-js';

async function getPromoDetails(code) {
  try {
    const promoByCode = await payment.promotionCodes.byCode(code);
    console.log('找到 Promotion Code:', promoByCode);
    // 您现在可以访问关联的 Coupon 详细信息
    console.log('折扣:', promoByCode.coupon);
  } catch (error) {
    console.error(`未找到 Promotion Code '${code}' 或发生错误:`, error.message);
  }
}

getPromoDetails('WELCOME20');

检查 Coupon 使用情况

确定一个 Coupon 是否至少被兑换过一次。这对于决定是否仍可编辑 Coupon 的规则很有用。

检查 Coupon 使用情况

javascript
import payment from '@blocklet/payment-js';

async function checkCouponUsage(couponId) {
  try {
    const { used } = await payment.coupons.used(couponId);
    if (used) {
      console.log(`Coupon ${couponId} 已被使用,其规则现已锁定。`);
    } else {
      console.log(`Coupon ${couponId} 尚未被使用。`);
    }
  } catch (error) {
    console.error('检查 Coupon 使用情况时出错:', error.message);
  }
}

checkCouponUsage('coupon_xxx'); // 替换为有效的 Coupon ID

列出兑换记录

您可以检索已兑换特定 Coupon 或 Promotion Code 的客户或订阅的分页列表。

列出 Coupon 兑换记录

javascript
import payment from '@blocklet/payment-js';

async function getCouponRedemptions(couponId) {
  try {
    const redemptions = await payment.coupons.redemptions(couponId, {
      type: 'customer', // 或 'subscription'
      page: 1,
      pageSize: 10
    });
    console.log(`找到 ${redemptions.count} 个 Coupon ${couponId} 的客户兑换记录:`);
    redemptions.customers.forEach(customer => {
      console.log(`- 客户 ID: ${customer.id}`);
    });
  } catch (error) {
    console.error('获取兑换记录时出错:', error.message);
  }
}

getCouponRedemptions('coupon_xxx'); // 替换为有效的 Coupon ID