JAVA小程序微信支付

微信支付有专门的文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1
当时找的时候都是前台如何,后来才发现后台需要做的就是统一下单
一、
先到微信下载两个证书,然后把证书放到resources下,cart是我自己建的
在这里插入图片描述
二、因为需要调用微信接口所以我们需要一个调用接口的工具类,下面是我的工具类
1.工具类需要的pom文件

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.48</version>
		</dependency>

		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.2</version>
		</dependency>

2.工具类

package com.weizhang.until;

import net.sf.json.JSONObject;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Set;


/**
 *HttpClient为网络请求的工具类,网络请求的超时时间为5秒。超时、连接出现错误等,响应码非200均返回null。
 *
 * <b>传入的Map参数会自动转换成json格式的数据发送<b/>
 *
 */
public class HttpClient {
    private HttpClient(){}
    public static final String METHOD_POST = "POST";
    public static final String METHOD_GET = "GET";
    private static final int TIME_OUT = 5000;


    /**
     * POST请求url,返回String 类型的结果,5秒超时,出现异常返回null
     * @param url 请求路径
     * @param map 请求参数封装到map中
     * @return
     */
    public static String forStringResult(String url,Map<String,Object> map){
        return forStringResult(url,map,METHOD_POST);
    }

    /**
     * 获取网络请求,5秒超时,出现异常返回null
     * @param urlStr 请求地址
     * @param map 参数封装到map
     * @param method 请求方式GET或POST
     * @return
     */
    public static String forStringResult(String urlStr,Map<String,Object> map,String method){
        String param = null;
        if(map!=null){
            JSONObject obj = new JSONObject();
            Set<Map.Entry<String, Object>> set = map.entrySet();
            for(Map.Entry<String,Object> entry :set){
                obj.put(entry.getKey(),entry.getValue());
            }
            param = obj.toString();
        }

        return getResult(urlStr,param,method);
    }

    /**
     * 返回JSON格式的结果,5秒超时,出现异常返回null
     * @param url 请求url
     * @param map 将参数封装到map中
     * @return
     */
    public static JSONObject forJsonResult(String url, Map<String,Object> map){
        return forJsonResult(url,map,METHOD_POST);
    }


    /**
     * 返回json格式的结果,5秒超时,出现异常返回null
     * @param urlStr 请求url
     * @param map 参数封装到map中
     * @param method 请求方式GET或POST
     * @return
     */
    public static JSONObject forJsonResult(String urlStr,Map<String,Object> map,String method){
        String result = forStringResult(urlStr,map,method);
        if(result==null){
            return null;
        }
        JSONObject jsonObject = JSONObject.fromObject(result);
        return jsonObject;
    }

    /**
     *获取网路请求,5秒超时,出现异常返回null
     * @param url 请求地址
     * @param param  请求参数
     * @return
     */
    public static String forStringResult(String url,String param){
        return  getResult(url,param,null);
    }

