微信公众号支付(二):统一下单
上一篇已经获取到了用户的OpenId
转载自:http://www.knowsky.com/888924.html
这篇主要是调用微信公众支付的统一下单API
API地址:https://pay.weixin.QQ.com/wiki/doc/api/jsapi.php?chapter=9_1
看文档,主要流程就是把20个左右的参数封装为xml格式发送到微信给的接口地址,然后就可以获取到返回的内容了,如果成功里面就有支付所需要的预支付ID
请求参数就不解释了。
其中,随机字符串:我用的是UUID去中划线
1 public static String create_nonce_str() {2 return UUID.randomUUID().toString().replace("-","");3 }
商户订单号:每个订单号只能使用一次,所以用的是系统的订单号加的时间戳。
总金额:不能为0
通知地址:微信支付成功或失败回调给系统的地址
签名:
1 import java.io.Serializable; 2 3 public class PayInfo implements Serializable{ 4 5 PRivate static final long serialVersionUID = 5637164279924222380L; 6 private String appid; 7 private String mch_id; 8 private String device_info; 9 private String nonce_str;10 private String sign;11 private String body;12 private String attach;13 private String out_trade_no;14 private int total_fee;15 private String spbill_create_ip;16 private String notify_url;17 private String trade_type;18 private String openid;19 20 //下面是get,set方法 21 }
1 /** 2 * 创建统一下单的xml的java对象 3 * @param bizOrder 系统中的业务单号 4 * @param ip 用户的ip地址 5 * @param openId 用户的openId 6 * @return 7 */ 8 public PayInfo createPayInfo(BizOrder bizOrder,String ip,String openId) { 9 PayInfo payInfo = new PayInfo();10 payInfo.setAppid(Constants.appid);11 payInfo.setDevice_info("WEB");12 payInfo.setMch_id(Constants.mch_id);13 payInfo.setNonce_str(CommonUtil.create_nonce_str().replace("-", ""));14 payInfo.setBody("这里是某某白米饭的body");15 payInfo.setAttach(bizOrder.getId());16 payInfo.setOut_trade_no(bizOrder.getOrderCode().concat("A").concat(DateFormatUtils.format(new Date(), "MMddHHmmss")));17 payInfo.setTotal_fee((int)bizOrder.getFeeAmount());18 payInfo.setSpbill_create_ip(ip);19 payInfo.setNotify_url(Constants.notify_url);20 payInfo.setTrade_type("JSAPI");21 payInfo.setOpenid(openId);22 return payInfo;23 }
获取签名:
1 /** 2 * 获取签名 3 * @param payInfo 4 * @return 5 * @throws Exception 6 */ 7 public String getSign(PayInfo payInfo) throws Exception { 8 String signTemp = "appid="+payInfo.getAppid() 9 +"&attach="+payInfo.getAttach()10 +"&body="+payInfo.getBody()11 +"&device_info="+payInfo.getDevice_info()12 +"&mch_id="+payInfo.getMch_id()13 +"&nonce_str="+payInfo.getNonce_str()14 +"¬ify_url="+payInfo.getNotify_url()15 +"&openid="+payInfo.getOpenid()16 +"&out_trade_no="+payInfo.getOut_trade_no()17 +"&spbill_create_ip="+payInfo.getSpbill_create_ip()18 +"&total_fee="+payInfo.getTotal_fee()19 +"&trade_type="+payInfo.getTrade_type()20 +"&key="+Constants.key; //这个key注意21 22 MessageDigest md5 = MessageDigest.getInstance("MD5");23 md5.reset();24 md5.update(signTemp.getBytes("UTF-8"));25 String sign = CommonUtil.byteToStr(md5.digest()).toUpperCase();26 return sign;27 }
注意:上面的Constants.key取值在商户号API安全的API密钥中。
一些工具方法:获取ip地址,将字节数组转换为十六进制字符串,将字节转换为十六进制字符串
1 /** 2 * 将字节数组转换为十六进制字符串 3 * 4 * @param byteArray 5 * @return 6 */ 7 public static String byteToStr(byte[] byteArray) { 8 String strDigest = ""; 9 for (int i = 0; i < byteArray.length; i++) {10 strDigest += byteToHexStr(byteArray[i]);11 }12 return strDigest;13 }14 15 /**16 * 将字节转换为十六进制字符串17 * 18 * @param btyes19 * @return20 */21 public static String byteToHexStr(byte bytes) {22 char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };23 char[] tempArr = new char[2];24 tempArr[0] = Digit[(bytes >>> 4) & 0X0F];25 tempArr[1] = Digit[bytes & 0X0F];26 27 String s = new String(tempArr);28 return s;29 }30 31 /**32 * 获取ip地址33 * @param request34 * @return35 */36 public static String getIpAddr(HttpServletRequest request) { 37 InetAddress addr = null; 38 try { 39 addr = InetAddress.getLocalHost(); 40 } catch (UnknownHostException e) { 41 return request.getRemoteAddr(); 42 } 43 byte[] ipAddr = addr.getAddress(); 44 String ipAddrStr = ""; 45 for (int i = 0; i < ipAddr.length; i++) { 46 if (i > 0) { 47 ipAddrStr += "."; 48 } 49 ipAddrStr += ipAddr[i] & 0xFF; 50 } 51 return ipAddrStr; 52 }
这样就获取了签名,把签名与PayInfo中的其他数据转成XML格式,当做参数传递给统一下单地址。
1 PayInfo pi = pu.createPayInfo(bo,"10.204.3.32","22");2 String sign = pu.getSign(pi);3 pi.setSign(sign);
对象转XML
1 /** 2 * 扩展xstream使其支持CDATA 3 */ 4 private static XStream xstream = new XStream(new XppDriver() { 5 public HierarchicalStreamWriter createWriter(Writer out) { 6 return new PrettyPrintWriter(out) { 7 //增加CDATA标记 8 boolean cdata = true; 9 10 @SuppressWarnings("rawtypes")11 public void startNode(String name, Class clazz) {12 super.startNode(name, clazz);13 }14 15 protected void writeText(QuickWriter writer, String text) {16 if (cdata) {17 writer.write("<![CDATA[");18 writer.write(text);19 writer.write("]]>");20 } else {21 writer.write(text);22 }23 }24 };25 }26 });27 28 public static String payInfoToXML(PayInfo pi) {29 xstream.alias("xml", pi.getClass());30 return xstream.toXML(pi);31 }
xml转Map
1 @SuppressWarnings("unchecked") 2 public static Map<String, String> parseXml(String xml) throws Exception { 3 Map<String, String> map = new HashMap<String, String>(); 4 5 Document document = DocumentHelper.parseText(xml); 6 Element root = document.getRootElement(); 7 List<Element> elementList = root.elements(); 8 9 for (Element e : elementList)10 map.put(e.getName(), e.getText());11 return map;12 }
下面就是调用统一下单的URL了
1 log.info(MessageUtil.payInfoToXML(pi).replace("__", "_"));2 Map<String, String> map = CommonUtil.httpsRequestToXML("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", MessageUtil.payInfoToXML(pi).replace("__", "_").replace("<![CDATA[", "").replace("]]>", ""));3 log.info(map);
1 public static Map<String, String> httpsRequestToXML(String requestUrl, String requestMethod, String outputStr) { 2 Map<String, String> result = new HashMap<>(); 3 try { 4 StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr); 5 result = MessageUtil.parseXml(buffer.toString()); 6 } catch (ConnectException ce) { 7 log.error("连接超时:"+ce.getMessage()); 8 } catch (Exception e) { 9 log.error("https请求异常:"+ece.getMessage());10 }11 return result;12 }
httpsRequest()这个方法在第一篇中上面获取到的Map如果成功的话,里面就会有
1 String return_code = map.get("return_code"); 2 if(StringUtils.isNotBlank(return_code) && return_code.equals("SUCCESS")){ 3 String return_msg = map.get("return_msg"); 4 if(StringUtils.isNotBlank(return_msg) && !return_msg.equals("OK")) { 5 return "统一下单错误!"; 6 } 7 }else{ 8 return "统一下单错误!"; 9 }10 11 String prepay_Id = map.get("prepay_id");
这个prepay_id就是预支付的ID。后面支付需要它
转载于:https://blog.51cto.com/1306733/1874608
微信公众号支付(二):统一下单相关推荐
- 微信公众号支付--2--统一下单
调用统一下单api之前,需要先获取openid,请先查看https://blog.csdn.net/hjfcgt123/article/details/104172909这篇博文. 一.配置JSAPI ...
- 微信公众号支付及提现
微信支付,分为很多种,前端一般情况有两种,公众号支付和H5页面支付(在QQ,浏览器上),这篇文章为公众号支付,H5页面支付请看:https://blog.csdn.net/qq_34664239/ar ...
- 微信公众号支付,iframe跨域
官方文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_7&index=6,即可看到h5调起支付需要的参数. 获取后台调 ...
- php微信统一公众号支付接口,微信公众号支付怎么实现统一下单接口
微信公众号支付怎么实现统一下单接口 发布时间:2021-03-12 09:44:45 来源:亿速云 阅读:89 作者:小新 这篇文章将为大家详细讲解有关微信公众号支付怎么实现统一下单接口,小编觉得挺实 ...
- yii2嵌入微信公众号支付
序言 随着微信被越来越多的人使用,微信商城成为如今的热门.每一个商城都需要有自己的支付方式,微信商城也不例外.微信公众号支付就是微信商城的一种支付方式,微信支付随着微信的推广使用也被广泛应用.今天我主 ...
- js如何调用h5的日期控价_微信公众号支付H5调用支付解析
最近项目需要微信支付,然后看了下微信公众号支付,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验. 一.配置公众号微信支付 ...
- vue 微信公众号支付接口_基于vue的h5项目之支付宝支付与微信支付
本文仅记录基于vue开发h5项目过程中使用支付宝和微信支付过程中的重点与槽点,仅为前端部分,如有疏漏不正之处,请于文末评论探讨.注意:标红部分灰常重要,仔细阅读官方文档非常重要,耐心非常重要,细心非常 ...
- h5通过php微信支付宝支付,用H5调用支付微信公众号支付的解析
这篇文章主要为大家详细介绍了微信公众号支付H5调用支付,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 最近项目需要微信支付,然后看了下微信公众号支付,虽然不难,但是细节还是需要注意的,用了大半天时 ...
- 关于微信公众号支付接口开发遇到的奇葩问题,始终返回get_brand_wcpay_request:fail。
最近公司开发网站针对微信公众号的支付功能. 由于公司目前的这个项目网站是使用asp代码开发的,但是微信官方给出的demo中是没有asp版本的,所以楼主只有下载demo的php版本作为参考写了一个asp ...
- java开发微信公众号支付
这篇文章主要给大家结合微信支付接口开发的实践,从获取用户授权到各主要接口的使用方法等方面介绍微信支付的关键点技术,有需要的小伙伴可以参考下 最近做了微信公众号支付的开发,由于是第一次做也摸索了几天的时 ...
最新文章
- 自定义组合控件:下拉选择框
- 天津工业大学19年计算机考研大纲,2019年天津工业大学《计算机原理及接口技术》考研复试大纲...
- 记录navigator实现不同设备页面跳转
- 用8小时工作,用24小时思考
- 关于DataFormWebPart中CreatedModifiedInfo信息的分开使用
- netfilter que_QUE的完整形式是什么?
- Web Hacking 101 中文版 十、跨站脚本攻击(一)
- Android面向HTTP协议发送post请求
- The “note“ model is Samsung’s first
- 记一个SwipeMenuListView侧滑删除错乱的Bug
- Sicily/1927. Conflict
- mysql索引简单介绍
- BIM标准化系列写作思路
- 百度token怎么获取_【专栏精选】实战:百度语音识别
- python人机猜拳_python实现人机猜拳小游戏
- Ubuntu16(ROS_Kinetic)海康威视网络摄像机(单目)内参标定
- 单片机与PC机的交流———基于STM32的串口通信
- 住在宝马对面的苦逼程序员
- 手把手教你批量制作MV连播视频
- cpu架构(cpu架构怎么看)
热门文章
- DLT(DeepLearningTracker)学习与代码理解 (1)
- 其原因可能是堆被损坏,这也说明 xxx.exe 中或它所加载的任何 DLL 中有 bug
- 使用easeui dialog弹出框中使用CKeditor多次加载后无法编辑问题
- About Javascript MVC
- c primer plus(第五版)读书笔计 第四章(1)
- 为在innodb中什么主键用auto_increment效率会提高
- 利用Directsound编程实现实时混音
- JavaScript初体验之冲出迷雾,我四个多小时的经验教训_AX
- EOSRAM那么火,BANCOR协议白皮书了解一下?
- Python学习日志(5)- Numpy