微信支付退款 java_小黑式烂代码之微信APP支付 + 退款(JAVA实现)

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

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

cbe27d452075624c23b286d683d2951f.png

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

4025676fc8c68442db0af0b54fdcbc7a.png

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

782f10149e6ac8ebb9e472526e31237b.png

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

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

a559ad4c9d6d6550e9670f373a4b7100.png

71a4fb3f58781ba27668afbdcaddf2a0.png

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

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

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

fd30645f1be1f7d9ae659cc8476d7ae5.png

7ec58b2a2ddb812334cf8e7b68fa7812.png

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

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

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

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

e11b65b920ea1414683b83b16e730e67.png

对 你没看错,就这一个,这个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@Service6 public classWechatPayService {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{28LocalHttpClient.initMchKeyStore(MCH_ID, API_CLIENT_CERT_PATH);29}30

31 /**32 * @description:使用微信支付-APP支付方式-统一下单;

33 *@return支付参数,如果支付失败则返回null

34 *@author:Fanhaojian

35*/

36 publicMchPayApp orderAppPay(PayLog payLog) {37

38 Unifiedorder unifiedorder = newUnifiedorder();39

40 /**APPID*/

41unifiedorder.setAppid(APPID);42

43 /**商户号*/

44unifiedorder.setMch_id(MCH_ID);45

46 /**随机字符串*/

47 unifiedorder.setNonce_str(UUID.randomUUID().toString().replaceAll("-", ""));48

49 /**商品描述*/

50unifiedorder.setBody(payLog.getPayCode());51

52 /**商户订单号*/

53unifiedorder.setOut_trade_no(payLog.getPayCode());54

55 /**订单总金额*/

56 unifiedorder.setTotal_fee(payLog.getPayPrice().multiply(new BigDecimal(100)).intValue() + ""); //订单总金额,单位为分;

57

58 /**用户端请求IP地址*/

59unifiedorder.setSpbill_create_ip(IpUtils.getClientIp());60

61 /**异步通知回调地址*/

62unifiedorder.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 returnPayUtil.generateMchAppData(unifiedorderResult.getPrepay_id(), APPID, MCH_ID, PRIVATE_KEY);82}83 return null;84}85

86 /**87 * @description:微信退款业务封装(支付押金退还);

88 *@paramPayLog order:支付订单信息

89 * Double refundAmount:退款金额

90 *@return微信退款接口返回数据 true 退款成功 false 退款失败

91 *@author:FanHaoJian

92*/

93 publicBoolean refundOrder(PayLog order, Double refundAmount) {94

95 //调用微信支付退款接口;

96 SecapiPayRefund payRefund = newSecapiPayRefund();97payRefund.setAppid(APPID);98payRefund.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 returnBoolean.TRUE;119}120}121

122 returnBoolean.FALSE;123}124 }

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

17a047ba05f70cb146174c7b35a7ce4d.png

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

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

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

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

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

1 /**

2 * @description:微信支付异步通知请求URL3 *@author:小黑4 */

5 public class WechatOrderNotify extendsActionSupport {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 privateString xml;14

15 @Override16 public String wechatOrderNotify() throwsException {17

18 //解析微信支付异步通知请求参数;

19 HttpServletRequest request =ServletActionContext.getRequest();20 String xml = StreamUtils.copyToString(request.getInputStream(), Charset.forName("utf-8"));21 Map 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 = newMchBaseResult();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 = newMchBaseResult();68 baseResult.setReturn_code("SUCCESS");69 baseResult.setReturn_msg("OK");70 xml =XMLConverUtil.convertToXML(baseResult);71

72 /**支付失败*/

73 }else{74 MchBaseResult baseResult = newMchBaseResult();75 baseResult.setReturn_code("FAIL");76 baseResult.setReturn_msg("FAIL");77 xml =XMLConverUtil.convertToXML(baseResult);78 }79

80 /**支付失败*/

81 }else{82 MchBaseResult baseResult = newMchBaseResult();83 baseResult.setReturn_code("FAIL");84 baseResult.setReturn_msg("FAIL");85 xml =XMLConverUtil.convertToXML(baseResult);86 }87 LOGGER.warn("微信支付--APP支付方式支付用户订单异步通知返回数据:" +xml);88 returnResults.XML;89 }90

91 publicString getXml() {92 returnxml;93 }94

95 public voidsetXml(String xml) {96 this.xml =xml;97 }98 }

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

fc565ec89f661d29da94fb8180c9e903.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值