一笔订单带有哪些金额字段?
所有金额都是字符串而不是数字——公开说明的原因是浮点精度:
0.1 + 0.2 不等于 0.3,这对金额来说不可接受。请按 decimal 解析。
我该如何验证一笔订单就是我创建的那笔?
以你自己的paymentRequestId 或 merchantOrderId 为键,把 orderAmount + orderCurrency 与你发送的值比较。这两个字段是你自己的输入回显,所以它们是唯一一对保证等于你所要求内容的字段。
不要通过比较 finalDealAmount 与你的预期金额来验证。它在设计上就是另一个量,两种完全正常的情形都会让它不同——这就是下一个问题。
为什么 finalDealAmount 和 orderAmount 不一样?
API 契约给出了两个原因,两者都是正常的:
- 你的订单币种不是用户的支付币种。 跨币种订单由你以一种币种定价、用户以另一种币种支付,所以两个数字单位不同,不会相等。
- 用户额外支付了服务费。 当支付方式向付款人收取手续费时,该手续费包含在
finalDealAmount中,所以它比你的金额大。
finalDealAmount 回答的是*「这笔花了用户多少钱」,orderAmount 回答的是「我收了多少」*。发货和业务校验请基于 orderAmount;只有在想向用户展示他们支付了多少时才用 finalDealAmount。
orderCurrency 和 userCurrency 真的可以不同吗?
可以——这正是跨币种订单的定义:你以自己的币种定价,用户以他们的币种支付。这不是错误状态,也不限于某一类支付方式。公开的定义及配套参数见金额与币种;下单时的实际规则是,当你没有固定 payMethodType 或 payMethodName 时,跨币种订单需要 payMethodCountry,而 userCurrency 本身仍是可选的。
如果你的对账假设每笔订单只有一种币种,请从一开始就按三个字段来设计:orderCurrency(你的)、userCurrency / userPaymentCurrency(用户的),以及你的结算币种(见结算计算说明)。它们是三个独立的东西,下单时只有第一个由你控制。
用户以自己的币种到底付了多少?
paymentInfo.payMethodResponse.userPaymentAmount 加 paymentInfo.payMethodResponse.userPaymentCurrency。该块是支付方式自身对这笔交易的视图,还带有:
它是一个 JSON 字符串,具体包含哪些键取决于支付方式——请防御性地读取,不要假设固定结构。
我能用 finalDealAmount 减去用户手续费算出用户净支付吗?
不能——至少不能从查询响应算。userFeeAmount 和 userFeeCurrency 返回在订单创建响应的 orderAction.actionData 中,而不是作为订单查询或支付通知的顶层字段。所以在你对账的那一刻,通常手上没有单独的手续费数字可减,而且跨两种币种做减法本来就是错的。
请改用:
- 我收到的金额对吗? →
orderAmount+orderCurrency。 - 用户总共付了多少? →
finalDealAmount,或支付方式一侧的数字userPaymentAmount。 - 手续费是多少? → 在创建时捕获
actionData.userFeeAmount并存下来,如果之后需要。
用户手续费只在柜台(over-the-counter)支付时收取吗?
API 没有这样限定。userFeeAmount / userFeeCurrency 位于 orderAction.actionData,这是面向自建收银台商户的块,契约中没有任何内容把它们限制在某一个 payMethodType。把付款人手续费当作在任何支付方式上都可能出现,读字段本身,而不是按支付方式类别去判断——与 finalDealAmount 的建议一样:读它,不要推断它。
如果你使用 Waffo 收银台页面,用户会在收银台上直接看到手续费;你不需要渲染它。
originalAmount 是什么?折扣应该按哪个金额校验?
originalAmount 是应用折扣之前的订单金额。使用了促销码或优惠券时,orderAmount 是折后应付金额,originalAmount 是你定价的折前数字。
所以对于业务校验——权益、履约、「他们为这个 SKU 付够了吗」——用 orderAmount,因为那是实际收取的金额。originalAmount 只用于展示或衡量折扣影响。优惠券和促销码的机制,包括退款时折扣如何处理,见优惠券与促销码。
我的财务应该按哪个金额对账?
orderAmount 和 finalDealAmount 单独哪个都不行——它们是订单级字段,在手续费和结算换汇之前。资金对账请使用结算报表,它把金额、手续费和结算币种放在一起:结算报表和结算计算说明。
订单级字段用于订单对账——证明你创建的订单就是被支付的那笔。把两件事分开做;这是「你的数字和我的对不上」最常见的单一原因。
我必须用本地币种创建订单吗?
不必。orderCurrency 是你的定价币种,跨币种订单——你以一种币种定价、用户以另一种币种支付——是受支持的一等流程。某个支付方式能否服务某个订单币种取决于你账户上的合约,这是一次查询,不是猜测:
由于该响应以合约为键,同一个支付方式可能出现多次——每个币种一次。
payMethodName 不是唯一键。详情见支付方式配置与限额。
某个支付方式只列了一种币种,我还能用另一种币种定价吗?
把两种币种分开看:- 支付币种——向用户收取时用的币种。对本地支付方式来说,这实际上由支付方式本身固定。
- 订单币种——你定价用的币种,也是向你计费和结算的币种。
A0018,即合约不匹配码,而不是币种专属错误;见限额、币种与配置类错误。
跨币种订单的汇率在哪里看?
两个不同的汇率,两个不同的字段:
它们回答不同的问题,可能不一样。汇率何时固定、有效多久、退款用哪个汇率,都在支付与结算中的汇率。
我可以传几位小数?取决于币种吗?
是的,取决于币种,而且同币种和跨币种订单的规则不同。公开的规则是:大多数币种按 ISO 4217 取两位小数,一组币种在同币种订单中必须不带任何小数,而在跨币种订单中每种币种都必须遵循其 ISO 4217 精度,没有例外。完整列表和拒绝行为见金额与币种和订单金额、限额与拒绝。 各支付方式的金额范围是与精度独立的另一项检查:它们来自合约上的orderAmountMin / orderAmountMax,所以请在创建订单前按这两个值校验,而不是从错误码里发现限额。
一笔退款带有哪些金额字段?
remainingRefundAmount 是你自己「还能不能退」逻辑应依据的字段,而不是从自己的记录重新计算——它已经把该订单上的每一笔退款都算进去了,包括不是你自己发起的那些。退款规则本身见退款 FAQ和各支付方式的退款限制。
还是不确定该比较哪个字段?联系支持,附上你的
paymentRequestId 和两个不一致的数字。