里面有很多逻辑需要大家自己写啊,比如订单获取啊,生成订单啊,变更订单状态,退款啊,等等的,我这里就实现了一个基本的功能,就是拉起支付,支付到账这样的,大家根据需求自己编写就行。我这里提供的基本上都是复制了直接就能用的那种啊,前提是你要有商户号,要生成秘钥证书这些啊
首先需要去注册商户号啊,这个过程比较复杂啊,然后微信平台上有引导的,大家跟着做就行
就是这个位置啊,然后需要提交的材料准备好就行,基本上当天就会批下来,费率的话每个行业都是不一样的啊,然后在小程序里关联到商户号就行,
代码编写 只附部分核心程序,他是需要拿着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);
}
}