赞
踩
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: #微信公众号或者小程序等的appid
- mchId: #微信支付商户号
- 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 {
- @Autowired
- private WeChatPayProperties properties;
-
- @Bean
- @ConditionalOnMissingBean
- public 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;
- }
- @Bean
- public WxPayService wxPayService(WxPayConfig payConfig) {
- WxPayService wxPayService = new WxPayServiceImpl();
- wxPayService.setConfig(payConfig);
- return wxPayService;
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
微信支付接口的 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 {
-
- @Autowired
- private WxPayService wxPayService;
- @Autowired
- WeChatPayProperties 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);
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
上述代码便是位置支付的调起信息和支付成功后回调的处理逻辑了,可以对代码进行适当的修改,便可使用。
微信退款实现:
以下便是微信退款的实现,代码也相对简单,修改以下便可使用,当然要各种参数校验等,否则可能会出现被人恶意调起的可能
- 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";
-
- @Autowired
- private 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);
- }
- }
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
案例相关代码已经发布到 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
总结:
上述便是微信支付和微信退款的实现!代码不难,只是开发资质倒是个问题。如果有资质的话,那这篇文章可能给到您一些帮助。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。