微信支付统一下单

2024-08-28 04:48
文章标签 微信 统一 支付 下单

本文主要是介绍微信支付统一下单,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[java] view plain copy
  1. 估计大多数人和我一样吧,每次要使用腾讯的开发api,都有一种想上吊的感觉,尤其是微信支付和支付宝对比起来文档确实差距还是有点大的  

关于微信支付的申请我就不多说了,网上有很多,我们直接来说一下微信支付

微信支付是以下步骤(官方文档说明 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3)

步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。

步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。参见【统一下单API】。

步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay

      步骤3要注意千万不要按照他给的签名字段进行前面,我就被坑了一天

     appid
     partnerid
     prepayid
     package
     noncestr
     timestamp
     sign

   签名字段一定不要按照文档的驼峰写法,应该是全部小写,就像上面

步骤4:商户APP调起微信支付。api参见本章节【app端开发步骤说明】

步骤5:商户后台接收支付通知。api参见【支付结果通知API】

步骤6:商户后台查询支付结果。,api参见【查询订单API】

接下来我们就开始讲解统一下单

请求URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder

参数

字段名变量名必填类型示例值描述
应用IDappidString(32)wxd678efh567hg6787微信开放平台审核通过的应用APPID
商户号mch_idString(32)1230000109微信支付分配的商户号
设备号device_infoString(32)013467007045764终端设备号(门店号或收银设备ID),默认请传"WEB"
随机字符串nonce_strString(32)5K8264ILTKCH16CQ2502SI8ZNMTM67VS随机字符串,不长于32位。推荐随机数生成算法
签名signString(32)C380BEC2BFD727A4B6845133519F3AD6签名,详见签名生成算法
商品描述bodyString(128)Ipad mini  16G  白色商品或支付单简要描述
商品详情detailString(8192)Ipad mini  16G  白色商品名称明细列表
附加数据attachString(127)深圳分店附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
商户订单号out_trade_noString(32)20150806125346商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
货币类型fee_typeString(16)CNY符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
总金额total_feeInt888订单总金额,单位为分,详见支付金额
终端IPspbill_create_ipString(16)123.12.12.123用户端实际ip
交易起始时间time_startString(14)20091225091010订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
交易结束时间time_expireString(14)20091227091010

订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。其他详见时间规则

