轻松应对->微信小程序支付

引言:之前的项目中涉及了微信支付,今天在这里整理下记录下来。废话不多说,直接上demo

一、首先需要开通微信支付功能

小程序认证以后,可以在小程序后台,微信支付菜单栏,申请微信支付。

二、官方文档

(多读几遍文档也是很简单的)

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1

三、大致的把支付流程分成如下步骤

(1)小程序向服务端发起支付请求

(2)服务端向微信服务器发起统一下单

官网统一下单文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1

扫描二维码关注公众号,回复: 10909285 查看本文章

Tips:

1)微信提供了支付的demo和工具包:

工具包:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

里面有如下文件,我这里只用了WXPayUtil、WXPayXmlUtil,(需要对里面报错提示的地方进行修改补充)

2)用户的openid(支付用户的openid哟)

private final String UNIFIED_ORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";

private ResultInfo prePayOrder() {
        ResultInfo resultInfo = new ResultInfo();
        String appid = AppConstantsUtil.getWeixinMiniProgramAppId();//小程序appid
        final String WXPAY_KEY = AppConstantsUtil.getWeixinPayKey();//商户支付密钥
        final String timeStamp = WXPayUtil.getCurrentTimestamp()+"";//时间戳,需要多次使用
        Map<String,String> orderParamsMap=new HashMap<>();
        orderParamsMap.put("appid",appid);
        orderParamsMap.put("body","商品名称");
        orderParamsMap.put("detail","商品描述");
        orderParamsMap.put("mch_id",AppConstantsUtil.getWeixinMchId());//商户号
        String nonceStr = WXPayUtil.generateNonceStr();//随机字符串,需要多次使用
        orderParamsMap.put("nonce_str",nonceStr);
        orderParamsMap.put("notify_url","订单回调通知地址,外网必须能够访问");
        orderParamsMap.put("openid","用户的openid");
        orderParamsMap.put("out_trade_no", "商户自定义订单号");
        orderParamsMap.put("spbill_create_ip","127.0.0.1");//终端ip
        orderParamsMap.put("total_fee","金额,单位是分");
        orderParamsMap.put("trade_type","JSAPI");
        try {
            // 微信支付工具包提供的方法(参数排序、加密签名、转为xml字符串)
            String paramXmlStr = WXPayUtil.generateSignedXml(orderParamsMap, WXPAY_KEY);
            // 向微信发起post请求
            String orderResultStr = postCommand(UNIFIED_ORDER, paramXmlStr);
            // 微信支付工具包提供的方法(返回的xml字符串转为map)
            Map<String, String> orderResultMap = WXPayUtil.xmlToMap(orderResultStr);
            // 下单成功
            if("SUCCESS".equals(orderResultMap.get("return_code")) && "SUCCESS".equals(orderResultMap.get("result_code"))){
                Map<String,String> payParamsMap=new HashMap<>();
                // 这里有坑需要注意:上面发起订单的时候是appid,这里是appId
                payParamsMap.put("appId",appid);
                payParamsMap.put("nonceStr",nonceStr);//上面用到的随机字符串
                payParamsMap.put("package","prepay_id="+orderResultMap.get("prepay_id"));//订单号
                payParamsMap.put("signType","MD5");
                payParamsMap.put("timeStamp",timeStamp);//上面用到的时间戳
                System.out.println("payParamsMap"+payParamsMap.toString());
                // 微信支付工具包提供的方法,参数排序并且MD5加密生成签名
                String paySign = WXPayUtil.generateSignature(payParamsMap, WXPAY_KEY);
                payParamsMap.put("paySign",paySign);
                // 返回给小程序
               return ResultInfo.success(payParamsMap,"微信预支付下单成功!");
            }else {
                logger.info("创建预支付订单失败,{}",orderResultMap.get("err_code_des"));
                ResultInfo.error("创建订单失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultInfo;
    }

 

(3)服务端响应小程序(1)步请求,拉起支付界面

// 服务端返回的数据res

wx.requestPayment({
   'timeStamp': res.data.timeStamp,
   'nonceStr': res.data.nonceStr,
   'package': res.data.package_,
   'signType': 'MD5',
   'paySign': res.data.paySign,
    success (res) {
        console.info(res)
    },
    fail (res) {
            console.info(res)
    },
    complete (res) {
        console.info(res)
   }
})

(4)支付结果通知(用户在小程序端支付成功后,微信服务端回调通知商户)

商户对订单状态进行修改

public void wxPayCallback(HttpServletRequest request, HttpServletResponse response){
		logger.info("微信通知回调。。");
		try {
			StringBuffer sb = new StringBuffer();
			InputStream inputStream = request.getInputStream();
			String s ;
			BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
			while ((s = in.readLine()) != null){
				sb.append(s);
			}
			in.close();
			inputStream.close();
			Map<String, String> stringStringMap = WXPayUtil.xmlToMap(sb.toString());
			logger.info("订单通知回调{}",stringStringMap.toString());
			Map<String, String> resultMap = new HashMap<>();
			if ("SUCCESS".equals(stringStringMap.get("result_code"))){
                // 验证签名防止被篡改
				boolean signatureValid = WXPayUtil.isSignatureValid(stringStringMap, AppConstantsUtil.getWeixinPayKey());
				if (signatureValid) {
					logger.info("订单:{}支付成功!",stringStringMap.get("out_trade_no"));
                    // 处理自己的相关业务
					//sxqOrderService.dealOrder(stringStringMap);
                    // 返回success给微信服务端,不然微信会认为你没收到会重发共十次
					resultMap.put("return_code","SUCCESS");
					resultMap.put("return_msg","OK");
				}else{
					resultMap.put("return_code","FAIL");
					resultMap.put("return_msg","签名失败");
				}
			}else {
				logger.error("支付失败");
				resultMap.put("return_code","FAIL");
				resultMap.put("return_msg","支付失败");
			}
			PrintWriter writer = response.getWriter();
			writer.write(WXPayUtil.mapToXml(resultMap));
			writer.flush();
			writer.close();
		} catch (Exception e) {
			logger.error("参数异常");
			e.printStackTrace();
		}
	}

总结:理清整个支付流程,用上微信提供的工具包,自己只需要提供相应的数据就ok了,还是很简单。

希望对你有所微薄的帮助。

                                                                                  向上的路并不拥挤,而大多数人选择了安逸

发布了23 篇原创文章 · 获赞 41 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/feng_zi_ye/article/details/96018269