内容来自:https://www.jianshu.com/p/0a0ccc15cb80

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

    <dependency><groupId>com.github.binarywang</groupId><artifactId>weixin-java-pay</artifactId><version>3.0.0</version></dependency>

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

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

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

keyPath: classpath:证书名

还需要准备两个配置文件

WechatPayConfig 文件

import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;/*** @author Gentle* @date 2019/05/05* 微信支付信息注入bean 中*/
@Component
public class WeChatPayConfig {@Autowiredprivate WeChatPayProperties properties;@Bean@ConditionalOnMissingBeanpublic WxPayConfig payConfig() {WxPayConfig payConfig = new WxPayConfig();payConfig.setAppId(this.properties.getAppId());payConfig.setMchId(this.properties.getMchId());payConfig.setMchKey(this.properties.getMchKey());payConfig.setKeyPath(this.properties.getKeyPath());payConfig.setTradeType(this.properties.getTradeType());payConfig.setNotifyUrl(this.properties.getNotifyUrl());return payConfig;}@Beanpublic WxPayService wxPayService(WxPayConfig payConfig) {WxPayService wxPayService = new WxPayServiceImpl();wxPayService.setConfig(payConfig);return wxPayService;}
}

微信支付接口的 Controller

import com.gentle.config.WeChatPayProperties;
import com.gentle.entity.ReturnPayInfoVO;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.util.SignUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;/*** @author : Gentle* @date : 2019/5/17 12:11* @description:*/
@RestController
@RequestMapping(value = "/api/client/pay/")
public class WeChatPayController {@Autowiredprivate WxPayService wxPayService;@AutowiredWeChatPayProperties weChatPayProperties;/*** 此处处理订单信息,构建订单数据。** 将构建好的支付参数返回到前端,前端调起微信支付* @return*/@GetMapping(value = "weChatPay")public ReturnPayInfoVO weChatPay() {/*** 处理内部业务,校验订单等*/final WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = WxPayUnifiedOrderRequest.newBuilder()//调起支付的人的 openId.openid("openId")//订单编号.outTradeNo("我们系统内部订单号")//订单金额.totalFee(yuanToFee(new BigDecimal(100)))//商品描述.body("订单信息")//获取本地IP.spbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress())//回调的 URL 地址.notifyUrl("http://我们的域名/api/client/pay/weChatPayNotify").build();WxPayUnifiedOrderResult wxPayUnifiedOrderResult =null;try {wxPayUnifiedOrderResult = wxPayService.unifiedOrder(wxPayUnifiedOrderRequest);} catch (WxPayException e) {e.printStackTrace();throw new RuntimeException("微信支付调起失败!");}//组合参数构建支付Map<String, String> paySignInfo = new HashMap<>(5);String timeStamp = createTimestamp();String nonceStr = String.valueOf(System.currentTimeMillis());paySignInfo.put("appId", weChatPayProperties.getAppId());paySignInfo.put("nonceStr", nonceStr);paySignInfo.put("timeStamp", timeStamp);paySignInfo.put("signType", "MD5");paySignInfo.put("package", "prepay_id=" + wxPayUnifiedOrderResult.getPrepayId());String paySign = SignUtils.createSign(paySignInfo, "MD5", weChatPayProperties.getMchKey(), false);//组合支付参数ReturnPayInfoVO returnPayInfoVO = new ReturnPayInfoVO();returnPayInfoVO.setAppId(weChatPayProperties.getAppId());returnPayInfoVO.setNonceStr(nonceStr);returnPayInfoVO.setPaySign(paySign);returnPayInfoVO.setSignType("MD5");returnPayInfoVO.setPrepayId(wxPayUnifiedOrderResult.getPrepayId());returnPayInfoVO.setTimeStamp(timeStamp);return returnPayInfoVO;}/**** @param xmlData 微信返回的流* @return*/@RequestMapping(value = "weChatPayNotify",method = {RequestMethod.GET,RequestMethod.POST})public String weChatNotify(@RequestBody String xmlData){try {final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);//这里是存储我们发起支付时订单号的信息,所以取出来notifyResult.getOutTradeNo();/*** 系统内部业务,修改订单状态之类的*///成功后回调微信信息return WxPayNotifyResponse.success("回调成功!");} catch (WxPayException e) {e.printStackTrace();return WxPayNotifyResponse.fail("回调有误!");}}/*** 1 块钱转为 100 分* 元转分** @param bigDecimal 钱数目* @return 分*/private int yuanToFee(BigDecimal bigDecimal) {return bigDecimal.multiply(new BigDecimal(100)).intValue();}/*** 时间** @return 时间戳*/private String createTimestamp() {return Long.toString(System.currentTimeMillis() / 1000);}
}

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

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

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.math.BigDecimal;/*** @author : Gentle* @date : 2019/5/17 12:38* @description:*/
@RestController
@RequestMapping(value = "/api/client/refund/")
@Slf4j
public class WeChatRefundController {private static final String REFUND_SUCCESS = "SUCCESS";@Autowiredprivate WxPayService wxPayService;@PostMapping(value = "weChatRefund")public String refund() {//申请退款WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()//订单号.outTradeNo("自己系统订单号")//退款订单号.outRefundNo("自己系统订单号")//金额.totalFee(yuanToFee(new BigDecimal(100)))//退款金额.refundFee(yuanToFee(new BigDecimal(100)))//todo 回调地址.notifyUrl("http://我们系统的域名/api/client/refund/refundNotify").build();WxPayRefundResult wxPayRefundResult;try {wxPayRefundResult = wxPayService.refund(refundInfo);//判断退款信息是否正确if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode())&& REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode())) {/*** 系统内部业务逻辑*/return "正在退款中。。";}} catch (WxPayException e) {log.error("微信退款接口错误信息= {}", e);}return "退款失败";}/*** 仅支持一次性退款,多次退款需要修改逻辑* @param xmlData 微信返回的流数据* @return*/@RequestMapping(value = "refundNotify",method = {RequestMethod.GET,RequestMethod.POST})public String refundNotify(@RequestBody String xmlData) {WxPayRefundNotifyResult wxPayRefundNotifyResult;try {wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);} catch (WxPayException e) {log.error("退款失败,失败信息:{}", e);return WxPayNotifyResponse.fail("退款失败");}//判断你返回状态信息是否正确if (REFUND_SUCCESS.equals(wxPayRefundNotifyResult.getReturnCode())) {WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();//判断退款状态if (REFUND_SUCCESS.equals(reqInfo.getRefundStatus())) {//内部订单号String outTradeNo = reqInfo.getOutTradeNo();/*** 一、可能会重复回调,需要做防重判断* 二、处理我们系统内部业务,做修改订单状态,释放资源等!*/return WxPayNotifyResponse.success("退款成功!");}}return WxPayNotifyResponse.fail("回调有误!");}/*** 1 块钱转为 100 分* 元转分** @param bigDecimal 钱数目* @return 分*/private int yuanToFee(BigDecimal bigDecimal) {return bigDecimal.multiply(new BigDecimal(100)).intValue();}/*** 时间** @return 时间戳*/private String createTimestamp() {return Long.toString(System.currentTimeMillis() / 1000);}
}

案例相关代码已经发布到 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

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

作者:LuckToMeetDian叶
链接:https://www.jianshu.com/p/0a0ccc15cb80
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

weixin-java-pay实现公众号微信支付与退款相关推荐

