微信商户 h5支付详解

1.准备工作

appid公众账号、mch_id商户号、parentKey商户号支付秘钥

pom.xml 导入

<dependency>
	<groupId>com.github.wxpay</groupId>
	<artifactId>wxpay-sdk</artifactId>
	<version>0.0.3</version>
</dependency>

2.注意事项以及java代码

在使用过程中要注意:

        body 商品描述(这是你在微信支付页面看到的内容)

        outTradeNo  商户订单号32个字符以内,不能重复

        totalFee  支付的金额以分为单位

        ip 在微信开发文档上写的是spbill_create_ip  以下内容来自微信h5支付开发文档

        H5支付要求商户在统一下单接口中上传用户真实ip地址“spbill_create_ip”,为保证微信端获取的用户ip地址与商户端获取的一致

        为什么会讲这个ip呢?因为在跟app对接调试的时候会报以下错误:

    

通过调用此方法

扫描二维码关注公众号,回复: 2743161 查看本文章
public static Map<String, String> doPay(String body, String outTradeNo, String totalFee,String ip) throws Exception {
		WXpayConfig config = new WXpayConfig();
		WXPay wxpay = new WXPay(config);
		Map<String, String> data = new HashMap<String, String>();
		data.put("body",body);
		data.put("out_trade_no", outTradeNo);
		data.put("total_fee", (int)(new BigDecimal(totalFee).multiply(new BigDecimal("100")).doubleValue()) + "");
		data.put("spbill_create_ip", ip);
		data.put("notify_url", WXpayConfig.NOTIFY_URL);
		data.put("trade_type", "MWEB");//此为h5支付
		System.out.println("\\内容==========>"+body);
		try {
			System.out.println("\\订单号==========>"+outTradeNo);
			Map<String, String> resp = wxpay.unifiedOrder(data);
			System.out.println("\n==========>统一下单resp:" + resp);
			/**
			 * 出参APP
			 * 调起支付接口:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_12&index=2
			 */
			Map<String, String> resultMap = new LinkedHashMap<String, String>();
			resultMap.put("appid", config.getAppID());										// 应用ID
			resultMap.put("partnerid", config.getMchID());									// 商户号
			resultMap.put("prepayid", resp.get("prepay_id"));								// 预支付交易会话ID
			resultMap.put("package", "Sign=WXPay");											// 扩展字段
			resultMap.put("noncestr", WXPayUtil.generateNonceStr());						// 随机字符串
			resultMap.put("timestamp", String.valueOf(System.currentTimeMillis()/1000));	// 时间戳
			resultMap.put("sign", WXPayUtil.generateSignature(resultMap, config.getKey()));	// 签名
			resultMap.put("mweb_url", resp.get("mweb_url"));//调用支付地址
			System.out.println("\n==========>调起支付resp:" + resultMap);
			return resultMap;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

WxpayConfig.java中

配置了NOTIFY_URL、AppId、MchId、Key(商户支付秘钥)

    NOTIFY_URL 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数

    例如:

	public static String NOTIFY_URL = "http://0.0.0.0:8080/apiwx/wxpayNotify";// 测试服

当你支付完后异步回调

        @RequestMapping(value = "wxpayNotify", method = RequestMethod.POST)
	@ResponseBody
	public void wxpayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		System.out.println("\n====================>WXPay Notify");
		InputStream inStream = request.getInputStream();
		ByteArrayOutputStream ouStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			ouStream.write(buffer, 0, len);
		}
		String notifyData = new String(ouStream.toByteArray(), "utf-8");
		inStream.close();
		ouStream.close();
		System.out.println("====================>notifyData:" + notifyData);
		// ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//		String notifyData = "....";// 支付结果通知的xml格式数据
		Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);// 转换成map
		WXpayConfig config = new WXpayConfig();
		WXPay wxpay = new WXPay(config);
		if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
			// 签名正确
			System.out.println("====================>签名正确");
			if("SUCCESS".equals(notifyMap.get("return_code")) && "SUCCESS".equals(notifyMap.get("result_code"))) {
				// 通信成功 && 交易成功
				System.out.println("====================>通信成功 && 交易成功");
				String out_trade_no = notifyMap.get("out_trade_no");// 商户订单号
				String total_fee = notifyMap.get("total_fee");		// 订单总金额,单位为分
				System.out.println("====================>商户订单号:" + out_trade_no);
				System.out.println("====================>订单总金额:" + total_fee + "(分)");
				//这里可以编写你支付成功执行的代码 通过订单号来查询
				}else{ }
					
			String returnStr = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
			response.getWriter().write(returnStr);
		}else {
			String returnStr = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>";
			response.getWriter().write(returnStr);
		}
	} 


3.调起微信h5支付

在调用doPay方法后会返回一个resultMap,其中有个参数mweb_url,偷个懒


你以为这样就结束了,那就错了!


4.在调起微信时会遇到的问题

    1.网络环境未能通过安全验证,请稍后再试(这个上面有介绍),简单

说一下那个ip就是你 百度ip查到的值


2.商家参数格式有误,请联系商家解决

Referer中的回调地址一定要加http://或https://

这个我们是无法解决的,但是可以去找安卓大佬

在他的代码中加一行

             @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // 如下方案可在非微信内部WebView的H5页面中调出微信支付
                if (url.startsWith("weixin://wap/pay?")) {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(url));
                    startActivity(intent);
                    return true;
                } else {
                    Map<String, String> extraHeaders = new HashMap<String, String>();
                    extraHeaders.put("Referer", "http://wxpay.wxutil.com");
                    view.loadUrl(url, extraHeaders);
                }
                return true;
            }


3. 这个问题是由上个问题间接引起的




然后就成功的调起微信支付了!!!

猜你喜欢

转载自blog.csdn.net/qq_38423105/article/details/80026669