直付通支付后如何查询支付宝手续费及实际到账金额
结论
直付通支付完成后,通常无法仅凭支付结果确定”手续费率”和”手续费承担方”,需要分别查询:
- 支付金额和商户实收金额:调用
alipay.trade.query,查看total_amount、buyer_pay_amount、receipt_amount等字段。 - 最终结算到账金额和实际扣费:查看支付宝商家中心的账单、资金明细,或通过
alipay.data.dataservice.bill.downloadurl.query下载账单。 - 签约费率:查看直付通产品的签约信息或支付宝商家中心。支付查询接口通常不返回签约费率。
- 手续费由二级商户还是平台承担:取决于直付通签约主体、费用承担模式,以及平台与二级商户之间的结算规则,没有统一答案。
如果平台自行与二级商户结算,即便支付宝从平台侧扣费,平台也可以根据双方协议将费用分摊给二级商户。因此,核对费用时要区分两个问题:支付宝向谁收费,以及平台内部最终由谁承担。
为什么支付结果不能直接代表最终到账
用户支付成功后,至少会涉及以下三类金额:
- 用户支付金额;
- 支付宝侧确认的商户实收金额;
- 经过结算、分账、退款或其他资金处理后的最终到账金额。
这些金额未必相等,常见原因包括:
- 支付宝按签约费率收取服务费;
- 订单发生部分退款或全额退款;
- 直付通订单还需分账或结算;
- 平台另行收取技术服务费或佣金;
- 账单费用按日汇总,并非每笔交易都立即扣除;
- 优惠、积分、红包等使付款构成发生变化;
- 支付成功和资金结算到账不在同一时间。
因此,alipay.trade.query 适合确认订单状态和支付金额。财务核对则应查看账单或资金明细。
第一步:查询支付订单
调用:
alipay.trade.query
查询时可传入支付宝交易号 trade_no,也可以传入商户订单号 out_trade_no。
Java 示例:
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.setBizContent("""
{
"out_trade_no": "202609090001"
}
""");
AlipayTradeQueryResponse response = alipayClient.execute(request);
if (response.isSuccess()) {
System.out.println("支付宝交易号: " + response.getTradeNo());
System.out.println("订单金额: " + response.getTotalAmount());
System.out.println("买家实付金额: " + response.getBuyerPayAmount());
System.out.println("商户实收金额: " + response.getReceiptAmount());
System.out.println("交易状态: " + response.getTradeStatus());
} else {
System.out.println("查询失败: " + response.getSubCode());
System.out.println("失败原因: " + response.getSubMsg());
}
具体的 SDK 类名和可用字段应以当前接入版本的支付宝开放平台文档为准,不同 SDK 版本未必提供完全相同的 getter。
各字段含义如下:
total_amount:订单总金额;buyer_pay_amount:买家实际支付金额;receipt_amount:接口定义中的商户实收金额;trade_status:交易状态。
receipt_amount 不能直接视为银行卡最终到账金额。直付通场景中,后续还可能发生结算、分账和费用扣除。
第二步:下载账单核对实际手续费
账单下载接口为:
alipay.data.dataservice.bill.downloadurl.query
常用账单类型包括:
trade:业务账单;signcustomer:签约账户账务账单。
Java 示例:
AlipayDataDataserviceBillDownloadurlQueryRequest request =
new AlipayDataDataserviceBillDownloadurlQueryRequest();
request.setBizContent("""
{
"bill_type": "trade",
"bill_date": "2026-09-08"
}
""");
AlipayDataDataserviceBillDownloadurlQueryResponse response =
alipayClient.execute(request);
if (response.isSuccess()) {
String downloadUrl = response.getBillDownloadUrl();
System.out.println("账单下载地址: " + downloadUrl);
} else {
System.out.println("账单申请失败: " + response.getSubCode());
System.out.println("失败原因: " + response.getSubMsg());
}
下载并解压账单后,可通过商户订单号或支付宝交易号匹配交易记录,再读取账单实际提供的服务费、实收金额等列。
账单字段会因产品、账单类型和接入模式而有所不同。程序应根据下载文件的表头解析,不要写死某份示例账单中的列序号。
账单下载地址通常有时效限制,获取后应及时下载,也不要将地址写入公开日志。
第三步:确认费率和费用承担方
费率通常属于签约配置,不会随每笔支付动态返回。可以通过以下方式确认:
- 登录支付宝商家中心,查看直付通产品的签约信息;
- 查看平台与支付宝签订的产品协议或费率协议;
- 查看二级商户进件、签约时约定的费用承担模式;
- 联系支付宝服务商、客户经理或开放平台技术支持;
- 检查平台与二级商户之间的结算协议。
如果支付宝按比例计费,可用以下公式估算单笔费用:
预计支付宝手续费 = 计费金额 × 签约费率
例如,计费金额为 100 元,签约费率为 0.6%,理论手续费为:
100 × 0.6% = 0.60 元
这只是估算值。实际费用还可能受到计费基数、优惠费率、费用减免、四舍五入规则、支付渠道和退款规则的影响。财务入账仍应以账单为准。
二级商户应该如何查看
二级商户能否直接查看支付宝手续费,取决于其是否拥有对应的商家账号和账单权限,以及资金是否直接结算到该商户账户。
通常分为两种模式:
支付宝直接结算给二级商户
如果二级商户是实际收款和结算主体,并拥有商家中心权限,可以在自己的资金明细或账单中查询实收金额和费用。平台获得合法授权后,也可以通过接口协助查询。
平台统一收款后再结算
如果支付宝只向平台账户结算,二级商户通常无法直接通过支付宝查询自己的最终到账金额。平台需要建立结算明细,并向二级商户展示:
订单金额
- 支付宝手续费
- 平台服务费
- 退款金额
- 其他调整金额
= 应结算金额
例如:
应结算金额 = 用户实付金额
- 支付宝手续费
- 平台佣金
- 已退款金额
± 其他资金调整
平台展示的数据还应关联 out_trade_no、trade_no、结算批次和账单日期,方便二级商户对账。
注意事项
- 不要只依据支付异步通知计算最终到账金额。异步通知主要用于告知交易状态,不能替代完整的财务账单。
receipt_amount是支付查询接口中的实收口径,未必等于结算账户的最终入账金额。- 不能根据接口调用者判断手续费承担方,应以支付宝签约关系和平台结算协议为准。
- 如果需要逐笔向二级商户展示手续费,建议每天下载支付宝账单,并与平台订单进行匹配。
- 退款后的手续费是否退还以及如何退还,应按对应产品和签约规则处理,不能简单地按原费率反算。
- 金额计算应使用
BigDecimal,不要使用double。
BigDecimal paidAmount = new BigDecimal("100.00");
BigDecimal feeRate = new BigDecimal("0.006");
BigDecimal estimatedFee = paidAmount
.multiply(feeRate)
.setScale(2, RoundingMode.HALF_UP);
BigDecimal estimatedSettlement = paidAmount.subtract(estimatedFee);
System.out.println("预计手续费: " + estimatedFee);
System.out.println("预计结算金额: " + estimatedSettlement);
上述代码仅适用于费率已经确认后的预估。最终手续费和到账金额仍以支付宝账单、资金明细及实际结算记录为准。
备注:内容仅供参考。