  1. 公众号微信支付开发手记

    作者:wallimn 时间:2017-02-27 本人原创,欢迎转载,转载请保留本文链接.本文地址:http://wallimn.iteye.com/blog/2359379 花了两天时间,琢磨了一下 ...

  2. php 公众号微信支付流程,微信公众号支付完整流程案例

    简介 微信公众号支付,顾名思义就是必须在微信中实现支付,并且需要公众号配合. 教程 由于我们使用的是第三方封装好的接口,这里省去了我们自己配置公众号.为什么用第三方?因为个人没有申请权限. 交互细节: ...

  3. Vue公众号微信支付

    需要获取的支付信息: openid.attach(备注).body(支付标题).out_trade_no(订单号).total_fee(订单价格,单位分,100是一元).goods_tag(订单类型) ...

  4. uniapp公众号微信支付

    1.安装jssdk npm install jweixin-module --save 2.调用 <template><viewstyle="width: 100%;hei ...

  5. 微信sdk 公众号 微信支付 NFC 坑笔记

    微信sdk--微信支付--NFC项目 坑&笔记 微信公众号开发的环境配置 准备工作 & 微信公众平台配置 & 环境配置 微信的登录流程(即授权机制)遵循OAuth2.0标准,实 ...

  6. 公众号微信支付ios和android,uni-app微信公众号支付和分享,特别是ios下的配置,完美解决...

