在Java商城项目中集成微信平台收付通实现购物车合并支付及平台抽成,需基于微信支付的服务商模式或直连模式,通过收付通的合单支付和分账接口完成。以下是关键步骤及代码实现逻辑:
一、系统架构与前置条件
-
资质准备
- 平台主体需具备ICP许可证或EDI许可证(主体与微信商户号一致)。
- 开通微信支付服务商或直连商户号,并在微信商户后台启用**“平台收付通”** 功能。
-
二级商户入驻
- 平台通过API将商家入驻为微信二级商户(子商户),获取其
sub_mchid:返回结果包含子商户号// 示例:调用二级商户入驻API Map<String, String> params = new HashMap<>(); params.put("business_code", "BUSINESS_CODE"); // 平台自定义业务号 params.put("subject_info", "{...}"); // 商户主体信息(营业执照等) String result = WxPayApi.call("https://api.mch.weixin.qq.com/v3/ecommerce/applyments/", params);sub_mchid,用于后续支付分账。
- 平台通过API将商家入驻为微信二级商户(子商户),获取其
-
绑定支付场景
- 在微信支付后台绑定商城的APPID(公众号/小程序),确保与ICP主体一致。
二、购物车合并支付实现流程
步骤1:生成合单订单
用户购物车包含多商户商品时,平台生成合单支付订单(最多50个子订单):
// 构建合单支付请求
Map<String, Object> combineOrder = new HashMap<>();
combineOrder.put("combine_appid", "PLATFORM_APPID"); // 平台APPID
combineOrder.put("combine_out_trade_no", "COMBINE_ORDER_123"); // 平台合单号
combineOrder.put("sub_orders", Arrays.asList(
new SubOrder("SUB_MCHID_A", 1000, "订单A描述"), // 子商户A订单
new SubOrder("SUB_MCHID_B", 2000, "订单B描述") // 子商户B订单
));
combineOrder.put("notify_url", "https://yourdomain.com/pay/notify"); // 支付回调地址
步骤2:调用合单支付API
使用微信支付SDK发起合单支付请求:
import com.github.wxpay.sdk.WXPay;
// 初始化微信支付配置
WXPayConfig config = new MyWxPayConfig(); // 实现WXPayConfig接口
WXPay wxpay = new WXPay(config);
// 调用合单支付接口
Map<String, String> response = wxpay.unifiedOrder(combineOrder);
if ("SUCCESS".equals(response.get("return_code"))) {
String prepayId = response.get("prepay_id"); // 获取预支付ID
// 返回前端支付参数(如JSAPI调起支付)
return buildJsapiParams(prepayId);
}
步骤3:处理支付结果回调
微信异步通知支付结果,平台需验证签名并更新订单状态:
@PostMapping("/pay/notify")
public String payNotify(HttpServletRequest request) {
Map<String, String> notifyData = parseRequest(request); // 解析回调数据
if (wxpay.isPayResultNotifySignatureValid(notifyData)) {
String combineOrderId = notifyData.get("combine_out_trade_no");
// 更新主订单状态为已支付,子订单资金进入冻结状态(默认冻结180天)
orderService.updateOrderStatus(combineOrderId, PAID);
return "<xml><return_code>SUCCESS</return_code></xml>";
}
}
三、平台抽成与分账实现
步骤1:解冻资金并分账
用户确认收货后(或满足平台规则),平台发起分账:
- 解冻子商户资金:通过分账接口解冻冻结资金。
- 平台抽佣:分账时平台抽取佣金(≤订单金额30%)。
// 构建分账请求(单笔订单)
Map<String, String> profitSharingReq = new HashMap<>();
profitSharingReq.put("transaction_id", "P20250626123456"); // 微信支付单号
profitSharingReq.put("out_order_no", "SHARE_ORDER_001"); // 分账单号
profitSharingReq.put("receivers", JSON.toJSONString(Arrays.asList(
new Receiver("SUB_MCHID_A", 700, "MERCHANT_ID"), // 子商户A分得70%
new Receiver("PLATFORM_MCHID", 300, "MERCHANT_ID") // 平台抽佣30%
)));
// 调用分账API
Map<String, String> shareResponse = wxpay.invokeProfitSharing(profitSharingReq);
⚠️ 关键限制:
- 分账比例总和≤30%(平台抽佣上限)。
- 多次分账需确保总分账额不超限。
步骤2:分账结果异步通知
处理微信分账结果回调,更新平台和子商户账务:
@PostMapping("/profit/notify")
public String profitNotify(HttpServletRequest request) {
// 验证回调签名
if (wxpay.isValidSignature(request)) {
String status = request.getParameter("status"); // SUCCESS/FAIL
if ("SUCCESS".equals(status)) {
// 更新分账状态,解冻资金转入商户账户
accountService.unfreezeSubMerchantFunds();
}
}
}
四、异常处理与优化
-
交易退款
- 需按子订单发起退款,退款金额≤子订单未分账金额。
- 若已分账,需先调用分账回退接口。
-
账期控制优化
- 冻结期默认180天,但可通过分账接口提前解冻(如用户确认收货后7天):
setAutoUnfreezeTime("7d"); // 设置自动解冻时间
- 冻结期默认180天,但可通过分账接口提前解冻(如用户确认收货后7天):
-
手续费处理
- 交易费率固定0.6%,可选择由平台或子商户承担。
- 发票开给实际承担方。
五、注意事项
-
合规性
- 禁止平台与子商户同主体(自营业务需用不同主体)。
- 分账资金必须流向真实业务参与方(避免二清风险)。
-
技术细节
- 合单支付仅支持:JSAPI/APP/小程序支付,不支持H5。
- 分账接收方需提前通过API添加(平台/供应商等)。
-
调试工具
- 日志记录所有分账操作,确保可追溯性。
总结:通过收付通的合单支付+分账能力,Java商城可实现多商户购物车合并支付及平台抽佣。核心在于合理设计资金冻结/解冻时机,遵守分账比例限制,并严格处理异步通知。完整API文档参考:微信支付平台收付通文档。