注意:最短失效时间间隔必须大于5分钟
商品标记goods_tagString(32)WXG商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
通知地址notify_urlString(256)http://www.weixin.qq.com/wxpay/pay.php接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
交易类型trade_typeString(16)APP支付类型
指定支付方式limit_payString(32)no_creditno_credit--指定不能使用信用卡支付
我们先上工具类吧
[java] view plain copy
  1. public class PayCommonUtil {  
  2.     //微信参数配置  
  3.     public static String API_KEY="";  
  4.     public static String APPID="";  
  5.     public static String MCH_ID="";  
  6.     //随机字符串生成  
  7.     public static String getRandomString(int length) { //length表示生成字符串的长度      
  8.            String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";         
  9.            Random random = new Random();         
  10.            StringBuffer sb = new StringBuffer();         
  11.            for (int i = 0; i < length; i++) {         
  12.                int number = random.nextInt(base.length());         
  13.                sb.append(base.charAt(number));         
  14.            }         
  15.            return sb.toString();         
  16.         }    
  17.     //请求xml组装  
  18.       public static String getRequestXml(SortedMap<String,Object> parameters){  
  19.             StringBuffer sb = new StringBuffer();  
  20.             sb.append("<xml>");  
  21.             Set es = parameters.entrySet();  
  22.             Iterator it = es.iterator();  
  23.             while(it.hasNext()) {  
  24.                 Map.Entry entry = (Map.Entry)it.next();  
  25.                 String key = (String)entry.getKey();  
  26.                 String value = (String)entry.getValue();  
  27.                 if ("attach".equalsIgnoreCase(key)||"body".equalsIgnoreCase(key)||"sign".equalsIgnoreCase(key)) {  
  28.                     sb.append("<"+key+">"+"<![CDATA["+value+"]]></"+key+">");  
  29.                 }else {  
  30.                     sb.append("<"+key+">"+value+"</"+key+">");  
  31.                 }  
  32.             }  
  33.             sb.append("</xml>");  
  34.             return sb.toString();  
  35.         }  
  36.       //生成签名  
  37.       public static String createSign(String characterEncoding,SortedMap<String,Object> parameters){  
  38.             StringBuffer sb = new StringBuffer();  
  39.             Set es = parameters.entrySet();  
  40.             Iterator it = es.iterator();  
  41.             while(it.hasNext()) {  
  42.                 Map.Entry entry = (Map.Entry)it.next();  
  43.                 String k = (String)entry.getKey();  
  44.                 Object v = entry.getValue();  
  45.                 if(null != v && !"".equals(v)  
  46.                         && !"sign".equals(k) && !"key".equals(k)) {  
  47.                     sb.append(k + "=" + v + "&");  
  48.                 }  
  49.             }  
  50.             sb.append("key=" + API_KEY);  
  51.             String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();  
  52.             return sign;  
  53.         }  
  54.       //请求方法  
  55.       public static String httpsRequest(String requestUrl, String requestMethod, String outputStr) {  
  56.             try {  
  57.                  
  58.                 URL url = new URL(requestUrl);  
  59.                 HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  60.                 
  61.                 conn.setDoOutput(true);  
  62.                 conn.setDoInput(true);  
  63.                 conn.setUseCaches(false);  
  64.                 // 设置请求方式(GET/POST)  
  65.                 conn.setRequestMethod(requestMethod);  
  66.                 conn.setRequestProperty("content-type""application/x-www-form-urlencoded");  
  67.                 // 当outputStr不为null时向输出流写数据  
  68.                 if (null != outputStr) {  
  69.                     OutputStream outputStream = conn.getOutputStream();  
  70.                     // 注意编码格式  
  71.                     outputStream.write(outputStr.getBytes("UTF-8"));  
  72.                     outputStream.close();  
  73.                 }  
  74.                 // 从输入流读取返回内容  
  75.                 InputStream inputStream = conn.getInputStream();  
  76.                 InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");  
  77.                 BufferedReader bufferedReader = new BufferedReader(inputStreamReader);  
  78.                 String str = null;  
  79.                 StringBuffer buffer = new StringBuffer();  
  80.                 while ((str = bufferedReader.readLine()) != null) {  
  81.                     buffer.append(str);  
  82.                 }  
  83.                 // 释放资源  
  84.                 bufferedReader.close();  
  85.                 inputStreamReader.close();  
  86.                 inputStream.close();  
  87.                 inputStream = null;  
  88.                 conn.disconnect();  
  89.                 return buffer.toString();  
  90.             } catch (ConnectException ce) {  
  91.                 System.out.println("连接超时:{}"+ ce);  
  92.             } catch (Exception e) {  
  93.                 System.out.println("https请求异常:{}"+ e);  
  94.             }  
  95.             return null;  
  96.         }  
  97.       //退款的请求方法  
  98.       public static String httpsRequest2(String requestUrl, String requestMethod, String outputStr) throws Exception {  
  99.             KeyStore keyStore  = KeyStore.getInstance("PKCS12");  
  100.             StringBuilder res = new StringBuilder("");  
  101.             FileInputStream instream = new FileInputStream(new File("/home/apiclient_cert.p12"));  
  102.             try {  
  103.                 keyStore.load(instream, "".toCharArray());  
  104.             } finally {  
  105.                 instream.close();  
  106.             }  
  107.   
  108.             // Trust own CA and all self-signed certs  
  109.             SSLContext sslcontext = SSLContexts.custom()  
  110.                     .loadKeyMaterial(keyStore, "1313329201".toCharArray())  
  111.                     .build();  
  112.             // Allow TLSv1 protocol only  
  113.             SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(  
  114.                     sslcontext,  
  115.                     new String[] { "TLSv1" },  
  116.                     null,  
  117.                     SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
  118.             CloseableHttpClient httpclient = HttpClients.custom()  
  119.                     .setSSLSocketFactory(sslsf)  
  120.                     .build();  
  121.             try {  
  122.   
  123.                 HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/refund");  
  124.                 httpost.addHeader("Connection""keep-alive");  
  125.                 httpost.addHeader("Accept""*/*");  
  126.                 httpost.addHeader("Content-Type""application/x-www-form-urlencoded; charset=UTF-8");  
  127.                 httpost.addHeader("Host""api.mch.weixin.qq.com");  
  128.                 httpost.addHeader("X-Requested-With""XMLHttpRequest");  
  129.                 httpost.addHeader("Cache-Control""max-age=0");  
  130.                 httpost.addHeader("User-Agent""Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");  
  131.                  StringEntity entity2 = new StringEntity(outputStr ,Consts.UTF_8);  
  132.                  httpost.setEntity(entity2);  
  133.                 System.out.println("executing request" + httpost.getRequestLine());  
  134.   
  135.                 CloseableHttpResponse response = httpclient.execute(httpost);  
  136.                  
  137.                 try {  
  138.                     HttpEntity entity = response.getEntity();  
  139.                       
  140.                     System.out.println("----------------------------------------");  
  141.                     System.out.println(response.getStatusLine());  
  142.                     if (entity != null) {  
  143.                         System.out.println("Response content length: " + entity.getContentLength());  
  144.                         BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));  
  145.                         String text;res.append(text);  
  146.                         while ((text = bufferedReader.readLine()) != null) {  
  147.                             res.append(text);  
  148.                             System.out.println(text);  
  149.                         }  
  150.                          
  151.                     }  
  152.                     EntityUtils.consume(entity);  
  153.                 } finally {  
  154.                     response.close();  
  155.                 }  
  156.             } finally {  
  157.                 httpclient.close();  
  158.             }  
  159.             return  res.toString();  
  160.               
  161.         }  
  162.       //xml解析  
  163.       public static Map doXMLParse(String strxml) throws JDOMException, IOException {  
  164.             strxml = strxml.replaceFirst("encoding=\".*\"""encoding=\"UTF-8\"");  
  165.   
  166.             if(null == strxml || "".equals(strxml)) {  
  167.                 return null;  
  168.             }  
  169.               
  170.             Map m = new HashMap();  
  171.               
  172.             InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));  
  173.             SAXBuilder builder = new SAXBuilder();  
  174.             Document doc = builder.build(in);  
  175.             Element root = doc.getRootElement();  
  176.             List list = root.getChildren();  
  177.             Iterator it = list.iterator();  
  178.             while(it.hasNext()) {  
  179.                 Element e = (Element) it.next();  
  180.                 String k = e.getName();  
  181.                 String v = "";  
  182.                 List children = e.getChildren();  
  183.                 if(children.isEmpty()) {  
  184.                     v = e.getTextNormalize();  
  185.                 } else {  
  186.                     v = getChildrenText(children);  
  187.                 }  
  188.                   
  189.                 m.put(k, v);  
  190.             }  
  191.               
  192.             //关闭流  
  193.             in.close();  
  194.               
  195.             return m;  
  196.         }  
  197.         
  198.       public static String getChildrenText(List children) {  
  199.             StringBuffer sb = new StringBuffer();  
  200.             if(!children.isEmpty()) {  
  201.                 Iterator it = children.iterator();  
  202.                 while(it.hasNext()) {  
  203.                     Element e = (Element) it.next();  
  204.                     String name = e.getName();  
  205.                     String value = e.getTextNormalize();  
  206.                     List list = e.getChildren();  
  207.                     sb.append("<" + name + ">");  
  208.                     if(!list.isEmpty()) {  
  209.                         sb.append(getChildrenText(list));  
  210.                     }  
  211.                     sb.append(value);  
  212.                     sb.append("</" + name + ">");  
  213.                 }  
  214.             }  
  215.               
  216.             return sb.toString();  
  217.         }  
  218.        
  219. }  

