PAYATHON 2026

Bigcommerce checkout 如何添加 2.5% processing fee?

支付小周

结论

前端脚本不能直接修改 BigCommerce 的 grand total。BigCommerce 会根据商品、折扣、运费、税费及平台认可的其他费用重新计算该金额。即使前端改了页面上的显示值,也无法可靠地改变订单金额或支付网关实际收取的金额。

可以按以下顺序选择实现方式:

  1. 优先使用后台支付方式提供的 surcharge、handling fee 或 payment fee 配置。
  2. 如果当前商店支持 Checkout Fees API,由服务端为 checkout 添加正式费用。
  3. 如果以上方式都不可用,可以添加一个代表 processing fee 的隐藏商品作为 line item。这是一种兼容方案,需要额外处理税费、折扣和重复添加等问题。
  4. 不要只在浏览器里修改总价,也不要等支付完成后再单独追加扣款。

方案一:配置支付方式附加费

先检查 BigCommerce 后台中当前信用卡支付方式的设置,查看是否有以下选项:

  • Surcharge
  • Handling Fee
  • Payment Fee
  • 按百分比收取费用的设置

如果支付方式支持按比例收费,可将费率设为 2.5%,并限制为仅对信用卡支付生效。这种方式通常最稳妥,因为费用会纳入平台的订单金额计算,支付网关收到的金额也能与订单总额保持一致。

不同 BigCommerce 商店方案、结账架构和支付网关提供的选项可能不同。如果后台没有相关字段,并不表示可以通过修改 checkout 模板来实现。此时需要继续检查 Checkout API 是否提供相应能力。

方案二:通过 Checkout Fees API 添加费用

部分 BigCommerce checkout 集成允许为 checkout 添加正式的 fee。如果当前商店支持,应由后端执行以下流程:

  1. 获取当前 checkoutId。
  2. 读取 checkout 的最新金额。
  3. 确认买家选择了需要收费的信用卡支付方式。
  4. 根据服务端读取到的计费基数计算费用。
  5. 创建或更新一个名为 Credit Card Processing Fee 的 checkout fee。
  6. 再次读取 checkout,并使用 BigCommerce 返回的新总额创建支付。

费用可以这样计算:

function calculateProcessingFee(amount, rate = 0.025) {
  return Math.round((amount * rate + Number.EPSILON) * 100) / 100;
}

const chargeableAmount = 100.00;
const processingFee = calculateProcessingFee(chargeableAmount);
// 2.50

实际集成时,不要自行猜测费用接口的 URL、字段名或适用范围。具体实现应以当前商店能够访问的 BigCommerce Checkout API 文档和实际 API 响应为准。如果平台没有向该商店开放 checkout fee 写入能力,就不能通过普通 checkout 更新接口强行改写 grand_total。

操作还需要具备幂等性,避免结账页面刷新或切换支付方式后重复收费:

async function ensureProcessingFee(checkout) {
  const feeName = 'Credit Card Processing Fee';
  const rate = 0.025;

  const existingFee = checkout.fees?.find(
    fee => fee.name === feeName
  );

  const chargeableAmount = getChargeableAmount(checkout);
  const expectedAmount = calculateProcessingFee(chargeableAmount, rate);

  if (existingFee && existingFee.amount === expectedAmount) {
    return checkout;
  }

  if (existingFee) {
    await removeCheckoutFee(checkout.id, existingFee.id);
  }

  await addCheckoutFee(checkout.id, {
    name: feeName,
    amount: expectedAmount
  });

  return getCheckout(checkout.id);
}

这里的 getChargeableAmount、addCheckoutFee 和 removeCheckoutFee 都是示意函数,并非可以直接调用的 BigCommerce SDK 方法。它们需要根据实际可用的 API 来实现。

方案三:添加隐藏的 line item

添加 line item 可以让费用进入订单总额,但普通商品与正式费用并不相同。可以创建一个不可搜索、无需配送的虚拟商品,例如:

Product: Credit Card Processing Fee
Price: 由后端计算
Shipping required: No
Visible in storefront: No

结账流程大致如下:

const fee = calculateProcessingFee(chargeableAmount, 0.025);

await removeExistingProcessingFeeItem(cartId);

if (isCreditCardSelected && fee > 0) {
  await addProcessingFeeItem(cartId, {
    productId: PROCESSING_FEE_PRODUCT_ID,
    quantity: 1,
    price: fee
  });
}

使用这种方式前,必须确认当前 API 是否允许覆盖商品价格。有些接口只接受 productId、variantId 和数量,最终价格仍以商品目录为准。如果无法可靠地传入动态价格,就只能预先创建大量价格变体,这并不适合百分比费用。

把费用作为商品还会引出一系列问题:

  • 可能被计入商品折扣或优惠券。
  • 可能影响免运费门槛。
  • 税费可能计算错误。
  • 可能参与库存、退货和商品报表。
  • 购物车金额变化后需要重新计算。
  • 切换到非信用卡支付方式时需要删除。
  • 页面刷新或重复请求可能导致多次添加。

因此,只有当平台不提供正式 fee 能力时,才应考虑使用 line item。

计费基数要先定义清楚

“按整个账单金额收取 2.5%”需要先确定具体包含哪些金额。常见的计算方式是:

fee = (商品金额 - 折扣 + 运费 + 税费) × 2.5%

假设计费基数为 100.00:

fee = 100.00 × 0.025 = 2.50
final total = 102.50

如果手续费本身也要计入“整个最终账单金额”,则需要使用另一套公式:

fee = base × rate / (1 - rate)

例如:

fee = 100.00 × 0.025 / 0.975 ≈ 2.56
final total = 102.56

多数情况下会采用第一种算法,但最终仍应以支付机构规则和商户对费用的定义为准。所有金额都应按照商店货币的最小单位统一舍入,不能让浏览器和后端各自使用不同的舍入方式。

实现时的注意事项

费用的计算和写入必须在服务端完成。浏览器传来的金额、支付方式名称和费率都不能直接信任。提交支付前,还应重新读取 checkout,确认订单总额与即将提交给支付网关的金额一致。

实现时还要处理以下状态变化:

  • 商品数量增加或减少
  • 优惠券添加或移除
  • 运费变化
  • 税费重新计算
  • 支付方式切换
  • 多币种结账
  • checkout 恢复或页面刷新
  • 退款和部分退款

信用卡 surcharge 还会受到当地法律、卡组织规则和支付网关协议的约束,可能涉及费率上限、披露要求,或禁止对某些卡种收费。实施前,应向收单机构或支付网关确认是否允许收取 2.5%,并在买家提交订单前清楚展示费用名称、费率和金额。

备注:内容仅供参考。