首先,你得先有微信开发平台账号密码还需要开通应用,然后还有微信服务商平台商户版账号(这些我都是给产品经理拿的)

其次我认为你先去看一看微信开发平台的文档!  https://pay.weixin.qq.com/wiki/doc/api/index.html

这里有很多种支付,我就采用APP支付来说了(会了APP支付其实H5支付都差不多的!)

进来后是这样的,随便看看'APP支付那几篇文章'讲的流程!,看完后知道大概了就可以看看'API列表了'

我们后台开发需要关注的就是这三个API了!

那我还是简单介绍一下APP支付的一个业务流程吧(其实文档里简述的了,我就直接贴图了!)

这些圈圈起来的流程步骤,就是我们后台要做的了,其他的都是由移动端来实现的,我们可以不理会,还有步骤6查询订单支付结果,这个可做可不做吧,为了系统更安全些更慎重些也可以去实现,不过我就没有实现了

下面就说一下如何对接这个所谓的第三方接口,其实就是跟前端来调用我们后端接口是一样的,我们在写接口文档时,有请求地址,请求参数,返回数据以及返回数据格式这4样!

只要提供这4种东西,前端就可以来对接我们后台接口啦!所以,同个道理的,这次是由我们后台人员去请求微信提供的接口!

所以文档上都有提供的了,我们只需要用httpclient来想微信接口那边发送同步请求获取返回结果数据即可,这样听起来貌似很简单!不过还真不是很简单,很多坑的,毕竟是腾讯的文档!

然后要注意的首先是请求参数,请求参数是否必填这个如果是否的话我就建议不用填上去了,然后签名参数也要去看文档,如何生成签名,还有,参数是要以xml格式形式发送过去,

而且返回结果也是以xml返回回来,所以和微信对接的交互就是xml,这点有点蛋疼呀!

好了,上面说了该怎么去请求第三方接口,想必大家有点懵吧,不知道该如何下手,其实上面的那个请求方式有点难度,小白可以忽略上面那套方式,直接使用微信支付的一个开源jar!

对 你没看错,就这一个,这个jar包里面已经封装好了我们如何获取签名,如何验签等api方法,而且还不需要我们去将参数转化成xml格式,它已经封装好了一切了,所以非常方便!

这个jar包可以在这个地址去下载http://www.mvnjar.com/com.github.liyiorg/weixin-popular/2.8.14/detail.html