    一.支付 由于在ios中uni-app发布的应用是单应用,不管访问哪个页面,始终记录的是首次进来的那个页面. 这样的话,在微信支付签名时会报签名不对的错误.怎么解决? 老王的解决方案是在main.js ...

  7. 公众号微信支付ios和android,【微信支付】

    跳转到还款小程序 var extraData = { appid:wxcbda96de0b165486, sub_appid:wxcbda96de0b165482, mch_id:1900009231 ...

  8. 大商创微信公众号微信支付失败报错

    支付失败链接 支付失败 https://XXX/mobile/onlinepay/index/index/order_sn/2018042715565982911.html 支付成功 https:// ...

  9. java微信公众号JSAPI支付以及所遇到的坑

    java微信公众号JSAPI支付以及所遇到的坑 上周做了个支付宝微信扫码支付,今天总结一下.微信相比支付宝要麻烦许多 由于涉及到代理商,没办法,让我写个详细的申请流程,懵逼啊. 笔记地址 http:/ ...

最新文章

  1. J-Focus动画应用框架使用教程
  2. 不同浏览器前端调试查看返回页面的json数据
  3. linux chown 函数用噶,chown - Linux C 函数 使用手册
  4. Oracle经典教程学习笔记
  5. postman调用webservice接口_【分享】关于接口对前后端和测试的意义
  6. 多表查询中的一些概念
  7. java支持的数据类型有哪些_Java支持的数据类型有哪些?什么时候自动装拆箱?...
  8. 1-18Linux内核空间和用户空间
  9. Web框架——Flask系列之Flask创建app对象 路由(十二)
  10. 博客园里如何防垃圾评论
  11. 设计模式系列 - 装饰器模式
  12. Quartus II 13.1的安装及使用
  13. App登录方式和测试重点总结
  14. 校园招聘的简历写作与面试技巧
  15. 【傻瓜教程】Ubuntu18.04LTS安装NVIDIA驱动详细完整过程
  16. 对几款网络抓包工具的评测
  17. 【uniapp | 微信小程序】注册和开发环境搭建
  18. 转-零死角玩转stm32-高级篇之SDIO(4bit + DMA、支持SDHC、带协议分析)
  19. struts中的redirect=true与redirect=false
  20. 域名解析的原理是什么?域名解析的流程是怎样的?

热门文章

  1. SolidWork的使用技巧总结
  2. linux 使用设备树点亮LED 实战
  3. 狼的故事11:以牙还牙
  4. 二、jQuery 选择器(超细)
  5. 视频剪辑学习笔记(1)
  6. vue 视频 时间进度条组件
  7. Vue + Element-ui 实现table表格 数据相同项合并
  8. ss3ex集成Beet记录日志
  9. 10年工作经验的程序猿年薪10万 多吗?
  10. 自制Java大学英语四级成绩计算器