Authorize.net API:有无订阅的客户滞纳金处理
结论
可以。Authorize.Net 可以使用 Customer Information Manager(CIM)中保存的 customerProfileId 和 paymentProfileId 发起一次性扣款。家长是否参加 recurring billing subscription,不影响学校收取滞纳金或未结余额。
Authorize.Net 没有专门用于处理“滞纳金”或“余额账户”的 API。滞纳金的计算、账龄、减免和余额分配都要由学校自己的业务系统管理。系统确定应收金额后,再通过 createTransactionRequest 提交普通交易。
推荐的处理方式
订阅扣款和额外费用可以分开处理:
- 学校系统记录学费、已付款、滞纳金和未结余额。
- 账单到期后,根据业务规则计算应收金额。
- 找到对应的
customerProfileId和paymentProfileId。 - 使用
authCaptureTransaction发起一次性扣款。 - 根据交易响应更新本地账单状态。
- 查询后续结算结果,并处理失败、撤销或退款。
已加入订阅的客户可以继续使用同一个 payment profile 支付额外费用。一次性滞纳金通常不适合通过临时修改订阅金额来收取,因为修改可能影响后续账期,还可能导致重复收费。
未加入订阅的客户也按相同方式处理,前提是已经创建 customer profile 和 payment profile。如果客户还没有保存付款方式,需要先通过符合 PCI 要求的页面或令牌化流程收集付款信息,然后创建 payment profile。
发起一次性扣款
以下 XML 示例使用已有的 payment profile 收取 25.00。其中,description 仅用于说明交易内容,Authorize.Net 不会据此计算或管理滞纳金。
<?xml version="1.0" encoding="utf-8"?>
<createTransactionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<merchantAuthentication>
<name>YOUR_API_LOGIN_ID</name>
<transactionKey>YOUR_TRANSACTION_KEY</transactionKey>
</merchantAuthentication>
<refId>late-fee-2026-001</refId>
<transactionRequest>
<transactionType>authCaptureTransaction</transactionType>
<amount>25.00</amount>
<profile>
<customerProfileId>123456789</customerProfileId>
<paymentProfile>
<paymentProfileId>987654321</paymentProfileId>
</paymentProfile>
</profile>
<order>
<invoiceNumber>INV-2026-001</invoiceNumber>
<description>Late fee for overdue tuition</description>
</order>
</transactionRequest>
</createTransactionRequest>
Sandbox 请求示例:
curl 'https://apitest.authorize.net/xml/v1/request.api' \
-H 'Content-Type: application/xml' \
--data-binary @request.xml
生产环境端点为:
https://api.authorize.net/xml/v1/request.api
API 凭据不能写入前端代码,也不要提交到版本库。
如何取得付款档案
系统已保存相关 ID 时,可以直接使用。尚未保存时,可调用以下接口:
getCustomerProfileRequest:获取客户档案及其 payment profiles。getCustomerPaymentProfileRequest:获取指定的 payment profile。getSubscriptionRequest:核对现有订阅信息。
这些接口用于读取档案或订阅信息,不会发起扣款。收费需要通过 createTransactionRequest 完成。
一个客户可能有多个 payment profiles。可以让客户预先指定默认付款方式,也可以由学校系统保存每张账单对应的 paymentProfileId。不能因为某条记录排在接口返回结果的第一位,就直接用它扣款。
未结余额如何处理
假设账单如下:
原学费余额:500.00
滞纳金:25.00
本次应收:525.00
可以提交一笔 525.00 的交易,也可以把学费和滞纳金拆成两笔。Authorize.Net 只处理提交的金额,不会识别这笔款项在学校账务系统中的分配方式。
合并成一笔交易通常更方便对账,也能减少交易手续费以及多次扣款引发的争议。如果学校需要分别撤销、退款,或将款项计入不同的会计科目,可以拆分交易,同时要做好重复提交控制。
客户只支付部分余额时,可以按实际付款金额创建交易,剩余金额继续记录在学校自己的应收账款系统中。
处理交易响应
处理响应时,不能只看 HTTP 状态码。还应检查:
- 顶层
messages.resultCode transactionResponse.responseCodetransactionResponse.transIdtransactionResponse.errors- AVS 或 CVV 响应,如业务和商户配置需要
responseCode 为 1 通常表示交易已获批准。系统还应保存 transId,并通过后续查询或 webhook 跟踪结算结果。交易获得授权时,资金尚未完成最终结算。
交易被拒绝后,不要将账单标记为已支付。系统应记录拒绝信息,并以合适的方式通知付款人更新付款方式。
实现时需要注意
防止重复扣款
refId 可用于关联业务记录,但不能充当完整的幂等机制。学校系统应为每笔应收款建立唯一的收费记录,同时保存提交状态和 transId。发生网络超时后,先核对原交易是否成功,再决定是否重试。
保留订阅原有职责
订阅适合收取固定的周期性费用。滞纳金、补缴款和临时调整可以作为独立的一次性交易处理。只有需要永久调整后续每期金额时,才使用订阅更新接口。
客户授权与合规
保存付款方式不代表商户可以随时追加扣款。学校应取得适当授权,并在协议中说明滞纳金标准、扣款时间和通知方式。具体要求取决于所在地法律、卡组织规则、收单机构和商户账户配置,必要时应请支付服务商或法律顾问确认。
不要依赖 Authorize.Net 保存账务余额
Customer Profile 用于保存客户及付款方式,subscription 用于保存周期扣款计划。以下数据仍需由学校自行保存:
- 每张账单的原始金额
- 到期日期和滞纳金规则
- 已付及未付金额
- 交易与账单的对应关系
- 减免、退款、拒付和冲正记录
学校的账单系统负责计算应收款并记账,Authorize.Net 负责完成实际支付。
备注:内容仅供参考。
