Bigcommerce checkout 如何添加 2.5% processing fee?
结论
前端脚本不能直接修改 BigCommerce 的 grand total。BigCommerce 会根据商品、折扣、运费、税费及平台认可的其他费用重新计算该金额。即使前端改了页面上的显示值,也无法可靠地改变订单金额或支付网关实际收取的金额。
可以按以下顺序选择实现方式:
- 优先使用后台支付方式提供的 surcharge、handling fee 或 payment fee 配置。
- 如果当前商店支持 Checkout Fees API,由服务端为 checkout 添加正式费用。
- 如果以上方式都不可用,可以添加一个代表 processing fee 的隐藏商品作为 line item。这是一种兼容方案,需要额外处理税费、折扣和重复添加等问题。
- 不要只在浏览器里修改总价,也不要等支付完成后再单独追加扣款。
方案一:配置支付方式附加费
先检查 BigCommerce 后台中当前信用卡支付方式的设置,查看是否有以下选项:
SurchargeHandling FeePayment Fee- 按百分比收取费用的设置
如果支付方式支持按比例收费,可将费率设为 2.5%,并限制为仅对信用卡支付生效。这种方式通常最稳妥,因为费用会纳入平台的订单金额计算,支付网关收到的金额也能与订单总额保持一致。
不同 BigCommerce 商店方案、结账架构和支付网关提供的选项可能不同。如果后台没有相关字段,并不表示可以通过修改 checkout 模板来实现。此时需要继续检查 Checkout API 是否提供相应能力。
方案二:通过 Checkout Fees API 添加费用
部分 BigCommerce checkout 集成允许为 checkout 添加正式的 fee。如果当前商店支持,应由后端执行以下流程:
- 获取当前
checkoutId。 - 读取 checkout 的最新金额。
- 确认买家选择了需要收费的信用卡支付方式。
- 根据服务端读取到的计费基数计算费用。
- 创建或更新一个名为
Credit Card Processing Fee的 checkout fee。 - 再次读取 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%,并在买家提交订单前清楚展示费用名称、费率和金额。
备注:内容仅供参考。
