微信小程序支付-java对接微信

 一共是两个方法:

一个方法后台生成预支付订单,得到预支付交易会话标识prepay_id,传给前端,让前端调起小程序支付;

一个是支付回调

目录

一、生成预支付订单 

注意:

二、 支付回调


一、生成预支付订单 

        封装参数向微信发送生成预支付交易单请求,微信会返回一个prepay_id,再将prepay_id与前段调起小程序支付所需参数一起给前端。

SortedMap<String,String> parameters = new TreeMap<>();

//先调用该接口在微信支付服务后台生成预支付交易单,获得prepay_id,用于调起支付
parameters.put("appid", appid);
parameters.put("mch_id", mchId);
parameters.put("openid", openid);
parameters.put("nonce_str", ToolUtil.getRandomString(32));//随机字符串
parameters.put("body", BODY);//商品信息
parameters.put("out_trade_no", orderSn);// 系统内部订单号,自生成
parameters.put("total_fee",totalFee);//真实金额,一定要整数
parameters.put("spbill_create_ip",spbillCreateIp);//调用微信支付API的机器IP
parameters.put("notify_url",notifyUrl);//通知地址
parameters.put("trade_type",TRADE_TYPE);//小程序固定取值:JSAPI

//将所有参数一起生成sign签名,一次签名
String sign = WeixinPayUtil.createSign(parameters,key);//MD5
parameters.put("sign",sign);

//参数封装完后,转xml格式,发起https请求,POST请求
String xml = WeixinPayUtil.getRequestXml(parameters);
Result result = WeixinPayUtil.sendRequest(xml, WeixinPayUtil.UNIFIED_ORDER_URL, HttpMethod.POST);

//获取请求返回的值prepay_id,加上前段调起支付API所需参数,返回给前端
Map<String, String> map  = (Map<String, String>) result.getData();
SortedMap<String,String> resultMap = new TreeMap<>();
resultMap.put("appId",appid);
resultMap.put("timeStamp",String.valueOf(System.currentTimeMillis()/1000));
resultMap.put("nonceStr", ToolUtil.getRandomString(32));//随机字符串
resultMap.put("package","prepay_id="+map.get("prepay_id"));//固定拼接格式
resultMap.put("signType","MD5");//签名类型MD5
//拼接key值,用所有参数生成sign签名并转MD5,二次签名,这里跟官方文档多拼接了一个key值,官方文档没写,但是需要
String paySign = WeixinPayUtil.createMiniSign(resultMap,key);
resultMap.put("paySign",paySign);
resultMap.put("orderSn", orderSn);
return ResultUtil.success(resultMap);

 发送http请求,老方法,自行选择是否使用

/**
     * 发送http请求
     * @param xml
     * @param url
     * @param method
     * @return
     */
    public static Result sendRequest(String xml, String url, HttpMethod method){
        YZLHttpClient client = YZLHttpClientFactory.create(YZLHttpClientFactory.HttpType.Mine);
        String result = client.sendRequestWithXml(url,xml,method);
        Map<String,String> map;
        try {
            map = WeixinPayUtil.doXMLParse(result);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (JDOMException e) {
            throw new RuntimeException(e);
        }
        if(! map.get("return_code").equals("SUCCESS"))
            return ResultUtil.error(ErrorCodeEnum.FAILED);
        return ResultUtil.success(map);
    }

 参数转xml工具类,老方法,自行选择是否使用

 /**
     * 组装xml
     * @param params
     * @return
     */
    public static String getRequestXml(SortedMap<String,String> params){
        StringBuffer sb = new StringBuffer();
        sb.append("<mapping>");
        Set es = params.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()){
            Map.Entry entry = (Map.Entry)it.next();
            String key = (String) entry.getKey();
            String value = entry.getValue().toString();
            if("attach".equalsIgnoreCase(key) || "body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)){
                sb.append("<"+key+">"+"<![CDATA["+value+"]]></"+key+">");
            }else {
                sb.append("<"+key+">"+value+"</"+key+">");
            }
        }
        sb.append("</mapping>");
        return sb.toString();
    }

 sign算法,这里跟官方文档多拼接了一个key值,官方文档没写,但是需要

/**
     * 微信小程序支付签名算法sign
     * @param parameters
     * @return
     */
    public static String createMiniSign(SortedMap<String,String> parameters, String apiKey){
        StringBuffer sb = new StringBuffer();
        Set<Map.Entry<String, String>> es = parameters.entrySet();

        for(Map.Entry<String, String> entry : es){
            String k = entry.getKey();
            String value = entry.getValue();
            if(value != null && !"".equals(value) && !"sign".equals(k) && !"key".equals(k)){
                sb.append(k+"="+value+"&");
            }
        }
        sb.append("key="+apiKey);
        String sign = MD5Util.encrypt(sb.toString()).toUpperCase();
        return sign;
    }

注意:

1.生成第一次签名,参数封装key值用下划线,生成二次签名参数封装key值要用驼峰命名 

2.生成二次签名的参数数量一定要与官方接口文档保持一致,最好顺序也保持一致

二、 支付回调

我用的是支付完成后查询订单方法,没用异步回调地址

SortedMap<String,String> parameters = new TreeMap<>();
        parameters.put("appid", appid);
        parameters.put("mch_id", mchId);
        parameters.put("out_trade_no", orderSn);// 系统内部订单号
        parameters.put("nonce_str", ToolUtil.getRandomString(32));
        String sign = WeixinPayUtil.createSign(parameters,key);
        parameters.put("sign",sign);
        String xml = WeixinPayUtil.getRequestXml(parameters);
        Result result = WeixinPayUtil.sendRequest(xml, WeixinPayUtil.ORDER_QUERY_URL, HttpMethod.POST);
        Map<String, String> map  = (Map<String, String>) result.getData();
        if ( map.get("result_code").equals("SUCCESS")){
            //回调成功后的业务逻辑
        }

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值