废话不多说。在看本文前,你一定要看官方文档!
明确你要接入服务商模式 还是普通商户模式
本文使用IJPAY实现
开发必要参数说明
2.以上说明是服务商模式的,需要获取sub_xx,普通商户模式不需要sub_xx的信息
服务商模式 支付参数:
app_id 小程序id
sp_mchid 服务商支付号
sp_appid 服务商appid
sub_mchid 子商户
sub_appid 子商户appid (如果不是每个子商户独立小程序,该参数可以为空)
sp_mchKey 服务商密钥
普通商户模式 支付参数
app_id 小程序id
mchid 支付号支付号
mchKey 支付密钥
如果不需要退款、红包等等操作账户内余额的操作,其他参数如证书是不需要的。
发起支付
普通商户模式:
bash
//需要通过授权来获取openId
String openId = (String) request.getSession().getAttribute("openId");
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
Map<String, String> params = UnifiedOrderModel
.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("IJPay 让支付触手可及-小程序支付")
.attach("Node.js 版:https://gitee.com/javen205/TNWXX")
.out_trade_no(WxPayKit.generateStr())
.total_fee("1000")
.spbill_create_ip(ip)
.notify_url(notifyUrl)
.trade_type(TradeType.JSAPI.getTradeType())
.openid(openId)
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String xmlResult = WxPayApi.pushOrder(false, params);
log.info(xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
String returnCode = result.get("return_code");
String returnMsg = result.get("return_msg");
if (!WxPayKit.codeIsOk(returnCode)) {
return new AjaxResult().addError(returnMsg);
}
String resultCode = result.get("result_code");
if (!WxPayKit.codeIsOk(resultCode)) {
return new AjaxResult().addError(returnMsg);
}
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
String prepayId = result.get("prepay_id");
Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(wxPayApiConfig.getAppId(), prepayId,
wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String jsonStr = JSON.toJSONString(packageParams);
log.info("小程序支付的参数:" + jsonStr);
return new AjaxResult().success(jsonStr);
服务商模式: 只需要改
bash
return UnifiedOrderModel.builder()
.appid(appId) // 服务商小程序id
.mch_id(wxPayInfo.getMchId())//服务商
.body(body)
.attach(JSON.toJsonString(attachMap))
.sub_mch_id(subMchId)//子商户的微信收款号
.sub_appid(appId)//如果子商户独立小程序,需要这个
.sub_openid()//子商户独立小程序的用户openid
.openid(userObj.getUnionId())//服务商用户openid
.nonce_str(WxPayKit.generateStr())
.out_trade_no(orderNo)
.total_fee(String.valueOf(payAmount))
.spbill_create_ip(getClientIp(request)) // 需要实现这个方法获取客户端IP
.notify_url(wxPayInfo.getNotifyUrl())
.trade_type("JSAPI")
.build()
.createSign(wxPayInfo.getMchKey(), SignType.HMACSHA256);
这里参数要选择一下,如果你子商户是独立的小程序
bash
.appid(appId) // 服务商小程序id
.mch_id(wxPayInfo.getMchId())//服务商
.sub_mch_id(subMchId)//子商户的微信收款号
.sub_appid(appId)//如果子商户独立小程序,需要这个
.sub_openid()//子商户独立小程序的用户openid
非独立小程序,也就是一个品牌下多个门店用一个小程序但是门店收款账户独立
bash
.appid(appId) // 服务商小程序id
.mch_id(wxPayInfo.getMchId())//服务商
.sub_mch_id(subMchId)//子商户的微信收款号
.openid(userObj.getUnionId())//服务商用户openid
这样支付就发起成功了。
回调
bash
```bash
@RequestMapping(value = "/payNotify", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String payNotify(HttpServletRequest request) {
String xmlMsg = HttpKit.readData(request);
log.info("支付通知=" + xmlMsg);
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
String returnCode = params.get("return_code");
// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
// 注意此处签名方式需与统一下单的签名类型一致
if (WxPayKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.HMACSHA256)) {
if (WxPayKit.codeIsOk(returnCode)) {
// 更新订单信息
// 发送通知等
Map<String, String> xml = new HashMap<String, String>(2);
xml.put("return_code", "SUCCESS");
xml.put("return_msg", "OK");
return WxPayKit.toXml(xml);
}
}
return null;
}
> 如果你还需要其他的如分账、企业付款、退款等操作,请去IJPAY官网查看或者[下载DEMO](https://gitee.com/javen205/IJPay/tree/master/IJPay-Demo-SpringBoot)