统一下单

参数说明
sn订单号
totalAmount支付金额
description产品描述

[java] view plain copy
  1. public static Map<String, String> weixinPrePay(String sn,BigDecimal totalAmount,  
  2.             String description, HttpServletRequest request) {  
  3.         Setting setting = SettingUtils.get();  
  4.         SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();  
  5.         parameterMap.put("appid", PayCommonUtil.APPID);  
  6.         parameterMap.put("mch_id", PayCommonUtil.MCH_ID);  
  7.         parameterMap.put("nonce_str", PayCommonUtil.getRandomString(32));  
  8.         parameterMap.put("body",  
  9.                 StringUtils.abbreviate(description.replaceAll(  
  10.                         "[^0-9a-zA-Z\\u4e00-\\u9fa5 ]"""), 600));  
  11.         parameterMap.put("out_trade_no", sn);  
  12.         parameterMap.put("fee_type""CNY");  
  13.         System.out.println("jiner");  
  14.         BigDecimal total = totalAmount.multiply(new BigDecimal(100));  
  15.         java.text.DecimalFormat df=new java.text.DecimalFormat("0");  
  16.         parameterMap.put("total_fee", df.format(total));  
  17.         System.out.println("jiner2");  
  18.         parameterMap.put("spbill_create_ip", request.getRemoteAddr());  
  19.         parameterMap.put("notify_url""http://xxx.com");  
  20.         parameterMap.put("trade_type""APP");  
  21.         System.out.println("");  
  22.         String sign = PayCommonUtil.createSign("UTF-8", parameterMap);  
  23.         System.out.println("jiner2");  
  24.         parameterMap.put("sign", sign);  
  25.         String requestXML = PayCommonUtil.getRequestXml(parameterMap);  
  26.         System.out.println(requestXML);  
  27.         String result = PayCommonUtil.httpsRequest(  
  28.                 "https://api.mch.weixin.qq.com/pay/unifiedorder""POST",  
  29.                 requestXML);  
  30.         System.out.println(result);  
  31.         Map<String, String> map = null;  
  32.         try {  
  33.             map = PayCommonUtil.doXMLParse(result);  
  34.         } catch (JDOMException e) {  
  35.             // TODO Auto-generated catch block  
  36.             e.printStackTrace();  
  37.         } catch (IOException e) {  
  38.             // TODO Auto-generated catch block  
  39.             e.printStackTrace();  
  40.         }  
  41.         return map;  
  42.     }  


