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

其次我认为你先去看一看微信开发平台的文档!  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. July 04th 2017 Week 27th Tuesday

    Nothing is really beautiful but truth. 只有真理才是真美. Truth can be beautiful, but it also can be cruel. W ...

  2. MongoDB排序记录

    MongoDB sort()方法 要在MongoDB中排序文档,需要使用sort()方法. 该方法接受包含字段列表及其排序顺序的文档.使用指定排序顺序1和-1. 1用于升序,而-1用于降序. 语法 s ...

  3. Android(java)学习笔记208:Android下的属性动画高级用法(Property Animation)

    1. 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是最常用的一些用法,这些用法足以覆盖我们平时大多情况下的动画需求了.但是,正如上篇文章当中所说到的,属性动画对补间动画 ...

  4. SOJ3266 Birthday

    Time Limit: 1000MS Memory Limit: 65536 K Description Today is Windy's birthday. What can I say? Inpu ...

  5. 解决weblogic错误:java.sql.SQLRecoverableException: IO Error: Broken pipe

    首先说一下系统基础架构: 服务器:weblogic11g集群 数据库:oracle数据库Rac 出错信息: 1.java.sql.SQLRecoverableException: Closed Con ...

  6. Dropdownlist控件属性 OnSelectedIndexChanged方法不触发

    <asp:DropDownList ID="ddlWJLX" runat="server" OnSelectedIndexChanged="dd ...

  7. 记一次关于SSM框架的使用错误

    今天遇到一个十分操蛋的问题,最后发现是因为忘记在对应的Service上加上@AutoWired. 难怪单元测试没问题,因为单元测试中用到的Service,其实现类通过DAO自动装配了.也就是在对应的s ...

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

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

  9. 【题解】洛谷P1315 [NOIP2011TG] 观光公交(前缀和+贪心)

    次元传送门:洛谷P1315 思路 思路大概想到了 可是代码实现却没想到 所以参考题解了 D2T3的贪心果然有难度 我们考虑在每次用加速器有两种情况 到下一个点还需要等待:以后的时间就不再影响了 到下一 ...

  10. 智能指针 与 oc中的指针

     智能指针 与 oc中的指针 智能指针的原理及实现 当类中有指针成员时,一般有两种方式来管理指针成员:一是采用值型的方式管理,每个类对象都保留一份指针指向的对象的拷贝:另一种更优雅的方式是使用智能指针 ...