微信支付(使用官方SDK,SpringBoot)

有微信支付的需求,先是自己看了几天博客和微信的官方文档,然后选择使用官方sdk去写,问题总结如下:

1.官方sdk的加密方式需要改成MD5,这是一个官方的大坑

public WXPay(final WXPayConfig config, final String notifyUrl, final boolean autoReport, final boolean useSandbox) throws Exception {
        this.config = config;
        this.notifyUrl = notifyUrl;
        this.autoReport = autoReport;
        this.useSandbox = useSandbox;
        if (useSandbox) {
            this.signType = SignType.MD5; // 沙箱环境
        }
        else {
            this.signType = SignType.MD5;
        }
        this.wxPayRequest = new WXPayRequest(config);
    }

2.下单之后最好有能收到微信返回结果的接口,微信返回来的结果不是json格式,接收方式也需要注意

具体看代码

获取openid

@PostMapping("/getOpenid")
public JsonResult getOpenid(@RequestBody Map request){
    MyConfig config = null;
    try {
        config = new MyConfig();
    } catch (Exception e) {
        e.printStackTrace();
    }
    initMyConf(config, (String) request.get("schId"));
    //先获取四个必要参数, 拼接获取微信openid的api
    String key = "appid=" + config.getAppID()
            + "&secret=" + config.getSecret()
            + "&grant_type=" + "authorization_code"
            + "&js_code=" + request.get("code");
    String url = "https://api.weixin.qq.com/sns/jscode2session" + "?" + key;
    String result = connectUrl(url);//这里我是使用了网络代理,没要求使用正常的http请求就行
    Map map =  JSON.parseObject(result,Map.class);
    assert map != null;
    if (map.get("openid") == null) {
        return JsonResultBuilder.errorMessage(map.get("errmsg").toString());
    }
    return JsonResultBuilder.successMessage(map.get("openid").toString());
}

统一下单

@PostMapping("/unifiedOrder")
    public JsonResult unifiedOrder(@RequestBody Map request){

        MyConfig config = null;
        WXPay wxpay = null;
        try {
            config = new MyConfig();
            wxpay = new WXPay(config);
        } catch (Exception e) {
            e.printStackTrace();
        }


        Map<String, String> data = new HashMap<String, String>();
        data.put("body", (String) request.get("body"));
        //生成商户订单号
        String out_trade_no = String.valueOf(SequenceFactory.getInstance().getSeqence(ShanyuanDonor.class.getSimpleName()).nextId());
        data.put("out_trade_no", out_trade_no);
        data.put("device_info", (String) request.get("device_info"));
        data.put("fee_type", (String) request.get("fee_type"));
        data.put("total_fee", (String) request.get("total_fee"));
        //获取本机的ip地址
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String spbill_create_ip = addr.getHostAddress();
        data.put("spbill_create_ip", spbill_create_ip);
        data.put("notify_url", "https://schoolfellowtest.edu-scene.com/xyh/WXPayController/returnPayResult/");
        data.put("trade_type", "JSAPI");  // 此处指定为JS支付
        data.put("openid", (String) request.get("openid"));
        //返回5个参数和sign
        Map resultMap = new HashMap();
        try {
            Map<String, String> resp = wxpay.unifiedOrder(data);
            System.out.println("统一下单返回:" + resp);
            String return_code = (String) resp.get("return_code");
            String result_code = (String) resp.get("result_code");
            Long timeStamp = System.currentTimeMillis() / 1000;
            String nonceStr = WXPayUtil.generateNonceStr();
            resultMap.put("nonceStr", nonceStr);
            if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
                String prepayid = resp.get("prepay_id");
                resultMap.put("package", "prepay_id="+prepayid);
                resultMap.put("signType", "MD5");
                //这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
                resultMap.put("timeStamp", String.valueOf(timeStamp));
                //再次签名,这个签名用于小程序端调用wx.requesetPayment方法
                resultMap.put("appId", config.getAppID());
                String sign = WXPayUtil.generateSignature(resultMap, config.getKey());
                resultMap.put("paySign", sign);
                System.out.println("生成的签名paySign : "+ sign);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JsonResultBuilder.success(resultMap);
    }

微信返回接受

@RequestMapping(value = "/returnPayResult" , produces = "text/xml; charset=utf-8")
    @ResponseBody
    public String returnPayResult(@RequestBody String notifyData){

        MyConfig config = null;
        WXPay wxpay = null;
        Map result = new HashMap();
        try {
            config = new MyConfig();
            wxpay = new WXPay(config);
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);  // 转换成map
            if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
                //根据自己需求写
                result.put("code", "SUCCESS");
                result.put("message", "成功");
            } else {
                result.put("message", "失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSON.toJSONString(result);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值