获取prepay_id,二次签名发送结果给app,此方法结合业务自己优化一下,这里只是举个例子

[java] view plain copy
  1. public static String createSignAgain(HttpServletRequest request)  
  2.             Map<String, String> map = weixinPrePay(payment.getSn(), payment.getAmount(),description,  
  3.                 request);  
  4.         JSONObject jsonObject = new JSONObject();  
  5.         SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();  
  6.         parameterMap.put("appid", PayCommonUtil.APPID);  
  7.         parameterMap.put("partnerid", PayCommonUtil.MCH_ID);  
  8.         parameterMap.put("prepayid", map.get("prepay_id"));  
  9.         parameterMap.put("package""Sign=WXPay");  
  10.         parameterMap.put("noncestr", PayCommonUtil.getRandomString(32));  
  11.         parameterMap.put("timestamp", System.currentTimeMillis());  
  12.         String sign = PayCommonUtil.createSign("UTF-8", parameterMap);  
  13.         parameterMap.put("sign", sign);  
  14.         jsonObject.put("parameterMap",parameterMap);  
  15.         return jsonObject.toString();  
  16.     }  


到此统一下下单完成,关于app支付我就不说了,下一篇说一下支付结果通用通知

这篇关于微信支付统一下单的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1113770

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

uniapp设置微信小程序的交互反馈

链接:uni.showToast(OBJECT) | uni-app官网 (dcloud.net.cn) 设置操作成功的弹窗: title是我们弹窗提示的文字 showToast是我们在加载的时候进入就会弹出的提示。 2.设置失败的提示窗口和标签 icon:'error'是设置我们失败的logo 设置的文字上限是7个文字,如果需要设置的提示文字过长就需要设置icon并给

华为OD机试真题-学生方阵-2024年OD统一考试(E卷)

题目描述 学校组织活动,将学生排成一个矩形方阵。 请在矩形方阵中找到最大的位置相连的男生数量。这个相连位置在一个直线上,方向可以是水平的,垂直的,成对角线的或者呈反对角线的。 注:学生个数不会超过10000 输入描述 输入的第一行为矩阵的行数和列数, 接下来的 n行为矩阵元素,元素间用""分隔。 输出描述 输出一个整数,表示矩阵中最长的位

UML- 统一建模语言(Unified Modeling Language)创建项目的序列图及类图

陈科肇 ============= 1.主要模型 在UML系统开发中有三个主要的模型: 功能模型:从用户的角度展示系统的功能,包括用例图。 对象模型:采用对象、属性、操作、关联等概念展示系统的结构和基础,包括类图、对象图、包图。 动态模型:展现系统的内部行为。 包括序列图、活动图、状态图。 因为要创建个人空间项目并不是一个很大的项目,我这里只须关注两种图的创建就可以了,而在开始创建UML图

基于微信小程序与嵌入式系统的智能小车开发(详细流程)

一、项目概述 本项目旨在开发一款智能小车,结合微信小程序与嵌入式系统,提供实时图像处理与控制功能。用户可以通过微信小程序远程操控小车,并实时接收摄像头采集的图像。该项目解决了传统遥控小车在图像反馈和控制延迟方面的问题,提升了小车的智能化水平,适用于教育、科研和娱乐等多个领域。 二、系统架构 1. 系统架构设计 本项目的系统架构主要分为以下几个部分: 微信小程序:负责用户界面、控制指令的

微信小程序uniappvue3版本-控制tabbar某一个的显示与隐藏

1. 首先在pages.json中配置tabbar信息 2. 在代码根目录下添加 tabBar 代码文件 直接把微信小程序文档里面的四个文件复制到自己项目中就可以了   3. 根据自己的需求更改index.js文件 首先我这里需要判断什么时候隐藏某一个元素,需要引入接口 然后在切换tabbar时,改变tabbar当前点击的元素 import getList from '../

微信小程序(一)数据流与数据绑定

一、单向数据流和双向数据流 1、单项数据流:指的是我们先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里面 优点:数据跟踪方便,流向单一,追寻问题比较方便【主要体现:微信小程序】。 缺点:就是写起来不太方便,如果修改UI界面数据需要维护对应的model对象 2、双向数据流:值和UI是双向绑定的,大家都知道,只要UI里面的值发生

微信小程序学习网站

小程序--柯神博客 http://www.cnblogs.com/nosqlcoco 案例地址: https://github.com/cocoli/weixin_smallexe/tree/master/weixin_demo/pages/component/uploadfile

分享一个基于uniapp科技馆服务微信小程序 博物馆管理小程序(源码、调试、LW、开题、PPT)

💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流! 💕💕学习资料、程序开发、技术解答、文档报告 💕💕如需要源码,可以扫取文章下方二维码联系咨询 💕💕Java项目 💕💕微信小程序项目 💕💕Android项目 �

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题 GitHub Pages是一个直接从GitHub存储库托管的静态站点服务,‌它允许用户通过简单的配置,‌将个人的代码项目转化为一个可以在线访问的网站。‌这里使用flutter build web来构建web发布到GitHub Pages。 最近通过flutter build web,通过发布到GitHu