当前位置:   article > 正文

weixin-java-pay实现公众号微信支付与退款_weixin java pay

weixin java pay

pom.xml 文件
需要在 pom.xml 加入以下依赖!

  1. <dependency>
  2. <groupId>com.github.binarywang</groupId>
  3. <artifactId>weixin-java-pay</artifactId>
  4. <version>3.0.0</version>
  5. </dependency>

application.yml 文件
将 application.yml 中修改自己商户平台的信息,以下 keyPath 是证书,可以在微信支付后台下载,指定相关目录即可。

  1. wx:
  2. pay:
  3. appId: #微信公众号或者小程序等的appid
  4. mchId: #微信支付商户号
  5. mchKey: #微信支付商户密钥
  6. keyPath: # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
  7. tradeType: JSAPI #JSAPI--公众号支付 NATIVE--原生扫码支付 APP--app支付

假设我们将证书放到 resources 目录下,那写成以下形式即可。

keyPath: classpath:证书名

还需要准备两个配置文件

WechatPayConfig 文件

  1. import com.github.binarywang.wxpay.config.WxPayConfig;
  2. import com.github.binarywang.wxpay.service.WxPayService;
  3. import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.stereotype.Component;
  8. /**
  9. * @author Gentle
  10. * @date 2019/05/05
  11. * 微信支付信息注入bean 中
  12. */
  13. @Component
  14. public class WeChatPayConfig {
  15. @Autowired
  16. private WeChatPayProperties properties;
  17. @Bean
  18. @ConditionalOnMissingBean
  19. public WxPayConfig payConfig() {
  20. WxPayConfig payConfig = new WxPayConfig();
  21. payConfig.setAppId(this.properties.getAppId());
  22. payConfig.setMchId(this.properties.getMchId());
  23. payConfig.setMchKey(this.properties.getMchKey());
  24. payConfig.setKeyPath(this.properties.getKeyPath());
  25. payConfig.setTradeType(this.properties.getTradeType());
  26. payConfig.setNotifyUrl(this.properties.getNotifyUrl());
  27. return payConfig;
  28. }
  29. @Bean
  30. public WxPayService wxPayService(WxPayConfig payConfig) {
  31. WxPayService wxPayService = new WxPayServiceImpl();
  32. wxPayService.setConfig(payConfig);
  33. return wxPayService;
  34. }
  35. }

微信支付接口的 Controller

  1. import com.gentle.config.WeChatPayProperties;
  2. import com.gentle.entity.ReturnPayInfoVO;
  3. import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
  4. import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
  5. import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
  6. import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
  7. import com.github.binarywang.wxpay.exception.WxPayException;
  8. import com.github.binarywang.wxpay.service.WxPayService;
  9. import com.github.binarywang.wxpay.util.SignUtils;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.web.bind.annotation.*;
  12. import java.math.BigDecimal;
  13. import java.net.InetAddress;
  14. import java.util.HashMap;
  15. import java.util.Map;
  16. /**
  17. * @author : Gentle
  18. * @date : 2019/5/17 12:11
  19. * @description:
  20. */
  21. @RestController
  22. @RequestMapping(value = "/api/client/pay/")
  23. public class WeChatPayController {
  24. @Autowired
  25. private WxPayService wxPayService;
  26. @Autowired
  27. WeChatPayProperties weChatPayProperties;
  28. /**
  29. * 此处处理订单信息,构建订单数据。
  30. *
  31. * 将构建好的支付参数返回到前端,前端调起微信支付
  32. * @return
  33. */
  34. @GetMapping(value = "weChatPay")
  35. public ReturnPayInfoVO weChatPay() {
  36. /**
  37. * 处理内部业务,校验订单等
  38. */
  39. final WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()
  40. //调起支付的人的 openId
  41. .openid("openId")
  42. //订单编号
  43. .outTradeNo("我们系统内部订单号")
  44. //订单金额
  45. .totalFee(yuanToFee(new BigDecimal(100)))
  46. //商品描述
  47. .body("订单信息")
  48. //获取本地IP
  49. .spbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress())
  50. //回调的 URL 地址
  51. .notifyUrl("http://我们的域名/api/client/pay/weChatPayNotify")
  52. .build();
  53. WxPayUnifiedOrderResult wxPayUnifiedOrderResult =null;
  54. try {
  55. wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);
  56. } catch (WxPayException e) {
  57. e.printStackTrace();
  58. throw new RuntimeException("微信支付调起失败!");
  59. }
  60. //组合参数构建支付
  61. Map<String, String> paySignInfo = new HashMap<>(5);
  62. String timeStamp = createTimestamp();
  63. String nonceStr = String.valueOf(System.currentTimeMillis());
  64. paySignInfo.put("appId", weChatPayProperties.getAppId());
  65. paySignInfo.put("nonceStr", nonceStr);
  66. paySignInfo.put("timeStamp", timeStamp);
  67. paySignInfo.put("signType", "MD5");
  68. paySignInfo.put("package", "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId());
  69. String paySign = SignUtils.createSign(paySignInfo, "MD5", weChatPayProperties.getMchKey(), false);
  70. //组合支付参数
  71. ReturnPayInfoVO returnPayInfoVO = new ReturnPayInfoVO();
  72. returnPayInfoVO.setAppId(weChatPayProperties.getAppId());
  73. returnPayInfoVO.setNonceStr(nonceStr);
  74. returnPayInfoVO.setPaySign(paySign);
  75. returnPayInfoVO.setSignType("MD5");
  76. returnPayInfoVO.setPrepayId(wxPayUnifiedOrderResult.getPrepayId());
  77. returnPayInfoVO.setTimeStamp(timeStamp);
  78. return returnPayInfoVO;
  79. }
  80. /**
  81. *
  82. * @param xmlData 微信返回的流
  83. * @return
  84. */
  85. @RequestMapping(value = "weChatPayNotify",method = {RequestMethod.GET,RequestMethod.POST})
  86. public String weChatNotify(@RequestBody String xmlData){
  87. try {
  88. final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);
  89. //这里是存储我们发起支付时订单号的信息,所以取出来
  90. notifyResult.getOutTradeNo();
  91. /**
  92. * 系统内部业务,修改订单状态之类的
  93. */
  94. //成功后回调微信信息
  95. return WxPayNotifyResponse.success("回调成功!");
  96. } catch (WxPayException e) {
  97. e.printStackTrace();
  98. return WxPayNotifyResponse.fail("回调有误!");
  99. }
  100. }
  101. /**
  102. * 1 块钱转为 100 分
  103. * 元转分
  104. *
  105. * @param bigDecimal 钱数目
  106. * @return 分
  107. */
  108. private int yuanToFee(BigDecimal bigDecimal) {
  109. return bigDecimal.multiply(new BigDecimal(100)).intValue();
  110. }
  111. /**
  112. * 时间
  113. *
  114. * @return 时间戳
  115. */
  116. private String createTimestamp() {
  117. return Long.toString(System.currentTimeMillis() / 1000);
  118. }
  119. }