好了,那上面的介绍看完还有微信jar拿到手后,现在就可以开始来实现了! 我就直接亮代码了!

  1 /**
2 * @description:微信支付JAVA-SDK: APP支付,退款
3 * @author:小黑
4 */
5 @Service
6 public class WechatPayService {
7 private static final Logger LOGGER = LoggerFactory.getLogger(WechatPayService.class);
8
9 /************ 微信开放平台配置 ***************/
10
11 /** APPID */
12 private static final String APPID = "";
13
14 /** 商户号 */
15 private static final String MCH_ID = "";
16
17 /** 密钥 */
18 private static final String PRIVATE_KEY = "";
19
20 /** 用户订单支付结果异步通知url */
21 private static final String NOTIFY_URL = "";
22
23 /** 商户支付证书路径 */
24 private static final String API_CLIENT_CERT_PATH = "";
25
26 // 加载商户支付证书文件;
27 static {
28 LocalHttpClient.initMchKeyStore(MCH_ID, API_CLIENT_CERT_PATH);
29 }
30
31 /**
32 * @description:使用微信支付-APP支付方式-统一下单;
33 * @return 支付参数,如果支付失败则返回null
34 * @author:Fanhaojian
35 */
36 public MchPayApp orderAppPay(PayLog payLog) {
37
38 Unifiedorder unifiedorder = new Unifiedorder();
39
40 /** APPID */
41 unifiedorder.setAppid(APPID);
42
43 /** 商户号 */
44 unifiedorder.setMch_id(MCH_ID);
45
46 /** 随机字符串 */
47 unifiedorder.setNonce_str(UUID.randomUUID().toString().replaceAll("-", ""));
48
49 /** 商品描述 */
50 unifiedorder.setBody(payLog.getPayCode());
51
52 /** 商户订单号 */
53 unifiedorder.setOut_trade_no(payLog.getPayCode());
54
55 /** 订单总金额 */
56 unifiedorder.setTotal_fee(payLog.getPayPrice().multiply(new BigDecimal(100)).intValue() + ""); // 订单总金额,单位为分;
57
58 /** 用户端请求IP地址 */
59 unifiedorder.setSpbill_create_ip(IpUtils.getClientIp());
60
61 /** 异步通知回调地址 */
62 unifiedorder.setNotify_url(NOTIFY_URL);
63
64 /** 交易类型 */
65 unifiedorder.setTrade_type("APP");
66
67 LOGGER.warn("微信APP支付--(签名前):" + XMLConverUtil.convertToXML(unifiedorder));
68
69 /** 获取签名 */
70 UnifiedorderResult unifiedorderResult = PayMchAPI.payUnifiedorder(unifiedorder, PRIVATE_KEY);
71
72 LOGGER.warn("微信APP支付--支付统一下单接口请求状态(return_code):" + unifiedorderResult.getReturn_code());
73 LOGGER.warn("微信APP支付--支付统一下单接口请求状态(return_msg):" + unifiedorderResult.getReturn_msg());
74 LOGGER.warn("微信APP支付--支付统一下单接口请求状态(result_code):" + unifiedorderResult.getResult_code());
75 LOGGER.warn("微信APP支付--支付请求参数封装(签名后):" + XMLConverUtil.convertToXML(unifiedorder));
76 LOGGER.warn("微信APP支付--支付统一下单接口返回数据:" + FastJSONUtils.getJsonHelper().toJSONString(unifiedorderResult));
77
78 // 下单结果验签;
79 if(unifiedorderResult.getSign_status() != null && unifiedorderResult.getSign_status()) {
80 LOGGER.warn("微信APP支付验签成功");
81 return PayUtil.generateMchAppData(unifiedorderResult.getPrepay_id(), APPID, MCH_ID, PRIVATE_KEY);
82 }
83 return null;
84 }
85
86 /**
87 * @description:微信退款业务封装(支付押金退还);
88 * @param   PayLog order:支付订单信息
89 * Double refundAmount:退款金额
90 * @return 微信退款接口返回数据 true 退款成功 false 退款失败
91 * @author:FanHaoJian
92 */
93 public Boolean refundOrder(PayLog order, Double refundAmount) {
94
95 // 调用微信支付退款接口;
96 SecapiPayRefund payRefund = new SecapiPayRefund();
97 payRefund.setAppid(APPID);
98 payRefund.setMch_id(MCH_ID);
99 payRefund.setNonce_str(UUID.randomUUID().toString().replaceAll("-", ""));
100 payRefund.setOut_trade_no(order.getPayCode());//支付订单号
101 payRefund.setOut_refund_no(order.getRefundCode());//退款单号
102 payRefund.setTotal_fee(order.getPayPrice().multiply(new BigDecimal(100)).intValue());//原订单金额,单位:分;
103 payRefund.setRefund_fee(new BigDecimal(refundAmount).multiply(new BigDecimal(100)).intValue());//退款订单金额,单位:分;
104
105 SecapiPayRefundResult refundResult = PayMchAPI.secapiPayRefund(payRefund, PRIVATE_KEY);
106
107 // 微信支付退款接口返回数据验签;
108 if(refundResult.getSign_status() != null && refundResult.getSign_status()) {
109 LOGGER.warn("微信退款接口--接口请求状态(return_code):" + refundResult.getReturn_code());
110 LOGGER.warn("微信退款接口--接口请求状态(return_msg):" + refundResult.getReturn_msg());
111
112 // 退款信息提交成功;
113 if("SUCCESS".equals(refundResult.getReturn_code())) {
114 LOGGER.warn("微信退款接口--接口请求状态(result_code):" + refundResult.getResult_code());
115 LOGGER.warn("微信退款接口--接口请求状态(err_code):" + refundResult.getErr_code());
116 LOGGER.warn("微信退款接口--接口请求状态(err_code_des):" + refundResult.getErr_code_des());
117
118 return Boolean.TRUE;
119 }
120 }
121
122 return Boolean.FALSE;
123 }
124 }

在项目建一个sdk包,然后统一放入sdk,类似这样!

然后创建一个微信支付SDK,将上面代码复制过去,然后看一遍代码里的方法流程,看明白后在改改里面的代码!

然后我简单介绍一下上面的微信支付SDK吧,里面有两个方法,一个是统一下单,一个是退款!

统一下单返回的数据就是要拿给移动端的签名数据,退款返回的数据就是true和false,没什么判断成功还是失败就行了,成功该做什么,失败该做什么!

OK! 现在说完了统一下单和退款后,还有一个支付通知结果的API,也就是异步通知了!如果你看完了那篇流程图,你就会知道,当移动端调起支付并且支付成功后,微信后台那边会向我们这边后台发送一个请求过来!

