Java实现微信小程序唤起支付(JSAPI方式)

都是一些官方的东西,直接上代码,中文部分改成自己的

 public Object WxPay() {
        Map<String, Object> response = new HashMap<>();//返回给小程序端需要的参数
        try {
            //生成的随机字符串
            String nonce_str = WxPayUtil.getRandomStringByLength(32);
            String body = "支付的标题自己定义";
            //获取客户端的ip地址
            String spbill_create_ip = WxPayUtil.localIp();
            //组装参数,用户生成统一下单接口的签名
            Map<String, String> packageParams = new HashMap<>();
            packageParams.put("trade_type", "JSAPI");//支付方式

            packageParams.put("appid", "申请的appid");
            packageParams.put("mch_id", "申请的商户号");
            packageParams.put("nonce_str", nonce_str);
            packageParams.put("body", body);
            packageParams.put("out_trade_no", "自己生成一个订单号");//商户订单号,自己的订单ID
            packageParams.put("total_fee", WxPayUtil.getMoney(1 + ""));//支付金额,这边需要转成字符串类型,否则后面的签名会失败,单位是分
            packageParams.put("spbill_create_ip", spbill_create_ip);//ip地址
            packageParams.put("notify_url", "回调地址" + "/" + "订单号");//支付成功后的回调地址,地址后面加上订单号容易处理回调业务
            packageParams.put("time_expire", WxPayUtil.getEndTime(new Date()));  //超时时间60s yyyyMMddHHmmss

            packageParams.put("openid", "申请的openid");//用户的openID,自己获取

            String prestr = WxPayUtil.createLinkString(packageParams); // 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串

            //MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
            String mysign = WxPayUtil.sign(prestr, "自己的密钥", "utf-8").toUpperCase();
            packageParams.put("sign", mysign);
            //拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去
            String xml = XmlUtil.mapToXmlStr(packageParams, "xml");

            //调用统一下单接口,并接受返回的结果
            String result = WxPayUtil.httpRequest("微信的支付链接", "POST", xml); //https://api.mch.weixin.qq.com/pay/unifiedorder

            // 将解析结果存储在HashMap中
            Map map = WxPayUtil.doXMLParse(result);

            String return_code = (String) map.get("return_code");//返回状态码
            String result_code = (String) map.get("result_code");//返回状态码
            if (return_code.equals("SUCCESS") && return_code.equals(result_code)) {
                String prepay_id = (String) map.get("prepay_id");//返回的预付单信息


                response.put("nonceStr", nonce_str);
                response.put("package", "prepay_id=" + prepay_id);
                Long timeStamp = System.currentTimeMillis() / 1000;
                response.put("timeStamp", timeStamp + "");//这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
                //拼接签名需要的参数
                String stringSignTemp = "appId=" + "申请的appid" + "&nonceStr=" + nonce_str + "&package=prepay_id=" + prepay_id + "&signType=MD5&timeStamp=" + timeStamp;
                //再次签名,这个签名用于小程序端调用wx.requesetPayment方法
                String paySign = WxPayUtil.sign(stringSignTemp, "自己的密钥", "utf-8").toUpperCase();

                response.put("paySign", paySign);
                response.put("appid", "申请的appid");
                response.put("openid", "申请的openid");
                response.put("orderNo", "订单号");

                return response; //返给前端唤起支付
            } else {
                return map.get("return_msg");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "系统异常";
        }
    }

 wxpayutils:

import cn.hutool.core.util.XmlUtil;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;

public class WxPayUtil {


    /**
     * 获取本机IP地址
     *
     * @return String
     */
    public static String localIp() {
        String ip = null;
        Enumeration allNetInterfaces;
        try {
            allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                List<InterfaceAddress> InterfaceAddress = netInterface.getInterfaceAddresses();
                for (InterfaceAddress add : InterfaceAddress) {
                    InetAddress Ip = add.getAddress();
                    if (Ip != null && Ip instanceof Inet4Address) {
                        ip = Ip.getHostAddress();
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return ip;
    }

    /**
     * 元转换成分
     *
     * @param amount
     * @return
     */
    public static String getMoney(String amount) {
        if (amount == null) {
            return "";
        }
        // 金额转化为分为单位
        // 处理包含, ¥ 或者$的金额
        String currency = amount.replaceAll("\\$|\\¥|\\,", "");
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }

    /**
     * 签名字符串
     *
     * @param text          需要签名的字符串
     * @param key           密钥
     * @param input_charset 编码格式
     * @return 签名结果
     */
    public static String sign(String text, String key, String input_charset) {
        text = text + "&key=" + key;
        return DigestUtils.md5Hex(getContentBytes(text, input_charset));
    }


    /**
     * @param content
     * @param charset
     * @return
     * @throws java.security.SignatureException
     * @throws UnsupportedEncodingException
     */
    public static byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }
    

    /**
     * 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串
     *
     * @param params 需要排序并参与字符拼接的参数组
     * @return 拼接后字符串
     */
    public static String createLinkString(Map<String, String> params) {
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            if (i == keys.size() - 1) {// 拼接时,不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }
        return prestr;
    }

    //获取随机字符串
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * @param requestUrl    请求地址
     * @param requestMethod 请求方法
     * @param outputStr     参数
     */
    public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
        // 创建SSLContext
        StringBuffer buffer = null;
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(requestMethod);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.connect();
            //往服务器端写内容
            if (null != outputStr) {
                OutputStream os = conn.getOutputStream();
                os.write(outputStr.getBytes("utf-8"));
                os.close();
            }
            // 读取服务器端返回的内容
            InputStream is = conn.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            BufferedReader br = new BufferedReader(isr);
            buffer = new StringBuffer();
            String line = null;
            while ((line = br.readLine()) != null) {
                buffer.append(line);
            }
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }


    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     *
     * @param strxml
     * @return
     * @throws IOException
     */
    public static Map doXMLParse(String strxml) throws Exception {
        if (null == strxml || "".equals(strxml)) {
            return null;
        }

        // 解析xml成map
        Map<String, Object> m = XmlUtil.xmlToMap(strxml.toString());
        // 过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<>();
        Iterator<String> it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = it.next();
            Object parameterValue = m.get(parameter);
            String v = "";
            if (null != parameterValue) {
                v = parameterValue.toString().trim();
            }
            packageParams.put(parameter, v);
        }

        return m;
    }


    public static String getEndTime(Date now) {
        Long timeExpireNew = now.getTime() + 1 * 60 * 1000l;
        Date dtTimeExpire = new Date(timeExpireNew);
        SimpleDateFormat dtSdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String timeExpire = dtSdf.format(dtTimeExpire);
        return timeExpire;


    }
}

支付的回调需要看我另一篇文章

Java实现微信扫码支付(NATIVE方式)icon-default.png?t=LA92https://blog.csdn.net/weixin_52540274/article/details/120324029?spm=1001.2014.3001.5501

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值