    /**
     * 获取网络请求结果,5秒超时,出现异常返回null
     * @param urlStr
     * @param param
     * @param method
     * @return
     */
    private static String getResult(String urlStr,String param,String method){
        String result = null;
        HttpURLConnection connection = null;
        try {
            if(method==null){
                method = METHOD_POST;
            }
            // 创建连接
            URL url = new URL(urlStr);
            connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(TIME_OUT);//5秒超时
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod(method);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "multipart/form-data");
            connection.connect();
            if(param!=null){
                // POST请求
                DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                out.writeBytes(param);
                out.flush();
                out.close();
            }
            int responseCode = connection.getResponseCode();
            if(responseCode==200){
                result = inputStreamToString(connection.getInputStream());
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
        	// 断开连接
            connection.disconnect();
        }
        return result;
    }
    /**
     * 输入流转为String
     * @param is
     * @return
     */
    private static String inputStreamToString(InputStream is){

        // 读取响应
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String lines = "";
        StringBuffer sb = new StringBuffer();
        try {
            while ((lines = reader.readLine()) != null) {
                lines = new String(lines.getBytes(), "utf-8");
                sb.append(lines);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  sb.toString();
    }
}

三、因为微信有签名所以需要加密工具,我这里使用的事md5加密
1.pom文件

	<!--MD5-->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.3.2</version>
		</dependency>

2.md5工具类

package com.weizhang.until;


import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by admin on 2019/7/31.
 */
public class DM5 {
    //写一个md5加密的方法
    public static String md5(String plainText) {
        //定义一个字节数组
        byte[] secretBytes = null;
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            //对字符串进行加密
            md.update(plainText.getBytes());
            //获得加密后的数据
            secretBytes = md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("没有md5这个算法!");
        }
        //将加密后的数据转换为16进制数字
        String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
        // 如果生成数字未满32位,需要前面补0
        for (int i = 0; i < 32 - md5code.length(); i++) {
            md5code = "0" + md5code;
        }
        return md5code;
    }
}

四、下面开始正文,上代码
1.因为微信里有很多参数是固定值,所以创建一个实体类放这些值

package com.weizhang.wxpay;

/**
 * Created by admin on 2019/11/11.
 */
public class Aaa {
    public static String appid="小程序appid";
    public static String mch_id="商户号";
    public static String pay_key="商户号key";
    public static String body="描述";
    public static String out_trade_no="订单号";
    public static Integer total_fee=金额;
    public static String notify_url="回调地址,必须是外网能访问到的地址,微信需要根据这个地址调用我们的接口";
    public static String trade_type="JSAPI";//请求类型  JSAPI是小程序 其他去微信文档里找
}

2.准备工作都做好了就可以直接调用了

package com.weizhang.wxpay;

import com.weizhang.until.DM5;
import com.weizhang.until.HttpClient;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * Created by admin on 2019/11/11.
 */
public class WeiXinPay {
    private String url="https://api.mch.weixin.qq.com/pay/unifiedorder";//统一下单接口
    public void WeiXinPayA(String IP,String openid){
        Map<String,String> map = new HashMap<>();//我将所有参数放到map中了
        map.put("appid",Aaa.appid);
        map.put("mch_id",Aaa.mch_id);
        try {
            map.put("body",new String(Aaa.body.getBytes("UTF-8")));//这里需要注意,body需要提前进行utf-8转换,否则微信会报错
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        map.put("out_trade_no",Aaa.out_trade_no);
        map.put("total_fee",String.valueOf(Aaa.total_fee*100));
        map.put("notify_url",Aaa.notify_url);
        map.put("trade_type",Aaa.trade_type);
        map.put("spbill_create_ip",IP);
        map.put("openid",openid);//小程序必须穿openid
        String nonce_str =  UUID.randomUUID().toString().substring(0,32);//生成的32位随机数
        map.put("nonce_str",nonce_str);
        /*这里需要将上面我们所有的参数按照字典顺序排序,必须严格按照微信文档里签名规则来*/
        String signA="appid="+map.get("appid")+"&body="+map.get("body")+"&mch_id="+map.get("mch_id")+"&nonce_str="+
                map.get("nonce_str")+"&notify_url="+map.get("notify_url")+"&openid="+map.get("openid")+"&out_trade_no="+map.get("out_trade_no")+
                "&spbill_create_ip="+map.get("spbill_create_ip")+"&total_fee="+map.get("total_fee")+"&trade_type="+
                map.get("trade_type");
        String signB=signA+"&key="+Aaa.pay_key;//前面拼接完,最后拼接商户号的key
        String sign= DM5.md5(signB).toUpperCase();//将所有拼接的字符串进行md5加密,加密完转成大写
        map.put("sign",sign);
        /*微信传参需要穿xml格式,所以要将所有参数拼接成xml格式*/
        StringBuilder xml = new StringBuilder();
        xml.append("<xml>\n");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if ("body".equals(entry.getKey()) || "sign".equals(entry.getKey())) {
                xml.append("<" + entry.getKey() + "><![CDATA[").append(entry.getValue()).append("]]></" + entry.getKey() + ">\n");
            } else {
                xml.append("<" + entry.getKey() + ">").append(entry.getValue()).append("</" + entry.getKey() + ">\n");
            }
        }
        xml.append("</xml>");
		
        String cc = HttpClient.forStringResult(url,xml.toString());//调用微信统一下单接口
        System.out.println(cc);
    }
}

这样主要的工作就完成了,微信回调我们接口传的也是xml格式参数,只需要接收进行一下验证是否成功就行了,然后将前台需要的参数传给前台就OK了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值