微信支付
pom包
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>4.0.0</version>
</dependency>
配置
#微信配置
wx:
pay:
appid: ************** #公众账号ID
mchId: ************** #商户号
key: ************** #商户号的支付key
keyPath: C:\Users\admin\Desktop\apiclient_cert.p12 #微信支付证书(退款、关闭订单 时需要)
notifyUrl: https://**************/***/*** #支付通知地址(必须是外网可以访问的地址)
refundUrl: https://**************/***/*** #退款通知地址(必须是外网可以访问的地址)
配置文件
获取配置
package com.zt.edu.userapi.weChat.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@ConfigurationProperties(prefix = "wx.pay")
@Data
public class WxMaProperty {
/**
* 公众账号ID
*/
private String appid;
/**
* 设置微信小程序的Secret
*/
private String mchId;
/**
* 支付通知地址
*/
private String notifyUrl;
/**
* 退款通知地址
*/
private String refundUrl;
/**
* 支付key
*/
private String key;
/**
* 支付key
*/
private String keyPath;
}
配置文件
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;
/**
* @author ybwei
* @Description 支付配置
* @date 2021/3/22 14:09
**/
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxMaProperty.class)
public class WxPayConfiguration {
@Resource
WxMaProperty wxMaProperty;
private static Map<String, WxPayService> wxPayServices = new HashMap<>();
/**
* @Description 默认公众号appid
* @author: ybwei
* @Date: 2021/3/22 15:17
*/
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);
}
/**
* @Description 根据appid获取WxPayService
* @Author ybwei
* @Date 2021/3/22 15:01
* @Param [appid]
* @Return com.github.binarywang.wxpay.service.WxPayService
* @Exception
*/
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;
}
}
路径转二维码(扫码支付需要)
pom
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
工具类
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 {
/**
*
* @param response
* @param codeUrl 需要转二维码的URL
*/
public static void createQrCode(HttpServletResponse response,String codeUrl) {
try {
//生成二维码配置
Map<EncodeHintType,Object> 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();
}
}
}
示例
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;
/**
* 统一下单
* @return
* @throws Exception
*/
@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();
}
/**
* 支付回调
* @param xmlData
*/
@Override
@Transactional
public String payNotifywx(String xmlData) throws Exception {
log.info("PayController parseOrderNotifyResult xmlData:{}", xmlData);
//返回结果
WxPayOrderNotifyResult notifyResult = wxPayConfiguration.getMaService(wxMaProperty.getAppid()).parseOrderNotifyResult(xmlData);
//处理订单业务
//通知微信订单处理成功
return WxPayNotifyResponse.success("成功");
}
}
回调的controller接口
@RequestMapping("/payNotifywx")
public String payNotifywx(@RequestBody String xmlData) throws Exception {
return weChatPayService.payNotifywx(xmlData);
}