// MCH_ID = '';//商户ID // KEY = '';//商户key public JSONObject createUnifiedOrder(String orderCode,String openid,String amount) throws Exception { //设置最终返回对象 JSONObject resultJson = new JSONObject(); //接口调用总金额单位为分换算一下(测试金额改成1,单位为分则是0.01,根据自己业务场景判断是转换成float类型还是int类型) BigDecimal amountFen = new BigDecimal(amount); BigDecimal fen = new BigDecimal(100); BigDecimal amountFen100 = amountFen.multiply(fen); BigDecimal setScale = amountFen100.setScale(0,BigDecimal.ROUND_HALF_DOWN); //创建hashmap(用户获得签名) SortedMap<String, String> paraMap = new TreeMap<String, String>(); //设置body变量 (支付成功显示在微信支付 商品详情中) String body = "订单编号["+orderCode+"],金额为["+amount+"]"; //设置随机字符串 String nonceStr = UUID.randomUUID().toString().replaceAll("-", ""); //设置请求参数(小程序ID) paraMap.put("appid", ""); //设置请求参数(商户号) paraMap.put("mch_id", ""); //设置请求参数(随机字符串) paraMap.put("nonce_str", nonceStr); //设置请求参数(商品描述) paraMap.put("body", body); //设置请求参数(商户订单号) paraMap.put("out_trade_no", orderCode); //设置请求参数(总金额) paraMap.put("total_fee", setScale.toString()); //设置请求参数(终端IP) paraMap.put("spbill_create_ip", getIpAddress()); //设置请求参数(通知地址) paraMap.put("notify_url", getIpAddress()+":8080/pay/payCallback"); //设置请求参数(交易类型) paraMap.put("trade_type", "JSAPI"); //设置请求参数(openid)(在接口文档中 该参数 是否必填项 但是一定要注意 如果交易类型设置成'JSAPI'则必须传入openid) paraMap.put("openid", openid); //调用逻辑传入参数按照字段名的 ASCII 码从小到大排序(字典序) String stringA = formatUrlMap(paraMap, false, false); //第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。(签名) String sign = getMD5String(stringA+"&key="+KEY).toUpperCase(); //将参数 编写XML格式 StringBuffer paramBuffer = new StringBuffer(); paramBuffer.append("<xml>"); paramBuffer.append("<appid>"+BaseAppInfoMap.getInstance().findAppid()+"</appid>"); paramBuffer.append("<mch_id>"+MCH_ID+"</mch_id>"); paramBuffer.append("<nonce_str>"+paraMap.get("nonce_str")+"</nonce_str>"); paramBuffer.append("<sign>"+sign+"</sign>"); paramBuffer.append("<body>"+body+"</body>"); paramBuffer.append("<out_trade_no>"+paraMap.get("out_trade_no")+"</out_trade_no>"); paramBuffer.append("<total_fee>"+paraMap.get("total_fee")+"</total_fee>"); paramBuffer.append("<spbill_create_ip>"+paraMap.get("spbill_create_ip")+"</spbill_create_ip>"); paramBuffer.append("<notify_url>"+paraMap.get("notify_url")+"</notify_url>"); paramBuffer.append("<trade_type>"+paraMap.get("trade_type")+"</trade_type>"); paramBuffer.append("<openid>"+openid+"</openid>"); paramBuffer.append("</xml>"); //发送请求(POST)(获得数据包ID)(这有个注意的地方 如果body中 包含中文,需要对请求进行编码.) String map = getRestTemplateInstance("utf-8").postForObject(payUrl, paramBuffer.toString(), String.class); Map<String,String> parseObject = doXMLParse(map); //应该创建 支付表数据 if(parseObject != null){ log.info("微信 统一下单 接口调用成功 新增支付信息 :"+paraMap.get("out_trade_no")); resultJson.put("prepayId", parseObject.get("prepay_id")); resultJson.put("outTradeNo", paraMap.get("out_trade_no")); String sql = " Update orders set transaction ='"+parseObject.get("prepay_id") +"' where orderCode = "+paraMap.get("out_trade_no"); dao.update(sql); return resultJson; } //将 数据包ID 返回 return resultJson; }
public RestTemplate getRestTemplateInstance(String charset) { List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters(); for (HttpMessageConverter<?> httpMessageConverter : list) { if(httpMessageConverter instanceof StringHttpMessageConverter) { ((StringHttpMessageConverter) httpMessageConverter).setDefaultCharset(Charset.forName(charset)); break; } } return restTemplate; }
private String getIpAddress() { InetAddress address = null;; try { address = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } return address.getHostAddress(); /* // 避免反向代理不能获取真实地址, 取X-Forwarded-For中第一个非unknown的有效IP字符串 String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){ ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){ ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){ ip = request.getRemoteAddr(); } return ip;*/ }
private InputStream String2Inputstream(String str) { return new ByteArrayInputStream(str.getBytes()); } @SuppressWarnings("rawtypes") private String getChildrenText(List children) { StringBuffer sb = new StringBuffer(); if(!children.isEmpty()) { Iterator it = children.iterator(); while(it.hasNext()) { Element e = (Element) it.next(); String name = e.getName(); String value = e.getTextNormalize(); List list = e.getChildren(); sb.append("<" + name + ">"); if(!list.isEmpty()) { sb.append(getChildrenText(list)); } sb.append(value); sb.append("</" + name + ">"); } } return sb.toString(); } private String getMD5String(String str) { try { // 生成一个MD5加密计算摘要 MessageDigest md = MessageDigest.getInstance("MD5"); // 计算md5函数 md.update(str.getBytes()); // digest()最后确定返回md5 hash值,返回值为8位字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符 // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值 //一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方) return new BigInteger(1, md.digest()).toString(16); } catch (Exception e) { e.printStackTrace(); return null; } } private String formatUrlMap(Map<String, String> paraMap, boolean urlEncode, boolean keyToLower){ String buff = ""; Map<String, String> tmpMap = paraMap; try{ List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(tmpMap.entrySet()); // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序) Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>(){ @Override public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2){ return (o1.getKey()).toString().compareTo(o2.getKey()); } }); // 构造URL 键值对的格式 StringBuilder buf = new StringBuilder(); for (Map.Entry<String, String> item : infoIds){ if (StringUtils.isNotBlank(item.getKey())){ String key = item.getKey(); String val = item.getValue(); if (urlEncode){ val = URLEncoder.encode(val, "utf-8"); } if(keyToLower){ buf.append(key.toLowerCase() + "=" + val); }else{ buf.append(key + "=" + val); } buf.append("&"); } } buff = buf.toString(); if (buff.isEmpty() == false){ buff = buff.substring(0, buff.length() - 1); } } catch (Exception e){ return null; } return buff; }
@SuppressWarnings("rawtypes") private Map<String,String> doXMLParse(String strxml) throws JDOMException, IOException{ if(null == strxml || "".equals(strxml)) { return null; } Map<String,String> m = new HashMap<String,String>(); InputStream in = String2Inputstream(strxml); SAXBuilder builder = new SAXBuilder(); Document doc = builder.build(in); Element root = doc.getRootElement(); List list = root.getChildren(); Iterator it = list.iterator(); while(it.hasNext()) { Element e = (Element) it.next(); String k = e.getName(); String v = ""; List children = e.getChildren(); if(children.isEmpty()) { v = e.getTextNormalize(); } else { v = getChildrenText(children); } m.put(k, v); } //关闭流 in.close(); return m; }
相关推荐
在这个项目中,我们结合了微信小程序和Java后台技术,实现了一个完整的微信支付流程。以下将详细阐述涉及的知识点: 1. **微信小程序**:微信小程序是一种轻量级的应用开发框架,允许开发者在微信内部创建和运行...
微信支付 微支付 V3版 后端 JAVA 在pay.jsp里面填上商户密钥
在Java开发领域,微信支付是常见的在线支付方式之一,它为商家提供了...通过研究源码,你可以学习到如何对接微信支付接口,以及如何处理支付过程中的各种业务逻辑。在实际项目中,可以根据需求进行适当的修改和扩展。
Java后台微信支付工具类是开发微信App支付时不可或缺的一部分,它包含了处理支付请求、响应以及与微信支付服务器交互的关键逻辑。微信支付是一个安全且广泛使用的支付方式,它允许用户通过微信应用程序进行线上交易...
在微信支付的小程序开发中,Java后台扮演着关键的角色,主要负责处理支付相关的逻辑和与微信支付接口的交互。以下是一些关于这个主题的重要知识点: 1. **小程序支付流程**: - 用户在小程序内选择商品或服务并...
首先,"JAVA马来西亚微信支付"这个标题暗示我们需要关注的是Java平台上的微信支付SDK或API的使用。微信提供了官方的开发者文档,其中包括了Java版本的SDK,供开发者接入其支付系统。这通常涉及到创建商户账号,获取...
本篇将详细讲解如何利用Java后端为iOS应用构建微信支付接口。 首先,我们要了解微信支付的基本流程。微信支付通常包括以下几个步骤: 1. **预支付请求**:iOS客户端向Java后端发送请求,包含商品信息、订单详情等...
最近抽时间整理出来包括扫码支付和jsapi支付的版本的demo,代码非常的详细,很多容易出错的地方我都注释了出来,报错后台代码和前台代码的demo,前台包括二维码生成demo,另外增加了java版本处理微信支付回调通知的...
5. **支付集成**:微信小程序支持微信支付,后台需要实现微信支付接口对接,处理支付请求、验证支付结果,并完成订单状态的更新。 6. **安全与性能**:后台系统需确保用户数据的安全,例如使用HTTPS加密通信,防止...
源代码中包括了各种网络消息接收类,比如接收到的微信xml实体类,解析接收到的微信xml,微信服务端收发消息接口... 代码中将判断是否是微信接入激活验证,只有首次接入验证时才会收到echostr参数,此时需要把它直接返回
2. **统一下单接口**:在用户准备支付时,Java后台需要调用微信支付的统一下单接口,生成预支付交易会话标识(prepay_id)。这个过程需要提供商户号、商品描述、交易金额、回调URL等信息。 3. **生成支付二维码或...
使用JSAPI支付,开发者需要先在后台获取预下单(统一下单)的订单信息,包括`prepay_id`,然后在前端通过微信JSSDK将这个信息传递给微信支付接口,用户确认支付后,资金会直接进入商户账户。 2. **退款流程**: 在...
java 微信公众号
- 支付接口:对接微信支付或其他第三方支付平台,完成交易过程。 - 数据库操作:与数据库交互,实现数据的持久化存储。 - 接口设计:提供RESTful API供微信小程序调用,如商品查询、下单、支付等。 3. **...
- **后端接口**:您需要在服务器端实现与微信支付接口的对接,包括订单创建、退款、查询订单状态等功能。通常使用的是微信支付的商户API,涉及的接口如统一下单、退款申请、订单查询等。 - **微信支付SDK**:微信...
本案例将详细讲解如何使用Java来实现企业微信的回调配置,并提供相关的工具代码示例。 1. **企业微信API介绍** 企业微信提供了丰富的API接口,包括但不限于用户管理、部门管理、消息推送等。回调配置主要是通过...
微信支付同样提供了微信支付SDK,支持Java平台。开发者需要在微信商户平台申请相应的API权限,获取AppID、商户号、支付密钥等。使用SDK的`统一下单`接口生成预支付交易会话标识,这个标识将在前端调用微信支付H5页面...
3. **微信支付SDK**:为了简化与微信支付接口的对接,微信提供了Java版的SDK。开发者可以利用这个SDK处理签名、请求验证、调用接口等工作,减少错误和提高开发效率。 4. **微信小程序与H5页面集成**:前端部分包括...
在Java后台实现微信小程序支付主要包括以下知识点: 1. **OpenId 获取**:微信小程序用户在使用过程中,会通过微信登录授权获取到一个OpenId,这是识别用户身份的唯一标识。在后台,可以通过接收到的小程序前端传来...
### 最新王者荣耀模板发卡网整站源码对接微信支付宝双通道个人免签接口+个人发卡在线下单自动发货开源源码 #### 知识点一:王者荣耀模板发卡网整站源码 1. **定义与理解**: - 整站源码指的是网站从后端到前端的...