记录微信支付JSAPI(Java)

 

记录下自己的学习,有坑。欢迎指正,轮子很多。小伙伴们可以去其他地方找找,我参考了好多能直接跑起来的代码,想贴链接的,找不到了。。。。。

 

微信支付:

public class WxPay {
    
    /**
     * 
     * @param request 
     * @param orderSum //订单金额
     * @param order   //订单
     * @param payMethod //支付方式---只有微信支付
     * @param attach // 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用。
     * @return
     */
    public JSONObject wechatPay(HttpServletRequest request,Double orderSum,Order order, Integer payMethod, String attach) {
        SortedMap<String, String> payInfo = null;
        Date now = new Date();
        Customer customer = null;
        logger.error("..............微信支付.......");
        if (null != order) {
            customer = customerService.selectById(order.getCustomerId());
            if (null != customer) {
                // 微信支付统一下单
                XMLReturn rb = wxUnifiedOrder(order.getCode(), orderSum, customer.getOpenId(),
                        request.getRemoteAddr(), attach);
                if (null != rb.getResultCode() && rb.getResultCode().equals("SUCCESS") && rb.getReturnCode().equals("SUCCESS")) {
                    String prepayId = rb.getPrepayId(); //微信生成的预支付会话标识,用于后续接口调用中使用,该值有效期为2小时
                    if (!StringUtils.isEmpty(prepayId)) {
                        //业务逻辑部分
                        String packages = "prepay_id=" + prepayId;
                        /***
                         * 备注:prepay_id 通过 微信支付统一下单接口 拿到,paySign 采用统一的微信支付 Sign 签名生成方法,
                         * 注意这里 appId 也要参与签名,appId 与 config 中传入的 appId 一致,
                         * 即最后参与签名的参数有appId, timeStamp, nonceStr, package, signType。
                         */
                        payInfo = this.wxPay(packages, Config.MCHKEY);  //MCHKEY-微信支付商户密钥
                        logger.error("返回payInfo:" + payInfo.toString());
                        jsonObj.put("payInfo", payInfo);
                        jsonObj.put("code", 100000);
                        jsonObj.put("msg", "SUCCESS");
                    }
                } else {
                    logger.error("支付失败,错误码为:" + rb.getErrCode() + ", 错误原因:" + rb.getErrCodeDes());
                    jsonObj.put("code", 100003);
                    jsonObj.put("msg", "支付失败");
                }
            } else {
                jsonObj.put("code", 100004);
                jsonObj.put("msg", "当前用户不存在");
            }
        } 
        return jsonObj;
    }


    //统一下单
    public XMLReturn wxUnifiedOrder(String orderCode, Double totalFee, String openid, String userIP, String attach) {
        NumberFormat f = NumberFormat.getIntegerInstance();
        f.setGroupingUsed(false);
        SortedMap<String, String> params = new TreeMap<String, String>();
        params.put("appid", Config.APPID);
        params.put("attach", attach);
        params.put("mch_id", Config.MCHID);
        params.put("body", "");
        params.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", ""));
        params.put("out_trade_no", orderCode);
        params.put("total_fee", f.format(totalFee * 100)); //单位:分
        params.put("fee_type", "1");
        params.put("notify_url", Config.NOTIFYURL); //回调的url
        params.put("spbill_create_ip", userIP);
        params.put("openid", openid);
        params.put("trade_type", "JSAPI");

        String xml = createSign(params, AppKey); //AppKey
        try {
            XMLReturn ret = this.xmlPost(Config.UNIFIEDORDER_URL, xml.toString());
            return ret;
        } catch (WeixinApiException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    //排序
    private SortedMap<String, String> wxPay(String packages, String paySignKey) {
       SortedMap<String, String> params = new TreeMap<String, String>();
       params.put("appId", Config.APPID);
       params.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
       params.put("nonceStr", "");//支付签名随机串,不长于 32 位
       params.put("package", packages);
       params.put("signType", "MD5");
       String signature = createSign(params, paySignKey); 
       params.put("paySign", signature);
       return params;
   }
    
    /**
     * @param params
     * @Author: HONGLINCHEN
     * @Description:请求值转换为xml格式 SortedMap转xml
     * @Date: 2017-9-7 17:18
     */
    private String SortedMaptoXml(SortedMap<String, String> params) {
        StringBuilder sb = new StringBuilder();
        Set es = params.entrySet();
        Iterator it = es.iterator();
        sb.append("<xml>\n");
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            sb.append("<" + k + ">");
            sb.append(v);
            sb.append("</" + k + ">\n");
        }
        sb.append("</xml>");
        return sb.toString();
    }
    
    /**
     * 创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
     */
    private String createSign(SortedMap<String, String> packageParams, String AppKey) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + AppKey);
        String sign = MD5Util.md5Encode(sb.toString(), "UTF-8").toUpperCase();
        return sign;
    }
    
}

支付回调:

public String callbackWx(HttpServletRequest request) {
    try {
        logger.error("............回调成功....");
        BufferedReader reader = null;
        reader = request.getReader();
        String line = "";
        String xmlString = null;
        StringBuffer inputString = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        xmlString = inputString.toString();
        request.getReader().close();
        System.out.println("----接收到的数据如下:---" + xmlString);
        WeChatPayResultLog chatPayResultLog = (WeChatPayResultLog) XmlUtils.stringToObject(xmlString, WeChatPayResultLog.class);
        // 业务逻辑部分 --  做出判断 return 结果告诉微信
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "success";
}



其他说明:

/**
 * 回调类 --- WeChatPayResultLog / XMReturn   xml与对象的互相转的工具类,也有很多的。
 */
@XmlRootElement(name="xml")
@XmlAccessorType(XmlAccessType.FIELD)
public class WeChatPayResultLog implements Serializable {
   private static final long serialVersionUID = 8152863814242851179L;
   @XmlElement(name="return_code")
   private String returnCode;
   @XmlElement(name="return_msg")
   private String returnMsg;
   @XmlElement(name="appid")
   private String appid;
   @XmlElement(name="mch_id")
   private String mchId;
   //省略部分,以及 getter/setter
}

 

 


 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值