当然微信那边发送请求过来我们这边的接口,我也直接亮代码了!

 1 /**
2 * @description:微信支付异步通知请求URL
3 * @author:小黑
4 */
5 public class WechatOrderNotify extends ActionSupport {
6 private static final Logger LOGGER = LoggerFactory.getLogger(WechatOrderNotify.class);
7 private static final long serialVersionUID = 1L;
8
9 /** 密钥 */
10 private static final String PRIVATE_KEY = "";
11
12 /** 定义应答变量 */
13 private String xml;
14
15 @Override
16 public String wechatOrderNotify() throws Exception {
17
18 // 解析微信支付异步通知请求参数;
19 HttpServletRequest request = ServletActionContext.getRequest();
20 String xml = StreamUtils.copyToString(request.getInputStream(), Charset.forName("utf-8"));
21 Map<String, String> params = XMLConverUtil.convertToMap(xml);
22 MchPayNotify payNotify = XMLConverUtil.convertToObject(MchPayNotify.class, xml);
23
24 /** 打印日志信息 */
25 LOGGER.warn("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$---进入微信支付异步通知请求接口---$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
26 LOGGER.warn("微信支付用户订单支付结果异步通知请求参数(xml):" + params);
27 LOGGER.warn("微信支付用户订单支付结果异步通知请求参数(map):" + params);
28 LOGGER.warn("return_code:" + payNotify.getReturn_code());
29 LOGGER.warn("return_msg:" + params.get("return_msg"));
30
31 /** 校验支付成功还是失败 */
32 if("SUCCESS".equals(payNotify.getReturn_code())) {
33
34 /** 获取微信后台返回来的异步通知参数 */
35 String outTradeNo = payNotify.getOut_trade_no(); // 用户订单号;
36 String tradeNo = payNotify.getTransaction_id(); // 微信交易号;
37 String tradeStatus = payNotify.getResult_code(); // 微信支付状态;
38 Integer totalFee = payNotify.getTotal_fee(); // 支付金额
39
40 /** 获取验签结果 true说明验签成功 false说明验签失败 */
41 boolean flag = SignatureUtil.validateSign(params, PRIVATE_KEY);
42
43 /** 打印日志信息 */
44 LOGGER.warn("微信支付--APP支付方式支付用户订单异步通知订单号(out_trade_no):" + outTradeNo);
45 LOGGER.warn("微信支付--APP支付方式支付用户订单异步通知交易号(trade_no):" + tradeNo);
46 LOGGER.warn("微信支付--APP支付方式支付用户订单异步通知交易状态(result_code):" + tradeStatus);
47 LOGGER.warn("微信支付--APP支付方式支付用户订单异步通知支付金额(total_fee):" + totalFee);
48 LOGGER.warn("微信支付--APP支付方式支付用户订单异步通知验签状态:" + flag);
49
50 /** 根据订单号获取订单支付信息: 支付状态为 '未支付' */
51 ...此处省略 根据订单号去查订单 我用hibernate的 你们可能用mybatis或者其他,所以自己去查吧!
52
53 /** 支付成功/处理订单业务信息 */
54 if(flag && "SUCCESS".equals(tradeStatus) && order != null) {
55
56 /** 更新订单支付信息: */
57 ...此处省略 根据自己项目的业务去处理逻辑!
58
59 /** 封装通知信息 */
60 MchBaseResult baseResult = new MchBaseResult();
61 baseResult.setReturn_code("SUCCESS");
62 baseResult.setReturn_msg("OK");
63 xml = XMLConverUtil.convertToXML(baseResult);
64
65 /** 支付成功 */
66 }else if(flag && "SUCCESS".equals(tradeStatus)){
67 MchBaseResult baseResult = new MchBaseResult();
68 baseResult.setReturn_code("SUCCESS");
69 baseResult.setReturn_msg("OK");
70 xml = XMLConverUtil.convertToXML(baseResult);
71
72 /** 支付失败 */
73 }else {
74 MchBaseResult baseResult = new MchBaseResult();
75 baseResult.setReturn_code("FAIL");
76 baseResult.setReturn_msg("FAIL");
77 xml = XMLConverUtil.convertToXML(baseResult);
78 }
79
80 /** 支付失败 */
81 }else {
82 MchBaseResult baseResult = new MchBaseResult();
83 baseResult.setReturn_code("FAIL");
84 baseResult.setReturn_msg("FAIL");
85 xml = XMLConverUtil.convertToXML(baseResult);
86 }
87 LOGGER.warn("微信支付--APP支付方式支付用户订单异步通知返回数据:" + xml);
88 return Results.XML;
89 }
90
91 public String getXml() {
92 return xml;
93 }
94
95 public void setXml(String xml) {
96 this.xml = xml;
97 }
98 }

这里也是直接招搬过去,然后改改代码即可!需要注意的就是这个返回数据xml,你可能要自己定义一下,应答是要这种格式的:

APP支付 + 退款(JAVA实现)的更多相关文章

  1. 微信APP支付(基于Java实现微信APP支付)

    步骤: 导入maven依赖 <!--微信支付--> <dependency> <groupId>com.github.wxpay</groupId> & ...

  2. 支付宝APP支付之Java后台生成签名具体步骤

    /** *支付宝支付 * @param orderId 订单编号 * @param actualPay 实际支付金额 * @return */ private String getOrderInfoB ...

  3. 微信APP支付(Java后台生成签名具体步骤)

    public class PayCommonUtil { //定义签名,微信根据参数字段的ASCII码值进行排序 加密签名,故使用SortMap进行参数排序 public static String ...

  4. 支付宝APP支付(基于Java实现支付宝APP支付)

    贴一下支付核心代码,以供后续参考: 业务层 import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; ...

  5. 支付宝APP支付(Java后台生成签名具体步骤)

    /** *支付宝支付 * @param orderId 订单编号 * @param actualPay 实际支付金额 * @return */ private String getOrderInfoB ...

  6. JAVA支付宝和微信(APP支付,提现,退款)

    公共参数图表:       接口 需要参数 通知方式 支付宝APP支付 应用公钥,应用私钥 异步 支付宝APP提现 应用公钥,应用私钥,支付宝公钥 同步 支付宝APP退款 应用公钥,应用私钥,支付宝公 ...

  7. Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝支付)

    最近一直在接触第三方,刚接入完支付宝的API做一下总结,个人能力薄弱有不对的地方望指教.  做的是一个小型电商项目,所以会接入第三方的支付和登入功能, 第一次接入第三方撸了很多官方文档. 进入主题, ...

  8. 微信支付(公众号支付APIJS、app支付)服务端统一下单接口java版

    一.微信公众号支付APIJS: 要完整的实现微信支付功能,需要前后端一起实现,还需要微信商户平台的配置.这里只是涉及服务端的代码. jar包:pom.xml <!-- ↓↓↓↓↓↓↓↓ 支付相关 ...

  9. 支付宝app支付java后台流程、原理分析(含nei wang chuan tou)

    java版支付宝app支付流程及原理分析 本实例是基于springmvc框架编写     一.流程步骤         1.执行流程           当手机端app(就是你公司开发的app)在支付 ...

随机推荐

  1. macbook pro 2016 2017 15寸 雷电3 外接显卡 epu 简单教程(不修改UEFI)

    雷电3外接显卡效果还不错,但是除了akitio node 其他厂家并不会维护自己的固件来适配新机型,我自己买的mbp 2016 15''就出现了和AORUS Gaming Box 1070不兼容的问题 ...

  2. 安装ale_python_interface时遇到make错误

    1. 首先按照https://pypi.org/project/ale-python-interface/0.0.1/来安装,直接python3 -m pip 但提示缺少一个头文件ale_c_wrap ...

  3. MQ中将消息发送至远程队列的配置

    MQ中将消息发送至远程队列的配置 摘自MQ资源管理器帮助文档V7 在开始学习本教程之前,您需要从系统管理员处了解标识网络上接收机器的名称:IP地址.MQ的端口号.队列管理器.接收(远程机器)或者是发送 ...

  4. Powershell split file

    #网上所得非原创 function split($inFile, $outPrefix, [Int32] $bufSize){ $stream = [System.IO.File]::OpenRead ...

  5. 解决vuex requires a Promise polyfill in this browser问题

    造成这种现象的原因归根究底就是浏览器对ES6中的promise无法支持,因此需要通过引入babel-polyfill来是我们的浏览器正常使用es6的功能 首先通过npm来安装: npm install ...

  6. 二十、在Intellij IDEA中使用Debug

    Debug用来追踪代码的运行流程,通常在程序运行过程中出现异常,启用Debug模式可以分析定位异常发生的位置,以及在运行过程中参数的变化.通常我们也可以启用Debug模式来跟踪代码的运行流程去学习三方 ...

  7. java基本方法

    Java 方法 在前面几个章节中我们经常使用到 System.out.println(),那么它是什么呢? println() 是一个方法. System 是系统类. out 是标准输出对象. 这句话 ...

  8. .NET 中 如果一个Task A正在await另一个Task B,那么Task A是什么状态

    新建一个.NET Core控制台程序,输入如下代码: using System; using System.Threading; using System.Threading.Tasks; class ...

  9. EF Core如何输出日志到Visual Studio的输出窗口

    我们在使用EF Core的时候,很多时候需要在Visual Studio的输出窗口中知道EF Core在后台生成的SQL语句是什么,这个需求可以通过自定义EF Core的ILoggerFactory和 ...

  10. 系统优化怎么做-Tomcat优化

    大家好,这里是「聊聊系统优化 」,并在下列地址同步更新 博客园:http://www.cnblogs.com/changsong/ 知乎专栏:https://zhuanlan.zhihu.com/yo ...