微信小程序实现拉起微信支付功能-最简单版

小程序 0

里面有很多逻辑需要大家自己写啊,比如订单获取啊,生成订单啊,变更订单状态,退款啊,等等的,我这里就实现了一个基本的功能,就是拉起支付,支付到账这样的,大家根据需求自己编写就行。我这里提供的基本上都是复制了直接就能用的那种啊,前提是你要有商户号,要生成秘钥证书这些啊

首先需要去注册商户号啊,这个过程比较复杂啊,然后微信平台上有引导的,大家跟着做就行

就是这个位置啊,然后需要提交的材料准备好就行,基本上当天就会批下来,费率的话每个行业都是不一样的啊,然后在小程序里关联到商户号就行,

代码编写 只附部分核心程序,他是需要拿着openid去后台获取相应的参数的啊,这里的orderId我直接前端随机了,正常应该写在后端的啊,大家额注意一下。有些参数没明白的,可以去微信平台的文档里看一下啊,都是一一对应的啊,然后我这个也不需要下载什么jdk,maven的话也是springboot那一套啊,没什么特殊的

data: {    phoneNumber: '', // 存储手机号    openid: '', // 用户的 openid    orderId: '', // 订单 ID    paymentData: null, // 存储从后端获取的支付参数    statu:'点击支付',    isButtonDisabled: false // 默认按钮是可点击的  },  generateOrderId: function() {    // 获取当前时间戳    const timestamp = new Date().getTime();    // 生成一个随机数    const randomNum = Math.floor(Math.random() * 100000);    // 拼接时间戳和随机数生成订单号    return timestamp.toString() + randomNum.toString();  },  /**   * 生命周期函数--监听页面加载   */  onLoad(options) {    const orderId = this.generateOrderId();    const openId = wx.getStorageSync('openId')    this.setData({      openid: openId,      orderId: orderId         });  }, // 发起支付函数 startPayment: function () {  const that = this;  // 先从后端获取支付参数  wx.request({    url: url+'api/getPaymentParams',    method: 'POST',    data: {      openid: this.data.openid,      orderId: this.data.orderId    },    success: function (res) {      if (res.data && res.data.success) {        const paymentData = res.data.paymentData;        console.log(res.data.paySign)        // 调用微信支付接口        wx.requestPayment({          timeStamp: paymentData.timeStamp,          nonceStr: paymentData.nonceStr,          package: paymentData.package,          signType: paymentData.signType,          paySign: res.data.paySign,          success: (res) => { // 使用箭头函数           that.setData({              statu: '已支付',              isButtonDisabled: true // 将按钮设置为不可点击            });            console.log('支付成功', res);            wx.request({              url: url + 'api/setOrder?orderId=' + that.data.orderId, //仅为示例,并非真实的接口地址              method: 'GET',              header: { 'content-type': 'application/json' },              success: (res) => {                // 处理成功请求的回调              }            });                    // 支付成功后的操作,如跳转页面或其他逻辑          },          fail: (res) => { // 使用箭头函数            console.log('支付失败', res);            // 支付失败后的操作,如提示用户重新支付          }        });      } else {        wx.showToast({          title: '此订单已支付',          icon: 'none'        });        console.error('获取支付参数失败', res);      }    },    fail: function (err) {      wx.showToast({        title: '此订单已支付',         icon: 'none'      });      console.error('请求支付参数失败', err);    }  });},
Java:服务器端private static final String APPID = "";private static final String APPSECRET = "";private  static  final String MCHID="";//商户号private  static  final String NOTIFYURL="";//回执地址private  static  final String  MCHKEY="";//秘钥@PostMapping("/getPaymentParams")public @ResponseBody Map<String, Object> getPaymentParams(@RequestBody Map<String, String> request) {    String openid = request.get("openid");    String orderId = request.get("orderId");    String money="1";//目前模拟数据,后续需要通过支付金额表或者是通过第三方获取支付金额,通过OPENID去user表找到手机号,然后通过手机号查询金额表    // 创建统一下单请求参数    Map<String, String> params = new HashMap<>();    params.put("appid", APPID);    params.put("mch_id",MCHID );    params.put("nonce_str", WXPayUtil.generateNonceStr());    params.put("body", "订单支付");    params.put("out_trade_no", orderId);    params.put("total_fee", money); // 单位为分    params.put("spbill_create_ip", "127.0.0.1");    params.put("notify_url", NOTIFYURL);    params.put("trade_type", "JSAPI");    params.put("openid", openid);    try {        String sign = WXPayUtil.generateSignature(params, MCHKEY);        params.put("sign", sign);        String xml = WXPayUtil.mapToXml(params);        String response = HttpUtil.post("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);        Map<String, String> result = WXPayUtil.xmlToMap(response);        if ("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("result_code"))) {            String prepayId = result.get("prepay_id");            Map<String, String> payMap = new HashMap<>();            payMap.put("appId", APPID);            payMap.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));            payMap.put("nonceStr", WXPayUtil.generateNonceStr());            payMap.put("package", "prepay_id=" + prepayId);            payMap.put("signType", "MD5");            String paySign = WXPayUtil.generateSignature(payMap, MCHKEY);            Map<String, Object> responseMap = new HashMap<>();            responseMap.put("success", true);            responseMap.put("paymentData", payMap);            responseMap.put("paySign", paySign);            Order order=new Order();            order.setOrderId(orderId);            order.setOpenId(openid);            order.setPayTime(new Date());            order.setMoney(money);            orderService.add(order);            return responseMap;        } else {            Map<String, Object> responseMap = new HashMap<>();            responseMap.put("success", false);            responseMap.put("errMsg", result.get("err_code_des"));            return responseMap;        }    } catch (Exception e) {        e.printStackTrace();        Map<String, Object> responseMap = new HashMap<>();        responseMap.put("success", false);        responseMap.put("errMsg", e.getMessage());        return responseMap;    }}

util类,用来生成随机字符串,加密,验证签名等作用的

public class WXPayUtil {

    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }

    public static String generateSignature(Map<String, String> data, String key) throws Exception {
        // 1. Sort the parameters in dictionary order
        Map<String, String> sortedData = new TreeMap<>(data);

        // 2. Concatenate the parameters as per the format: key1=value1&key2=value2...
        String stringA = sortedData.entrySet().stream()
                .map(entry -> entry.getKey() + "=" + entry.getValue())
                .collect(Collectors.joining("&"));

        // 3. Append the key
        String stringSignTemp = stringA + "&key=" + key;

        // 4. Sign the concatenated string using MD5
        return MD5(stringSignTemp).toUpperCase();
    }

    public static String mapToXml(Map<String, String> data) {
        StringBuilder xml = new StringBuilder();
        xml.append("<xml>");
        for (Map.Entry<String, String> entry : data.entrySet()) {
            xml.append("<").append(entry.getKey()).append(">");
            xml.append(entry.getValue());
            xml.append("</").append(entry.getKey()).append(">");
        }
        xml.append("</xml>");
        return xml.toString();
    }

    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(new StringReader(strXML));
        Element root = doc.getRootElement();
        List<Element> children = root.getChildren();
        Map<String, String> data = new HashMap<>();
        for (Element child : children) {
            data.put(child.getName(), child.getTextNormalize());
        }
        return data;

    }

    private static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte b : array) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    /**
     * 验证签名
     * @param data 通知数据
     * @param key 密钥
     * @return 签名是否有效
     * @throws Exception
     */
    public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception {
        if (!data.containsKey("sign")) {
            return false;
        }
        String sign = data.get("sign");
        return generateSignature(data, key).equals(sign);
    }
}
 

也许您对下面的内容还感兴趣: