转自 https://blog.csdn.net/weixin_41497737/article/details/80547243

最近因为公司需求开始开始做微信支付的开发,在网上参考来了很多文章,大多都说微信支付的开发文档真坑怎样怎样,做完之后感觉没那么坑,都是自己看的不仔细才回导致出了问题。这里我以JSAPI公众号支付为例。测试环境使用花生壳的内网穿透来搭建的,还开始担心壳域名没有备案,后来发现也是可以的,用花生壳的可以放心使用..

主要分一下几个大步骤:

一。下载sdk 。其实这个sdk就已经把微信支付的功能封装在里面了,已经算是一个成形的代码级应用了.sdk已经把要做的工作都做了,剩下的就是你去调用了,就这么简单。

先看一下这几个接口和类大概是干嘛的(不了解也丝毫不影响开发):

可以对照自己的SDK来看。

1.IWXPayDomain.java

实现域名管理的,不需要我们做工作。

这个抽象接口,测试包中已经帮助我们实现了,我们可以拿过来直接用。复制粘贴改个名字。

2.WXPayConstants

微信支付常量类,这其中的常量很多,但是也都很好理解,内部类枚举,限定了签名方式只能是MD5或者HMACSHA256。这里要注意的是,签名也是有SDK内部实现的,只有在使用到沙箱环境时,才用MD5签名。最后两

部分主要是请求后缀,只不过前者是生产环境,后边的带有的SANbox的是沙箱测试环境。为了直观,我把他们都标注出来了。主要分六部分:

你可以把你们公司的名字MD5加密一下做加密或者直接加密的方式,MD5加密。这么做的好处是,加密源好记,可以防止丢失。

3.WXPayConfig.java

这是一个抽象类,里边是一些微信支付的基本配置。是需要你自己继承并完善的。但是这个实现在SDK自带的测试包中已经实现了,直接把他复制过来。把自己的配置搞进去。

这一步主要的就是下载证书,在商户平台下载证书后,生产环境或者测试的电脑主机才可以调用微信支付下载证书后,放到指定位置,在配置一下路径,很简单,例如我的:

这样配置的实现类就完成了。

4.WXPay.java

看名字你就应该知道,这是最重要的类。就是这个类中已经封装好了所有方法,我们只需要在创建一个类,来调用其中的方法就可以了。

5.WXPayUtil.java

工具类,里边包含了要用到的方法,很全面。

微信支付接口传输数据是通过XML字符串来传输的,然后再两端再分别解析成映射结合。这是封装在内部的我们了解一下就可以了。还包括符号的生成,你看,签名都给你写好了。

当然,你也可以根据自己的需求在放一些其他的工具方法。

6.request和report我没怎么看。看到这里就足够了。

二。创建工具类WXPayTool.java

这里我就直接复制了。排版有点乱,但方便大家。这是测试用,大家可以在改一下。在这里我还新创建了一个类,也就是OrderData类。在传参的时候还要多写一些代码,为什么我要创建这个类呢?我看了微信签名的生成规则,如果字符串为空或者空字符串。那么签名时会自动过滤掉,不参与签名。这么做的好处就是,易于扩展,如果以后公司在需要什么其他的支付方法,也比较方便,在调用一个wxpay中的方法,并传进对应的参数就可以了。我把WXPayTool和OrderData.java的实体类粘贴出来。

公共类WXPayTool {

私人WXPay wxpay;

私人WXPayConfigImpl配置;

公共WXPayTool()抛出异常{

config = WXPayConfigImpl.getInstance();

wxpay =新的WXPay(config,false,false);

}

/ **

*公众号支付

*发起支付后--- >>通信代码,必然返回。请求是否成功代码。如果成功则不返回或者。

*得到预付单编号

* /

public Map <String,String> doUnifiedOrder(OrderData orderData){

Map <String,String> data = new HashMap <String,String>();

data.put(“body”,orderData.getBody());

data.put(“out_trade_no”,orderData.getout_trade_no());

data.put(“total_fee”,orderData.getTotal_fee());

data.put(“spbill_create_ip”,orderData.getSpbill_create_ip());

data.put(“time_start”,orderData.getTime_start());

data.put(“time_expire”,orderData.getTime_expire());

data.put(“notify_url”,orderData.getNotify_url());

data.put(“trade_type”,orderData.getTrade_type());

data.put(“product_id”,orderData.getProduct_id());

data.put(“openid”,orderData.getOpenid());

尝试{

Map <String,String> r = wxpay.unifiedOrder(data,1000,1000);

的System.out.println(R);

返回r;

catch(Exception e){

e.printStackTrace();

返回null;

}

}

/ **

*关闭订单

* @param out_trade_no预付单

* @返回

* /

public Map <String,String> doOrderClose(String out_trade_no){

的System.out.println( “关闭订单”);

HashMap <String,String> data = new HashMap <String,String>();

data.put(“out_trade_no”,out_trade_no);

尝试{

Map <String,String> r = wxpay.closeOrder(data);

的System.out.println(R);

返回r;

catch(Exception e){

e.printStackTrace();

返回null;

}

}

public Map <String,String> doOrderQuery(String out_trade_no){

的System.out.println( “查询订单”);

HashMap <String,String> data = new HashMap <String,String>();

data.put(“out_trade_no”,out_trade_no);

//          data.put(“transaction_id”,“4008852001201608221962061594”);

尝试{

Map <String,String> r = wxpay.orderQuery(data,1000,1000);

的System.out.println(R);

返回r;

catch(Exception e){

e.printStackTrace();

返回null;

}

}

/ **

*退款

*已测试

* @返回

* /

public Map <String,String> doRefund(String out_trade_no,String total_fee){

HashMap <String,String> data = new HashMap <String,String>();

data.put(“out_trade_no”,out_trade_no);

data.put(“out_refund_no”,out_trade_no);

data.put(“total_fee”,total_fee);

data.put(“refund_fee”,total_fee);

data.put(“refund_fee_type”,“CNY”);

//data.put(“op_user_id”,config.getMchID());

尝试{

Map <String,String> r = wxpay.refund(data);

的System.out.println(R);

返回r;

catch(Exception e){

e.printStackTrace();

返回null;

}

}

/ **

*查询退款

*已经测试

* @返回

* /

public Map <String,String> doRefundQuery(String out_trade_no){

HashMap <String,String> data = new HashMap <String,String>();

data.put(“out_refund_no”,out_trade_no);

尝试{

Map <String,String> r = wxpay.refundQuery(data);

的System.out.println(R);

返回r;

catch(Exception e){

e.printStackTrace();

返回null;

}

}

/ **

*对账单下载

*已测试

* @返回

* /

public Map <String,String> doDownloadBill(long time){

HashMap <String,String> data = new HashMap <String,String>();

data.put(“bill_date”,WXPayUtil.generateBillDateStrByLong(time));

data.put(“bill_type”,“ALL”);

尝试{

Map <String,String> r = wxpay.downloadBill(data);

的System.out.println(R);

返回r;

catch(Exception e){

e.printStackTrace();

返回null;

}

}

}

/ **

*微信支付统一下单,所用到的参数,全部为String

* /

公共类OrderData扩展BaseEntity实现Serializable {

/ *参数说明---->

* 1。这里包含的参数,是出去的配置中的其他参数,配置中包含了

* APPID,mchid,标志,signtype,nonce_str

* 2。余下的是下面这些,***标记的为必填项

* 3。参数的初始值都是“”空字符串

*  因为在微信支付官方的SDK中,实现了参数为空不参与签名

* 4。把所有参数都实现的目的是,易于扩展

* 5。由于我们的使用场景,是JSAPI微信公众号支付,我们把要选择参数标记一下用###来标识

* /

private String device_info =“”; //设备号

private String body =“”; //商品简单描述维康动力 - 医疗###

private String detail =“”; //商品详情

私人字符串附加=“”; //附加数据,在查询时,原样返回待定

private String out_trade_no =“”; //订单号***

private String fee_type =“”; //类型,不传,默认为CNY

private String total_fee =“”; //总计多少钱***

private String spbill_create_ip =“”; //用户端ip,必传***

private String time_start =“”; // ###订单生成时间--->这里指的是预付单生成时间###

private String time_expire =“”; // ###订单失效时间--->预付单失效后,如果用户还要提交支付,需要发起重新请求订单接口,获得新的预付单ID ###

private String goods_tag =“”; //订单优惠说明待定

私人字符串notify_url =“”; //回调地址***

private String trade_type =“”; // JSAPI ***

私人字符串product_id =“”; //商品ID,###

private String limit_pay =“”; //非信用卡支付

private String openid =“”; //用户的OpenID ***

private String scene_info =“”; //场景信息

三。具体流程

上一张图,这是我测试用的前端页面,这样看起来也比较清楚。

第一个接口,也就是统一下单接口。这一步相当于用户选中了一个商品,并生成了订单,而这个订单就是预付单。这里有几个需要注意的地方

1)spbill_create_ip的填写文档中指的是客户端的IP,使用了SDK提供的方法WXPayUtil.getCustomerIp(请求)。但是貌似没有什么效果,直接用的127.0.0.1也没问题。微信支付系统虽然要求传这个参数,但貌似对这个参数没有多大的处理。

下面的开始时间和结束时间,微信支付是有要求的,格式为YYYYMMDDHHMMSS,下面的两个方法是我封装的方法。

2)在统一下单提交的数据中要添加notify_url。这是在用户支付成功之后,微信支付系统返回给系统的数据。以XML字符串数据流在HTTP实体中传过来。这是很重要的,在这个过程中,我们需要把返回的数据与平台内数据做对比,查看信息是否准确。并且校验之后要把信息返回给微信支付系统的。如果配置了过滤器过滤器,别忘了放了这个方法。

这个接口主要获得的就是prepay_id预付单ID,有了预付单号之后就可以进行下一步,在JS中调起微信支付控件了。

大概是这样的:

3)在调用返回的数据是Map集合,这样传到前端解析时有问题的,所以使用JSON.fromObject(map)解析成net.json,再传到前端就不会有问题了,后续的接口这些也是需要注意的。

第二步,已经有了订单,用户决定要不要支付。在JS中调起控件,发起支付。点击发起支付,输入密码付款成功。这里需要注意的是

1)package参数,packge参数的内部是prepay_id ='prepay_id'。在这一步测试时,最好用iphone测试,我在使用安卓时,出错了但是没有任何提示。在使用苹果测试时,弹出了错误信息,total_fee参数错误,但是在我们传的签名参数中根本就没有total_fee这个参数。这就比较奇怪了,再次查看文档,发现还是自己看的不仔细。

主要检查了下prepay_id,我传参数的时候格式不对,pacakge是js中的关键字,我把prepay_id传到了后台,拼接出键值对:package:'prepay_id = xxxxxx',在前端取值时就出了问题。所以我直接把prepay_id设置为js的全局变量。在js传参时直接把这个参数传进去。

2)在这里我引入了一个获取JS调用的参数的方法,这个方法也很简单,直接把prepay_id传入后端,用SDK生成签名。这里要注意的是signType不是MD5.MD5是沙箱测试才会使用签名方式。

第三步查询订单。,查询订单是可以根据微信生成的订单号或者平台自己的订单号来查询当前订单的状态的这里要注意的是:

1)要先分清几个单号的概念。预付单ID,商户订单ID,微信系统订单ID。商户订单,这里商户订单是平台自己的自己生成的,在平台中标识,并且也传到微信系统中。预付单,在把商品信息提交后产生的预付款的单号,只是在微信系统中生成了订单,但是还没有支付。而微信系统订单则是已经支付完成之后的单号。

开始的时候,我是用预付单查询订单,但是报错为参数长度有误。开发文档中写的是微信系统订单和商户订单二选一,并且长度都是32位的。后来我做了一个骚操作,数了一下预付单ID的长度,的确的确,它是31位的!后来尝试用支付成功后返回的微信系统订单来查询订单,发现还是不行的.

微信支付开发流程_清晰_易懂_有源码相关推荐

  1. JSAPI微信支付开发流程和坑

    首先,我先简要说明一下微信支付开发的流程 众所周知,工欲善其事,必先利其器,微信官方推出了web微信开发工具,有windows.linux.版本的,根据自己的开发环境选择合适自己的,登陆公众平台--& ...

  2. iOS之“微信支付”开发流程

    实现微信支付的开发,iOS端里面只需要四个步骤: 向服务端请求预支付,获得prepayid以及noncestr: 把参数拼起来签名: 发起支付请求: 处理支付结果. iOS的微信SDK的接入:即为&q ...

  3. 小程序微信支付开发流程记录

    我所在公司需要开发一款商城小程序,里面需要用到微信支付,我负责里面的下单功能,从小程序端到后台的支付流程都是我自己开发的,由于我们组没有人有开发微信支付的经验,只有我有开发过JSAPI的微信支付的经验 ...

  4. android支付宝、微信支付开发流程

    这一段时间项目需要加上微信支付和支付宝支付,经过一段时间摸索,总算能够正常进行支付使用了.想想在支付上遇到的坑,我觉得有必要进行一个记录,在后续的开发中避开支付中遇到的坑: 一.支付宝支付: ps:支 ...

  5. java微信支付必要参数_微信支付 开发账号体系各参数详解

    商户在微信公众平台提交申请资料以及银行账户资料,资料审核通过并签约后,可以获得表6-4所示帐户(包含财付通的相关支付资金账户),用于公众帐号支付. 帐号及作用: appid :公众帐号身份的唯一标识. ...

  6. 工作笔记——微信支付开发相关知识整理

    在最近的工作中,引入了微信小程序支付,在开发过程中积累和整理了一些技术知识,现将其整理如下 目录 一.概念认识 (一)术语介绍 (二)名词解释 (四)对接微信支付接口规则整理 二.微信支付开发参考 ( ...

  7. PHP版本微信支付开发----电脑网站扫码支付(native)(心得、总结)

    早就听说微信支付比支付宝支付的坑多,但还得得该填的填,该绕的绕, 最终我们网站的微信支付功能成功上线啦♪(^ ∇ ^*) 首先自报家门,我的PHP版本是7,微信demo用的是php_sdk_v3.0. ...

  8. 转:微信支付开发关键点技术解析

    原文来自于:http://www.csdn.net/article/2014-10-21/2822207-weiixn 微信支付是由微信及财付通联合推出的移动支付创新产品.如今,随着微信支付的全面开放 ...

  9. 微信支付开发关键点技术解析

    微信支付是由微信及财付通联合推出的移动支付创新产品.如今,随着微信支付的全面开放,相关需求也越来越多,很多开发人员进行微信支付开发及 商家申请微信支付时,面临着诸多疑惑.本文将结合微信支付接口开发的实 ...

最新文章

  1. 字节开启员工期权兑换,126美元每股;
  2. 周志华教授:如何做研究与写论文?(附完整的PPT全文)
  3. BZOJ3529: [Sdoi2014]数表(莫比乌斯反演 树状数组)
  4. 如何用深度学习做自然语言处理?这里有份最佳实践清单
  5. python装饰器实现对异常代码出现进行监控
  6. C#(WinForm) + MySQL的中文编码问题(MySQL中文编码的终极解决方案)
  7. Linux+Nginx+Apache+Atlas+Mysql+Php+Redis 分部式部署详细版
  8. 高等组合学笔记(十五):容斥原理,错排问题
  9. 楼房噪音模拟测试软件,房子不隔音?4种方法让你进入“静音”模式!
  10. pandas中每个元素减去所在行的平均值
  11. Java 笔试练习 01: T1~19
  12. 网络爬虫学习笔记——网络爬虫简介
  13. html5 canvas画椭圆形
  14. 【区块链】从一笔交易看区块链运作流程
  15. GPS网的基线计算以及平差处理(使用Python绘制误差椭圆,C++处理数据并输出Qxx矩阵)
  16. 百度智能云区块链产品负责人刘尧:Web3.0时代加速区块链到来,具有五大特性...
  17. ARGOX CP-2140MPPLB18X60药柜
  18. SeekBar实现实现进度提示随thum移动,自定义View
  19. 阿里算法工程师内推面试经历
  20. Raiffeisen银行俄罗斯分行使用区块链发放数字抵押贷款

热门文章

  1. 复杂网络概论----复杂网络分析(三)
  2. 摇一摇手机控制手机录音功能
  3. 慕课网微信点餐系统之商品信息加载不出来解决方案
  4. USB充电智能识别及自动转换芯片
  5. 5年经验之谈:月薪3000到30000,测试工程师的变“行”记
  6. C++经典排序算法总结
  7. 微信报名系统究竟有什么优势?
  8. 2021.10.02超详细实现过程-Linux 环境下的简易聊天室,采用CS模型,实现多客户端之间的稳定数据传输。(添加好友,删除好友、屏蔽好友、查看好友列表(针对数据库的操作))
  9. 分享我的电子藏书:Java系列
  10. 打造一个属于自己的博客网站-系列教程