如何在 Netsuite 中处理 Debit Card 分期付款?
结论
NetSuite 可以记录 Debit Card 支付的订金,也可以按计划生成后续应收款。不过,分期生成账单和自动从 Debit Card 扣款是两个不同的环节。
Debit Card 通常仍通过信用卡收单通道处理。能否保存卡片并在之后定期扣款,取决于支付服务商、NetSuite 的支付处理配置、发卡地区和持卡人授权规则。仅靠 NetSuite 的标准销售订单功能,无法保证完成自动扣款。
比较稳妥的流程是:
- 使用 Sales Order 管理订单。
- 将首付款记录为 Customer Deposit。
- 通过 Billing Schedule 分期生成 Invoice。
- 每期使用支付服务商保存的 token 扣款,或向客户发送付款链接。
- 扣款成功后,创建 Customer Payment 并应用到对应账单。
如果支付服务商不支持 Debit Card tokenization 或 merchant-initiated transaction,NetSuite 仍可管理分期应收,但客户需要在每一期主动付款。
Debit Card 和 Credit Card 的处理差异
从 NetSuite 业务单据的角度看,Debit Card 和 Credit Card 的订单流程并非完全不同,主要差异在支付处理环节:
- Credit Card 通常支持预授权、捕获和保存支付凭证。
- Debit Card 可能要求即时扣款,并通过 PIN、OTP 或 3-D Secure 完成验证。
- 部分 Debit Card 不支持持卡人不在场时的后续自动扣款。
- 卡片凭证应由支付服务商以 token 形式保存。
- 如果实际使用的是银行账户直接扣款,而非带卡组织标识的 Debit Card,则应采用 ACH、SEPA Direct Debit 等银行扣款方案。
因此,不能只看卡面上的 Debit 或 Credit 来决定流程,还要确认支付服务商实际返回的支付能力。
推荐的业务流程
1. 创建 Sales Order
在 Sales Order 中保存商品、总金额、客户和付款条款。客户支付订金后,不要立即将整笔订单视为已付款。
如果项目需要按交付阶段开票,可以在订单或订单行上配置 Billing Schedule。实际可用字段取决于账户已启用的功能、表单和业务配置。
2. 收取并记录订金
客户首次付款时,可以通过支付页面或已配置的 NetSuite 支付处理服务发起扣款。扣款成功后,将这笔金额记录为与 Sales Order 关联的 Customer Deposit。
Customer Deposit 是客户预收款,并非针对 Invoice 的直接付款。该款项通常先计入客户订金负债账户,之后再应用到相应的 Invoice。
3. 按计划生成 Invoice
使用 Billing Schedule 按日期、比例或固定金额生成后续 Invoice。例如:
- 签约时支付 20%;
- 30 天后开具金额为 40% 的 Invoice;
- 60 天后开具剩余 40% 的 Invoice。
Billing Schedule 只负责确定开票时间和金额,不会自动执行扣款。
4. 处理每期付款
每期 Invoice 到期时,可以选择以下方式:
- 使用支付服务商保存的 payment token 自动扣款;
- 向客户发送支付链接,让客户重新完成验证;
- 财务人员收到外部支付结果后录入 Customer Payment;
- 使用 ACH 或 Direct Debit 等更适合周期扣款的支付方式。
自动扣款成功后,应创建 Customer Payment,并准确应用到对应的 Invoice。如果扣款失败,不要生成已付款记录。Invoice 应保持未结状态,随后进入催收或重试流程。
SuiteScript 示例
下面的 SuiteScript 2.1 示例用于在支付服务商确认扣款成功后,创建 Customer Payment 并将其应用到指定 Invoice。
这段代码只演示应收账款入账,不会向 Debit Card 发起扣款。实际扣款必须通过已经配置的支付处理服务完成。
/**
* @NApiVersion 2.1
* @NScriptType ScheduledScript
*/
define(['N/record'], (record) => {
const createCustomerPayment = ({
customerId,
invoiceId,
amount,
externalReference
}) => {
const payment = record.create({
type: record.Type.CUSTOMER_PAYMENT,
isDynamic: true
});
payment.setValue({
fieldId: 'customer',
value: customerId
});
payment.setValue({
fieldId: 'payment',
value: amount
});
payment.setValue({
fieldId: 'memo',
value: `Gateway transaction: ${externalReference}`
});
const lineCount = payment.getLineCount({
sublistId: 'apply'
});
let invoiceFound = false;
for (let i = 0; i < lineCount; i += 1) {
payment.selectLine({
sublistId: 'apply',
line: i
});
const transactionId = payment.getCurrentSublistValue({
sublistId: 'apply',
fieldId: 'internalid'
});
if (Number(transactionId) === Number(invoiceId)) {
payment.setCurrentSublistValue({
sublistId: 'apply',
fieldId: 'apply',
value: true
});
payment.setCurrentSublistValue({
sublistId: 'apply',
fieldId: 'amount',
value: amount
});
payment.commitLine({
sublistId: 'apply'
});
invoiceFound = true;
break;
}
}
if (!invoiceFound) {
throw new Error(
`Invoice ${invoiceId} is not available for customer ${customerId}`
);
}
return payment.save({
enableSourcing: true,
ignoreMandatoryFields: false
});
};
const execute = () => {
// 参数应来自经过验证的支付成功事件或内部任务队列。
const result = {
customerId: 123,
invoiceId: 456,
amount: 1000.00,
externalReference: 'gateway-transaction-id'
};
createCustomerPayment(result);
};
return { execute };
});
不同账户可能有不同的必填字段、子公司、币种、A/R Account、部门、地点和自定义审批字段,因此上线前需要在 Sandbox 中验证。
如果接入支付服务商的 webhook,还需要验证签名,并通过交易编号实现幂等处理,避免同一通知创建两笔 Customer Payment。
不建议直接用脚本保存或处理卡号
不要在自定义字段、脚本参数、日志或自建数据库中保存以下信息:
- 完整卡号;
- CVV;
- PIN;
- OTP 或 3-D Secure 验证内容。
卡片凭证应使用支付服务商提供的 token,或由 NetSuite 支持的 Payment Instrument 管理。即使对卡号进行了简单加密,也不代表已经符合 PCI DSS 等合规要求。
实施前需要确认的事项
先向支付服务商确认以下能力:
- 是否接受目标地区和卡组织的 Debit Card;
- 是否支持 tokenization;
- 是否允许后续 merchant-initiated transaction;
- 首次付款是否必须进行 3-D Secure 或其他持卡人验证;
- 如何处理 token 失效、换卡和拒付;
- 是否支持部分退款、重复扣款检测和 webhook;
- 自动扣款是否需要客户单独授权或签署 mandate。
然后在 NetSuite 中确认:
- 是否已启用 Customer Deposit、Billing Schedule 和相关支付功能;
- 支付处理插件或 SuiteApp 是否支持当前业务;
- 订金应用到 Invoice 时的会计处理是否正确;
- 如何处理多币种、税费、退款和订单取消;
- 扣款失败后的重试次数、通知方式和催收规则;
- 是否需要通过 Map/Reduce 或 Scheduled Script 定期处理到期账单。
更合适的实现选择
如果客户只需要分期开票,不要求自动扣款,可以使用 Sales Order、Customer Deposit、Billing Schedule 和 Invoice。这种方案的实施风险最低。
如果必须自动扣取 Debit Card 款项,应优先选择明确支持 tokenized recurring payments 的 NetSuite 支付服务商,并取得客户授权。如果当地 Debit Card 对周期扣款限制较多,可以改用 ACH、SEPA Direct Debit,或在每期发送付款链接。
NetSuite 负责管理订单、账单和应收状态,卡片凭证与实际扣款则交给合规的支付服务商处理。
备注:内容仅供参考。
