微信小程序支付后台 java

最近做了一下微信小程序发起的支付,所以记录一下,也希望能帮助同行们跳出微信支付这个大坑。

首先说一下微信支付我所理解的流程吧,首先会想后端发起统一下单的请求,后台进行统一下单,加密之类的,然后将数据返回给前端,然后前端拿着数据发起支付,支付成功开始回调。

这里发一下微信统一下单的api 可以对照着看一下 这样会更容易理解

https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1&index=1

 

这篇文章主要说一下支付的统一下单和加密,至于回调(https://blog.csdn.net/qq_39897814/article/details/88890814)则会咋下一篇文章中解释。

先上代码

/**
*orderNo订单号
*openId 用户标识
*/
 public Map<String, String> pay(String orderNo, String openId) {
        OmsOrderParent orderParent = orderParentService.findByOrderNo(orderNo);
//小程序的
        //1 封装参数  这里的参数时统一下单所需要的参数
        Map<String, String> param = new HashMap<>();
        param.put("appid", );//应用ID  注意 这里的appid是小写
        param.put("mch_id", );//商户号
        param.put("nonce_str", );//随机字符串
        param.put("body",);//商品描述
        param.put("out_trade_no", orderNo);//商户订单号 NoUtils.getNo()
        param.put("total_fee", );//订单总金额(分)  这里要注意 支付的金额的单位是分,意思就是如果你支付的金额是1元的话 这里就是100不能有小数
        param.put("spbill_create_ip", );//终端ip
        param.put("notify_url",);//通知地址( 接收微信支付异步通知回调地址) 就是你后台回调的访问路径全路径 包括域名
        param.put("trade_type", "JSAPI");//交易类型
        param.put("openid", openId);//用户标识
          try {
              //这里对上面的数据进行第一次签名  WXPayUtil.generateSignature()方法是微信官方的 这里的KEY是你的api秘钥
              String sign1 =WXPayUtil.generateSignature(param, KEY); 
              log.info("第一次签名:****************"+sign1+"*****************");
              param.put("sign", sign1);//第一次加密的数据得到的签名
          }catch (Exception e){

      }
        String xmlParam;//生成带有sign的XML格式字符串  WXPayUtil.generateSignedXml也是微信官方的
        try {
            xmlParam = WXPayUtil.generateSignedXml(param, WXMiniPayConfig.KEY);
        } catch (Exception e) {
            log.info("第-------个" + e.getMessage());
            throw new IllegalArgumentException("生成签名失败");
        }
        //2 发送请求 统一下单 进行统一下单
        HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
        httpClient.setHttps(true);
        httpClient.setXmlParam(xmlParam);
        httpClient.post();

        //3 获取结果
        String xmlResult = httpClient.getContent();
        Map<String, String> mapResult;
        try {
            mapResult = WXPayUtil.xmlToMap(xmlResult);
        } catch (Exception e) {
            log.info("第一个" + e.getMessage());
            throw new IllegalArgumentException("生成支付信息失败");
        }
        log.info("MINI-----调用微信统一下单接口返回的结果为===================================" + mapResult);
        if(mapResult.get("prepay_id")==null){
          log.error("不能加密,prepay_id为空");
        }
        //4 返回数据至APP端 二次加密获取签名  注意这个map中的参数不能多也不能少,不然无法调起支付,而且一下参数的大小写一定要注意
        Map<String, String> map = new HashMap<>();
        map.put("appId", mapResult.get("appid"));//应用ID  注意 这里的appId是大写 千万注意
        map.put("nonceStr", ); //随机字符串,长度要求在32位以内
        //这里的package 对应的预支付交易会话标识的格式必须是prepay_id=****不然前端无法调起支付
        map.put("package", "prepay_id=" + mapResult.get("prepay_id")); //预支付交易会话标识prepayid
        map.put("signType", "MD5");  //加密方式
        map.put("timeStamp", );  //时间戳(10位数字,精确至秒)

        try {
            //二次加密 将次加密返回给前台 这里的KEY是你的api秘钥
            String sign2 = WXPayUtil.generateSignature(map, KEY);
            map.put("paySign", sign2);
        } catch (Exception e) {
            log.info("二次加密失败::::::" + e.getMessage());
            throw new IllegalArgumentException("生成签名失败");
        }
        log.info("返回APP端的数据为=================================================" + map);
        return map;
    }




   

到这里统一下单 已经完成,如果没有意外的话 是可以调起支付的

下面贴上工具类



import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * http请求客户端
 *
 * @author Administrator
 */
public class HttpClient {
    private String url;
    private Map<String, String> param;
    private int statusCode;
    private String content;
    private String xmlParam;
    private boolean isHttps;

    public boolean isHttps() {
        return isHttps;
    }

    public void setHttps(boolean isHttps) {
        this.isHttps = isHttps;
    }

    public String getXmlParam() {
        return xmlParam;
    }

    public void setXmlParam(String xmlParam) {
        this.xmlParam = xmlParam;
    }

    public HttpClient(String url, Map<String, String> param) {
        this.url = url;
        this.param = param;
    }

    public HttpClient(String url) {
        this.url = url;
    }

    public void setParameter(Map<String, String> map) {
        param = map;
    }

    public void addParameter(String key, String value) {
        if (param == null)
            param = new HashMap<String, String>();
        param.put(key, value);
    }

    public void post() {
        HttpPost http = new HttpPost(url);
        setEntity(http);
        try {
            execute(http);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void put() throws ClientProtocolException, IOException {
        HttpPut http = new HttpPut(url);
        setEntity(http);
        execute(http);
    }

    public void get() throws ClientProtocolException, IOException {
        if (param != null) {
            StringBuilder url = new StringBuilder(this.url);
            boolean isFirst = true;
            for (String key : param.keySet()) {
                if (isFirst)
                    url.append("?");
                else
                    url.append("&");
                url.append(key).append("=").append(param.get(key));
            }
            this.url = url.toString();
        }
        HttpGet http = new HttpGet(url);
        execute(http);
    }

    /**
     * set http post,put param
     */
    private void setEntity(HttpEntityEnclosingRequestBase http) {
        if (param != null) {
            List<NameValuePair> nvps = new LinkedList<NameValuePair>();
            for (String key : param.keySet())
                nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
            http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
        }
        if (xmlParam != null) {
            http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
        }
    }

    private void execute(HttpUriRequest http) throws ClientProtocolException,
            IOException {
        CloseableHttpClient httpClient = null;
        try {
            if (isHttps) {
                SSLContext sslContext = new SSLContextBuilder()
                        .loadTrustMaterial(null, new TrustStrategy() {
                            // 信任所有
                            public boolean isTrusted(X509Certificate[] chain,
                                                     String authType)
                                    throws CertificateException {
                                return true;
                            }
                        }).build();
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sslContext);
                httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
                        .build();
            } else {
                httpClient = HttpClients.createDefault();
            }
            CloseableHttpResponse response = httpClient.execute(http);
            try {
                if (response != null) {
                    if (response.getStatusLine() != null)
                        statusCode = response.getStatusLine().getStatusCode();
                    HttpEntity entity = response.getEntity();
                    // 响应内容
                    content = EntityUtils.toString(entity, Consts.UTF_8);
                }
            } finally {
                response.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpClient.close();
        }
    }

    public int getStatusCode() {
        return statusCode;
    }

    public String getContent() {
        return content;
    }

}

微信支付统一下单就这么多,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值