小程序 微信支付

对微信支付这个大坑的记录

  1. 第一次签名 appid 是小写的

  2. 第二次签名appId 用的是驼峰命名

  3. 第二次签名后面需要加上商户KEY

paySign = MD5(appId=wxd678efh567hg6787&nonceStr=5K8264ILTKCH16CQ2502SI8ZNMTM67VS&package=prepay_id=wx2017033010242291fcfe0db70013231072&signType=MD5&timeStamp=1490840662&key=qazwsxedcrfvtgbyhnujmikolp111111) = 22D9B4E54AB1950F51E0649E8810ACD6

完整代码
配置

    @Value("${weixin.app_id}") // spring配置文件配置了appID
    private String appId;
    @Value("${weixin.mch_id}") // spring配置文件配置了商户号
    private String mchId; 
    @Value("${weixin.app_secret}") // spring配置文件配置了secret
    private String secret;
    @Value("${weixin.notify_url}") // spring配置文件配置了notify_url
    private String notifyUrl;
    @Value("${weixin.pay_key}") // spring配置文件配置了pay_key
    private String paykey;

主代码

/**
     * 微信预订单
     * @return
     */
    @GetMapping("wxPayUnifiedorder/{id}")
    @LoginRequired
    @ResponseBody
    public String wxPayUnifiedorder(@CurrentUser User user, @PathVariable Integer id) throws Exception {
        OrderList orderList= orderListService.findOne(user.getId(),id);
        PayInfo pi = createPayInfo(orderList,"111.58.221.46",user.getOpenId());
        //获取第一次签名
        String sign = getSign(pi);
        //存入统一下单
        pi.setSign(sign.toUpperCase());
        //将需要发送的数据转XML
        String xml=WXUtils.payInfoToXML(pi).replace("__", "_").replace("<![CDATA[", "").replace("]]>","");
        //获取微信预订单
        xml =HttpUtils.postJson("https://api.mch.weixin.qq.com/pay/unifiedorder",xml);
        Map xmlmap= WXUtils.parseXml(xml);
        //map转json 返回
        String json =gson.toJson(xmlmap);
        //将放回的数据转json对象解析
        JsonObject jsonObject = gson.fromJson(json,JsonObject.class);
        String prepayId="";
        if(!jsonObject.get("prepay_id").isJsonNull()){
            //获取返回的订单号保存到数据库
            prepayId =jsonObject.get("prepay_id").getAsString();
            orderList.setPrepayId(prepayId);
            //把多了订单号的数据保存到数据库里
            orderListService.save(orderList);
        }
        jsonObject.addProperty("prepay_id",orderList.getPrepayId());
        //使用预订单号生成第二次签名发送到小程序
        return getPaySign(orderList.getPrepayId()).toString();
    }
    /**
     * 第一次获取签名
     * @param payInfo
     * @return
     * @throws Exception
     */
    public String getSign(PayInfo payInfo)  {
        String signTemp = "appid=" + payInfo.getAppid()
                +"&attach="+payInfo.getAttach()
                +"&body="+payInfo.getBody()
                +"&device_info="+payInfo.getDevice_info()
                +"&mch_id="+payInfo.getMch_id()
                +"&nonce_str="+payInfo.getNonce_str()
                +"&notify_url="+payInfo.getNotify_url()
                +"&openid="+payInfo.getOpenid()
                +"&out_trade_no="+payInfo.getOut_trade_no()
                +"&spbill_create_ip="+payInfo.getSpbill_create_ip()
                +"&total_fee="+payInfo.getTotal_fee()
                +"&trade_type="+payInfo.getTrade_type()
                +"&key="+paykey; //这个key注意,小程序支付密钥
        String sign = DigestUtils.md5DigestAsHex(signTemp.getBytes());
        return sign;
    }

    /**
     * 第二次签名
     * @param prepayId
     * @return
     */
    public JsonObject getPaySign(String prepayId){
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("timeStamp", ""+(System.currentTimeMillis()/1000));
        jsonObject.addProperty("nonceStr",UUID.randomUUID().toString().replace("-", "").toUpperCase());
        jsonObject.addProperty("prepayId","prepay_id="+prepayId);
        jsonObject.addProperty("signType","MD5");
        String paysignStr="appId="+appId
                +"&nonceStr="+jsonObject.get("nonceStr").getAsString()
                +"&package="+jsonObject.get("prepayId").getAsString()
                +"&signType="+jsonObject.get("signType").getAsString()
                +"&timeStamp="+jsonObject.get("timeStamp").getAsString()
                +"&key="+paykey;
        String paysignM = DigestUtils.md5DigestAsHex(paysignStr.getBytes());
        jsonObject.addProperty("paySign",paysignM);

        return jsonObject;
    }
 /**
     * 创建统一下单的xml的java对象
     * @param orderList 订单对象
     * @param ip 用户的ip地址
     * @param openId 用户的openId
     * @return
     */
    public PayInfo createPayInfo(OrderList orderList, String ip, String openId) {
        PayInfo payInfo = new PayInfo();
        //小程序ID
        payInfo.setAppid(appId);
        //附加数据 用来当参数
        payInfo.setAttach("购买电动车");
        //商品描述
        payInfo.setBody("购买电动车");
        //设备号
        payInfo.setDevice_info("xiaochengxu");
        //商户号
        payInfo.setMch_id(mchId);
        //随机字符串
        payInfo.setNonce_str(UUID.randomUUID().toString().replace("-", "").toLowerCase());
        //回调地址
        payInfo.setNotify_url(notifyUrl);
        //商户订单号
        payInfo.setOut_trade_no(orderList.getOutTradeNo());
        //        notifyUrl
        payInfo.setOpenid(openId);
        //用户IP
        payInfo.setSpbill_create_ip(ip);
        //商品价格
        payInfo.setTotal_fee(orderList.getSettlementAmount().multiply(new BigDecimal(100)).intValue());
        return payInfo;
    }

猜你喜欢

转载自blog.csdn.net/a961011576/article/details/86571607