金额不能只有数字,还要有单位与尺度
支付接口里的 1000 究竟是一千元还是十元,不能靠页面上的货币符号猜测。Adyen 文档要求交易金额同时指定币种与数值,多数 API 使用该币种的最小单位。[1] 本文建议把金额、币种、尺度及接口用途作为一个整体定义:展示字符串负责让人读懂,计算值负责运算,请求值遵守接收方契约。下文是文档研究与编辑建议,不代表 PayIn 的字段定义或产品能力。接口没有说明单位时应先确认,不要通过发起真实扣款来试探倍率。
不要把“乘以一百”写成全球规则
Adyen 的表格中,JPY 为零位小数,BHD 为三位;ISK 则标为两位,并注明不同于标准。[1] 因此同一个通用币种表不能自动替代供应商接口约定。建议按供应商、接口操作与币种维护经过审核的尺度映射,记录来源和生效版本。示例:尺度为二时,十进制字符串 12.34 对应整数 1234;尺度为三时,12.340 对应 12340。未知币种、缺失尺度或超出允许小数位的输入应进入明确的拒绝或审核路径,而不是默认两位后静默截断。
整数存储与十进制计算并不矛盾
Fintech Engineering Handbook 将整数最小单位存储与高精度十进制中间计算视为可以组合的选择。[4] 建议已确定的应付金额使用受控尺度的整数或精确十进制类型,费率、单价与中间结果保留业务需要的额外精度。整数也不意味着除法没有余数,十进制类型也不意味着所有除法都能有限表示。实现时从原始十进制文本解析,显式设置计算精度,检查乘法后的范围;不要先转二进制浮点,再期待换成 Decimal 能恢复原始输入。显示两位小数只是展示动作,不应覆盖计算底稿。
把舍入模式和发生位置分别写清楚
Python decimal 文档将 HALF_EVEN 定义为中点取邻近偶数,将 HALF_UP 定义为中点远离零,并把 FLOOR 定义为朝负无穷舍入。[3] 按这些定义,保留两位时 1.005 的前两种结果分别为 1.00 和 1.01;负数 -1.005 则分别为 -1.00 和 -1.01。建议规格同时写明目标尺度、模式、正负数处理、发生步骤与责任人,不能只写“四舍五入”。例如三个精确值 0.005,逐项 HALF_UP 后相加得到 0.03,先相加再舍入得到 0.02;这是舍入位置不同,不是显示错误。税务或合同要求逐项计算时应遵守,不能把“只在最后舍入”当作通用法规。
拆分总额时分配余数,不让一分钱消失
Stack Overflow 的工程讨论区分了存取精度与除法产生的余数,并用 10.00 拆成三个 3.33 展示剩下的 0.01。[5] 这类讨论能帮助识别边界,却不是会计规范。建议在业务允许分配时,先确定总额,再用明确算法分配整数最小单位。例如 1000 分三份,可以是 334、333、333;若采用最大余数法,余数相同时也要规定稳定排序。记录哪一份取得额外单位及其规则,检查各份之和严格等于总额。若合同禁止重新分配,应按获批规则保留差额,不要悄悄改某一行以凑齐数字。
JSON 与数据库边界也要保住整数
RFC 8259 指出,使用其讨论的常见数值实现时,位于 -(2^53)+1 至 (2^53)-1 范围内的整数能够获得精确一致的互操作结果。[6] 这不是说 JSON 语法禁止更大的数字,而是提醒接收端可能无法保持精度。建议逐段检查浏览器、服务端、数据库驱动与导出工具,确认金额没有隐式转成浮点。超出接收方安全范围时,只有协议允许才能使用字符串并配合大整数或十进制解析;第三方要求数值字段时不能私自换类型。先验证范围再发送,避免数值已经被改写后才检查。
用边界样例验收,而不是只测 9.99
建议测试集覆盖零位、两位与三位尺度,供应商特殊规则,0、最小单位、最大允许金额、超限值、多余小数位以及正负中点;仅在业务允许负值的操作中接受负金额。另测逐项与汇总舍入的差异、等分余数、序列化往返及数据库读写后的类型。上述数值是演算示例,不是已完成的支付测试。验收应留下输入文本、尺度版本、舍入规则与预期值,由独立计算复核;任何组件结果不一致都应阻止上线。本文不提供税务结论,实际收取金额及舍入顺序仍需以适用合同、法规和接口规范为准。
来源与日期
本次核验日期:2026-09-20。来源日期按原页面明确标注的发布或更新时间分别列示;未标注不等于本日发布。本文为公开文档研究,未进行真实支付、安全审计或辅助技术合规认证。厂商事实仅归属于被引用厂商;流程建议为编辑综合。
继续阅读最新内容
支付 API 密钥泄露后,怎样完成轮换而不漏掉后台任务? →
支付查询遇到 429/503:怎样设置退避、重试预算与恢复节奏? →
全部操作资料 →