java实现微信支付
java实现微信支付
package com.hk.wx.pay.service.impl; @Service public class PayServiceImpl implements PayService { private static final Logger LOG = LoggerFactory.getLogger(PayServiceImpl.class); private static final String PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; @Value("${appid}") private String APPID = ""; @Value("${pay.mch_id}") private String PAY_MACH_ID = ""; @Value("${pay.body}") private String PAY_BODY = ""; @Value("${pay.notify_url}") private String PAY_NOTIFY_URL = ""; @Value("${pay.trade_type}") private String PAY_TYPR = ""; @Value("${pay.key}") private String PAY_KEY = ""; public JSONObject wxPay(String total_fee, String imei, String ip, String openid) { Map pay = new LinkedHashMap(); // 按照 添加顺序 排序 pay.put("appid", this.APPID); //小程序 aapid pay.put("attach", getOrderNum()); //附加数据 pay.put("body", this.PAY_BODY); //商品描述 pay.put("device_info", imei); // pay.put("mch_id", this.PAY_MACH_ID); //商品号 pay.put("nonce_str", getNonceStr()); //随机字符串 pay.put("notify_url", this.PAY_NOTIFY_URL); //返回连接 pay.put("openid", openid); //微信用户 id pay.put("out_trade_no", getOrderNum()); //订单号 pay.put("sign_type", "MD5"); pay.put("spbill_create_ip", ip); pay.put("total_fee", total_fee); pay.put("trade_type", this.PAY_TYPR); pay.put("sign", getSign(pay)); String xml = XmlUtil.mapToXMLString(pay); // 转成 xml 形式 System.out.println(xml); String msg = ""; try { msg = HttpUtils.xmlRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", xml); // xml 形式 post请求 JSONObject json = XmlUtil.xmlToJSONObject(msg); String ret = json.getString("return_code"); if ((ret != "") && (ret.equals("SUCCESS")) && (!"SUCCESS".equals(json.getString("result_code")))) { return json; } LOG.info("# 统一下单错误...msg:" + json.toString()); return null; } catch (Exception e) { LOG.error("# 支付出错..."); e.printStackTrace(); }return null; }
//获取随机数 private static String getNonceStr() { return Md5Utils.encryption(ComApi.getUUID()); }
//获取 sign private static String getSign(Map<Object, Object> parameters) { String characterEncoding = "UTF-8"; StringBuffer sb = new StringBuffer(); List list = new ArrayList(parameters.entrySet()); Collections.sort(list, new Comparator() { public int compare(Map.Entry<Object, Object> mapping1, Map.Entry<Object, Object> mapping2) { return ((String)mapping1.getKey()).compareTo((String)mapping2.getKey()); } }); for (Map.Entry mapping : list) { String k = (String)mapping.getKey(); Object v = mapping.getValue(); if ((v != null) && (!"".equals(v)) && (!"sign".equals(k)) && (!"key".equals(k))) { sb.append(k + "=" + v + "&"); } } sb.append("key=key"); //key 是支付帐号里面的api安全密码 LOG.info("# sign 拼接:" + sb.toString()); String sign = Md5Utils.encryption(sb.toString(), characterEncoding).toUpperCase(); LOG.info("# 获取 签名...sign:" + sign); return sign; }
//获取订货号 private static String getOrderNum() { String time = TimeUtils.getSysDate("yyyyMMddHHmmssSSS"); String uuNum = ComApi.getUUNum(); String num = "HK" + time + uuNum; return num; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构