微信小程序支付-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
    评论
要在Java中调用微信支付,需要使用微信开放平台提供的统一下单API。下面是一个简单的示例代码,展示了如何使用Java调用微信支付API: ```java public class WechatPayUtil { private static final String URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; // 统一下单API地址 public static String createOrder(String appid, String mch_id, String out_trade_no, String body, int total_fee, String notify_url, String trade_type, String spbill_create_ip, String key) throws Exception { // 构造请求参数 SortedMap<String, String> paramMap = new TreeMap<String, String>(); paramMap.put("appid", appid); paramMap.put("mch_id", mch_id); paramMap.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", "")); paramMap.put("body", body); paramMap.put("out_trade_no", out_trade_no); paramMap.put("total_fee", String.valueOf(total_fee)); paramMap.put("spbill_create_ip", spbill_create_ip); paramMap.put("notify_url", notify_url); paramMap.put("trade_type", trade_type); // 生成签名 String sign = createSign(paramMap, key); paramMap.put("sign", sign); // 将请求参数转换为XML格式 String xml = mapToXml(paramMap); // 发起HTTP请求 HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(URL); httpPost.setEntity(new StringEntity(xml, "UTF-8")); HttpResponse httpResponse = httpClient.execute(httpPost); HttpEntity httpEntity = httpResponse.getEntity(); // 处理响应结果 String responseXml = EntityUtils.toString(httpEntity, "UTF-8"); SortedMap<String, String> responseMap = xmlToMap(responseXml); String prepayId = responseMap.get("prepay_id"); return prepayId; } private static String createSign(SortedMap<String, String> paramMap, String key) { StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> entry : paramMap.entrySet()) { if (entry.getValue() != null && !"".equals(entry.getValue()) && !"sign".equals(entry.getKey())) { sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&"); } } sb.append("key=").append(key); String str = sb.toString(); String sign = MD5Util.MD5Encode(str, "UTF-8").toUpperCase(); return sign; } private static String mapToXml(SortedMap<String, String> map) throws Exception { Document document = DocumentHelper.createDocument(); Element root = document.addElement("xml"); for (Map.Entry<String, String> entry : map.entrySet()) { if (entry.getValue() != null) { Element element = root.addElement(entry.getKey()); element.setText(entry.getValue()); } } return document.asXML(); } private static SortedMap<String, String> xmlToMap(String xml) throws Exception { SortedMap<String, String> map = new TreeMap<String, String>(); Document document = DocumentHelper.parseText(xml); Element root = document.getRootElement(); List<Element> elements = root.elements(); for (Element element : elements) { map.put(element.getName(), element.getText()); } return map; } } ``` 其中,createOrder方法用于调用统一下单API,传入的参数包括: - appid:公众账号ID或应用ID - mch_id:商户号 - out_trade_no:商户订单号 - body:商品描述 - total_fee:总金额,单位为分 - notify_url:接收微信支付异步通知回调地址 - trade_type:交易类型,JSAPI代表公众号支付 - spbill_create_ip:终端IP - key:商户密钥,用于生成签名 调用成功后,会返回预支付ID(prepay_id),用于生成支付请求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值