最近项目中支付部分涉及到微信支付,使用的是h5支付,官方文档中是没有demo的,所以摸着石头过河,将踩过的坑记录如下。
一 应用场景
H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发起本服务呼起微信客户端进行支付。 主要用于触屏版的手机浏览器请求微信支付的场景。可以方便的从外部浏览器唤起微信支付。有关于h5支付接口详细相关内容可以参考官方文档微信H5支付,本文主要记录实现代码及遇到的问题。
二 服务商模式介绍
服务商模式,适用于帮助其他商户接入微信支付的开发公司,该公司在微信开通的商户称为服务商。服务商在商户平台的服务商配置里,可以帮助商户提交公司或者个体户的资料,申请通过后可以获得特约商户号和密码,这个特约商户也可以称为是子商户,服务商可以对其下的子商户的功能进行配置。这样在一个服务商下面,可以实现对不同的客户提供微信支付服务,资金直接进入子商户的微信账户中(或银行对公户中)。
三 实现代码
1.调用微信统一下单接口
public class WxPay {private static final Logger logger = Logger.getLogger(WxPay.class);
public Map<String,String> wxPay(HttpServletRequest request){ // 账号信息 String appid = ""; // 公众账号ID String mch_id = ""; // 商户号 String sub_mch_id = ""; // 子商户号 String key = ""; // 微信密钥key String nonce_str = creRandStr(); // 随机字符串 String body = "1"; // 商品描述 String out_trade_no = "wxTest2"; // 商户订单号 String total_fee = "1"; // 总金额,单位为分 String spbill_create_ip = getRealIp(request); // 终端IP String notify_url = ""; // 回调通知地址 String trade_type = "MWEB"; // 交易类型,H5支付的交易类型为MWEB String scene_info = "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"https://pay.qq.com\",\"wap_name\": \"腾讯充值\"}}"; // 场景信息,可参考官方文档 Map<String,String> packageParams = new HashMap<>(); packageParams.put("appid",appid); // 公众账号ID packageParams.put("mch_id",mch_id); // 商户号 packageParams.put("sub_mch_id",sub_mch_id); // 子商户号 packageParams.put("nonce_str",nonce_str); // 随机字符串 packageParams.put("body",body); // 商品描述 packageParams.put("out_trade_no",out_trade_no); // 商户订单号 packageParams.put("total_fee",total_fee); // 总金额,单位为分 packageParams.put("spbill_create_ip",spbill_create_ip); // 终端IP packageParams.put("notify_url",notify_url); // 通知地址 packageParams.put("trade_type",trade_type); // 交易类型,H5支付的交易类型为MWEB packageParams.put("scene_info",scene_info); // 场景信息 String sign = createSign(packageParams,key); // 签名 packageParams.put("sign",sign); String xml = getRequestXml(packageParams); logger.info("xml-->" + xml); //请求微信统一下单接口,成功后返回预支付交易会话标识prepay_id String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String result = getPayNo(createOrderURL,xml); //返回结果,