上述代码便是位置支付的调起信息和支付成功后回调的处理逻辑了,可以对代码进行适当的修改,便可使用。

微信退款实现:
以下便是微信退款的实现,代码也相对简单,修改以下便可使用,当然要各种参数校验等,否则可能会出现被人恶意调起的可能

  1. import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
  2. import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
  3. import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
  4. import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
  5. import com.github.binarywang.wxpay.exception.WxPayException;
  6. import com.github.binarywang.wxpay.service.WxPayService;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.web.bind.annotation.*;
  10. import java.math.BigDecimal;
  11. /**
  12. * @author : Gentle
  13. * @date : 2019/5/17 12:38
  14. * @description:
  15. */
  16. @RestController
  17. @RequestMapping(value = "/api/client/refund/")
  18. @Slf4j
  19. public class WeChatRefundController {
  20. private static final String REFUND_SUCCESS = "SUCCESS";
  21. @Autowired
  22. private WxPayService wxPayService;
  23. @PostMapping(value = "weChatRefund")
  24. public String refund() {
  25. //申请退款
  26. WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()
  27. //订单号
  28. .outTradeNo("自己系统订单号")
  29. //退款订单号
  30. .outRefundNo("自己系统订单号")
  31. //金额
  32. .totalFee(yuanToFee(new BigDecimal(100)))
  33. //退款金额
  34. .refundFee(yuanToFee(new BigDecimal(100)))
  35. //todo 回调地址
  36. .notifyUrl("http://我们系统的域名/api/client/refund/refundNotify")
  37. .build();
  38. WxPayRefundResult wxPayRefundResult;
  39. try {
  40. wxPayRefundResult = wxPayService.refund(refundInfo);
  41. //判断退款信息是否正确
  42. if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())
  43. && REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {
  44. /**
  45. * 系统内部业务逻辑
  46. */
  47. return "正在退款中。。";
  48. }
  49. } catch (WxPayException e) {
  50. log.error("微信退款接口错误信息= {}", e);
  51. }
  52. return "退款失败";
  53. }
  54. /**
  55. * 仅支持一次性退款,多次退款需要修改逻辑
  56. * @param xmlData 微信返回的流数据
  57. * @return
  58. */
  59. @RequestMapping(value = "refundNotify",method = {RequestMethod.GET,RequestMethod.POST})
  60. public String refundNotify(@RequestBody String xmlData) {
  61. WxPayRefundNotifyResult wxPayRefundNotifyResult;
  62. try {
  63. wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);
  64. } catch (WxPayException e) {
  65. log.error("退款失败,失败信息:{}", e);
  66. return WxPayNotifyResponse.fail("退款失败");
  67. }
  68. //判断你返回状态信息是否正确
  69. if (REFUND_SUCCESS.equals(wxPayRefundNotifyResult.getReturnCode())) {
  70. WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();
  71. //判断退款状态
  72. if (REFUND_SUCCESS.equals(reqInfo.getRefundStatus())) {
  73. //内部订单号
  74. String outTradeNo = reqInfo.getOutTradeNo();
  75. /**
  76. * 一、可能会重复回调,需要做防重判断
  77. * 二、处理我们系统内部业务,做修改订单状态,释放资源等!
  78. */
  79. return WxPayNotifyResponse.success("退款成功!");
  80. }
  81. }
  82. return WxPayNotifyResponse.fail("回调有误!");
  83. }
  84. /**
  85. * 1 块钱转为 100 分
  86. * 元转分
  87. *
  88. * @param bigDecimal 钱数目
  89. * @return 分
  90. */
  91. private int yuanToFee(BigDecimal bigDecimal) {
  92. return bigDecimal.multiply(new BigDecimal(100)).intValue();
  93. }
  94. /**
  95. * 时间
  96. *
  97. * @return 时间戳
  98. */
  99. private String createTimestamp() {
  100. return Long.toString(System.currentTimeMillis() / 1000);
  101. }
  102. }

案例相关代码已经发布到 GitHub 和码云上,如有兴趣可以下载学习!
GitHub:
https://github.com/LuckyToMeet-Dian-N/WeChat-Demo/tree/master/wechat-pay-demo
码云:
https://gitee.com/reway_wen/WeChat-Demo/tree/master/wechat-pay-demo

总结:
上述便是微信支付和微信退款的实现!代码不难,只是开发资质倒是个问题。如果有资质的话,那这篇文章可能给到您一些帮助。

 

 

 

 

 

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/874180
推荐阅读
相关标签
  

闽ICP备14008679号