# 微信支付
## pom包
```xml
weixin-java-pay
```
## 配置
```yam
#微信配置
wx:
pay:
appid: ************** #公众账号ID
mchId: ************** #商户号
key: ************** #商户号的支付key
keyPath: C:UsersadminDesktopapiclient_cert.p12 #微信支付证书(退款、取消订单 时需要)
notifyUrl: https:/******
@ConfigurationProperties(prefix = "wx.pay")
@Data
public class WxMaProperty {
private String appid;
private String mchId;
private String notifyUrl;
private String refundUrl;
private String key;
private String keyPath;
}
```
配置文件
~~~java
package com.zt.edu.userapi.weChat.config;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxMaProperty.class)
public class WxPayConfiguration {
@Resource
WxMaProperty wxMaProperty;
private static Map
private String defaultAppid=null;
@PostConstruct
public void init() {
//1、赋值wxPayServices
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(StringUtils.trimTonull(wxMaProperty.getAppid()));
payConfig.setMchId(StringUtils.trimTonull(wxMaProperty.getMchId()));
payConfig.setMchKey(StringUtils.trimTonull(wxMaProperty.getKey()));
payConfig.setKeyPath(StringUtils.trimTonull(wxMaProperty.getKeyPath()));
// 可以指定是否使用沙箱环境
payConfig.setUseSandboxEnv(false);
WxPayService wxPayService = new WxPayServiceImpl();
wxPayService.setConfig(payConfig);
wxPayServices.put(wxMaProperty.getAppid(),wxPayService);
}
public WxPayService getMaService(String appid) {
//1、如果appid为空,默认首个公众号appid
if(appid==null){
appid=defaultAppid;
}
//2、路由
WxPayService wxService = wxPayServices.get(appid);
if (wxService == null) {
throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
}
return wxService;
}
}
~~~
## 示例
~~~java
package com.zt.edu.userapi.weChat.service.impl;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
import com.zt.edu.userapi.dto.ZtbOrderDTO;
import com.zt.edu.userapi.service.ZtbPayResultService;
import com.zt.edu.userapi.weChat.config.WxMaProperty;
import com.zt.edu.userapi.weChat.config.WxPayConfiguration;
import com.zt.edu.userapi.weChat.service.WeChatPayService;
import com.zt.edu.userapi.weChat.util.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
@Service
@Slf4j
public class WeChatPayServiceImpl implements WeChatPayService {
@Resource
private WxMaProperty wxMaProperty;
@Resource
private WxPayConfiguration wxPayConfiguration;
@Resource
private ZtbPayResultService ztbPayResultService;
@Override
public String unifiedOrder(ZtbOrderDTO orderDTO) throws Exception {
String spbillCreateIp = WXPayUtil.getLocalIp();
WxPayUnifiedOrderRequest orderRequestequest = WxPayUnifiedOrderRequest.newBuilder()
.body(orderDTO.getCourseName())//订单名称
.outTradeNo(orderDTO.getOrderNo())//商户的订单号
.totalFee(orderDTO.getPrice().multiply(new BigDecimal("100")).intValue())//需要支付的金额(单位:分)
.spbillCreateIp(spbillCreateIp)//APP和网页支付提交用户端ip
.notifyUrl(wxMaProperty.getNotifyUrl())//支付结果回调地址
.tradeType("NATIVE")//支付类型:JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付
.productId(String.valueOf(orderDTO.getId()))//支付的商品id(商户自定义)
.build();
//获取指定appId的WxPayService(com.github.binarywang.wxpay.service.WxPayService)调用统一下单
WxPayUnifiedOrderResult result = wxPayConfiguration.getMaService(wxMaProperty.getAppid()).unifiedOrder(orderRequestequest);
return result.getCodeURL();
}
}
@Resource private WxMaProperty wxMaProperty;
public WxPayService getMaService(String appid) {
//1、如果appid为空,默认首个公众号appid
if(appid==null){
appid=defaultAppid;
}
//2、路由
WxPayService wxService = wxPayServices.get(appid);
if (wxService == null) {
throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
}
return wxService;
}
统一下单后生成二维码
package com.zt.edu.userapi.util;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
public class QRCodeUtil {
public static void createQrCode(HttpServletResponse response,String codeUrl) {
try {
//生成二维码配置
Map hints = new HashMap<>();
//设置纠错等级
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
//设置编码类型
hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
//构造图片对象
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE,400,400,hints);
//输出流
OutputStream out = response.getOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix,"png",out);
} catch (Exception e) {
e.printStackTrace();
}
}
}
微信回调
代码示例
@RequestMapping("/payNotifywx")
public String payNotifywx(@RequestBody String xmlData) throws Exception {
return weChatPayService.payNotifywx(xmlData);
}
@Override
@Transactional
public String payNotifywx(String xmlData) throws Exception {
log.info("PayController parseOrderNotifyResult xmldata:{}", xmlData);
//记录返回结果
ztbPayResultService.savePayResult(xmlData, PayAisleEnum.WE_CHAT.getCode(),0);
WxPayOrderNotifyResult notifyResult = wxPayConfiguration.getMaService(wxMaProperty.getAppid()).parseOrderNotifyResult(xmlData);
if (WxPayConstants.ResultCode.SUCCESS.equals(notifyResult.getReturnCode())
&& WxPayConstants.ResultCode.SUCCESS.equals(notifyResult.getResultCode())){
//生成支付信息
// 处理自己的业务逻辑
}
//通知微信订单处理成功
return WxPayNotifyResponse.success("成功");
}



