1. 微信支付接入官网:
可选择适合其接入方式,我们目前选择的是Native支付接入
2. 微信Native支付接入前准备:
主要准备好以下五种接入前的开发参数:
微信商户账号(mchid)
商户AppId
ApiV3秘钥(商户内自行设置的,并设置操作密码保存)
证书序列号
API证书压缩包中的文件apiclient_key.pem
3. 微信支付业务流程
4. 微信接入创建支付订单
PS:微信支付金额单位为分!!
引入微信支付sdk
<!--WeChat Pay SDK-->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-java</artifactId>
<version>0.2.9</version>
</dependency>
统一初始化RSAAutoCertificateConfig,value的值在对应的yml文件里进行配置即可
package com.geb.common.config;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Configuration
@Data
@Component
public class WxPayConfig {
private static volatile Config config;
/** 商户号 */
@Value("${wechat.pay.mchId}")
public String mchId;
/** 商户API私钥路径 */
@Value("${wechat.pay.privateKeyPath}")
public String privateKeyPath;
/** 商户证书序列号 */
@Value("${wechat.pay.merchantSerialNumber}")
public String merchantSerialNumber;
/** 商户APIV3密钥 */
@Value("${wechat.pay.apiV3key}")
public String apiV3key;
//SDK 提供的定时更新平台证书
@Bean
public Config getConfig(WxPayConfig wxPayConfig) {
if (config == null) {
config = new RSAAutoCertificateConfig.Builder()
.merchantId(mchId)
.privateKeyFromPath(privateKeyPath)
.merchantSerialNumber(merchantSerialNumber)
.apiV3Key(apiV3key)
.build();
}
return config;
}
}
创建支付订单-Service层方法
/** AppId */
@Value("${wechat.pay.appId}")
public String appId;
/** 商户号 */
@Value("${wechat.pay.mchId}")
public String mchId;
/** 支付回调地址 */
@Value("${wechat.callback.notifyUrl}")
private String notifyUrl;
@Autowired
private WxPayConfig wxPayConfig;
/**
* 创建订单 - wechat - 生成预支付订单code_url
* @param orderAddDto
* @return
*/
@Override
@Transactional
public OrderCreateVo createOrder(OrderAddDto orderAddDto){
// 创建订单
Order order = WrapperUtil.transform(orderAddDto, Order.class);
order.setOrderCode(generateOrderNumber());
order.setCreateTime(DateUtils.getNowDate());
order.setBuyBy(SecurityUtils.getLoginUser().getUser().getNickName());
order.setBuyId(SecurityUtils.getUserId());
order.setUserId(SecurityUtils.getUserId());
order.setPayStatus(PayStatusEnum.WAIT_PAY.getCode());
order.setChannel(PayChannelEnum.WECHART.getCode()); // 1微信 2支付宝
// 设置选择的时间
order.setDuration(orderAddDto.getDurationName().getExpBase());
BigDecimal cost = productService.calOrderCost(orderAddDto.getProductId().intValue(), String.valueOf(orderAddDto.getDurationName()), orderAddDto.getResourcePackageNum());
// BigDecimal cost = new BigDecimal("0.01");
order.setShouldAmount(cost);
this.save(order);
// 获取产品标题
WdProductEntity product = productMapper.selectById(orderAddDto.getProductId());
// 使用自动更新平台证书的RSA配置
Config config = wxPayConfig.getConfig(wxPayConfig);
// 构建service
NativePayService service = new NativePayService.Builder().config(config).build();
// 设置所需参数
PrepayRequest request = new PrepayRequest();
Amount amount = new Amount();
amount.setTotal((cost.multiply(new BigDecimal(100)).intValue())); // 微信支付用分来结算 记得 * 100
amount.setCurrency("CNY");
request.setAmount(amount);
request.setAppid(appId);
request.setMchid(mchId);
request.setDescription(product.getName());
request.setNotifyUrl(notifyUrl);
request.setOutTradeNo(order.getOrderCode());
/*// 微信二维码失效时间 4 分钟
Date date = new Date(new Date().getTime() + 4 * 60 * 1000);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
String expire = format.format(date);
request.setTimeExpire(expire);*/
PrepayResponse response = null;
try {
// 调用下单方法,得到应答
response = service.prepay(request);
// 使用微信扫描 code_url 对应的二维码,即可体验Native支付
System.out.println(response.getCodeUrl());
log.info("CreateOrder-PrePay code_url:{}", response.getCodeUrl());
}catch (Exception e){
System.out.println(e.getMessage());
}
// 设置返回订单信息
OrderCreateVo orderCreateVo = new OrderCreateVo();
orderCreateVo.setCodeUrl(response.getCodeUrl());
orderCreateVo.setOrderCode(order.getOrderCode());
orderCreateVo.setCompanyName(orderAddDto.getCompanyName());
orderCreateVo.setShouldAmount(order.getShouldAmount());
orderCreateVo.setExpireTime(orderAddDto.getExpireTime());
return orderCreateVo;
}
创建完订单后向微信发起创建预支付订单请求,然后会返回code_url,是二维码的url,前端用qrcode库转成待支付的二维码,然后用户进行扫码支付(二维码默认俩小时内有效)
5. 微信回调商户平台接口 -> 微信二维码扫码支付成功后
PS: 回调接口一定要域名备案的https的443端口哦~ 否则回调失败
/**
* 微信支付回调接口
* @param request
* @param response
* @return
*/
@Override
@Transactional
public String wxpayNotify(JSONObject body, HttpServletRequest request, HttpServletResponse response) throws IOException {
log.info("微信支付回调:body:{}, request:{}, response:{}", body, request, response);
// 获取请求体原内容(此时获取的数据是加密的)
BufferedReader reader = request.getReader();
StringBuilder requestBody = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
requestBody.append(line);
}
log.info("微信支付回调-requestBody:{}", requestBody);
// 构造 RequestParam
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(request.getHeader("wechatPay-Serial")) //证书序列号
.nonce(request.getHeader("wechatPay-Nonce")) // 随机字符串
.signature(request.getHeader("wechatPay-Signature")) // 签名
.timestamp(request.getHeader("wechatPay-Timestamp")) // 时间戳
.signType(request.getHeader("wechatPay-Signature-Type")) // 签名类型
.body(requestBody.toString()) // 请求体内容(原始内容,不要解析)
.build();
log.info("微信支付回调-requestData:requestParam:{}", requestParam);
//获取微信证书,没有的话重新构造一个
Config config = wxPayConfig.getConfig(wxPayConfig);
NotificationParser parser = new NotificationParser((NotificationConfig)config);
// 以支付通知回调为例,验签、解密并转换成 Transaction
Transaction transaction = parser.parse(requestParam, Transaction.class);
// 获取支付单号
log.info("支付成功,回调信息:{}", transaction);
// 打印其中的"微信支付单号"字段,可用于查单操作
log.info("微信支付单号:{}", transaction.getTransactionId());
// 获取微信支付回调状态
Transaction.TradeStateEnum tradeState = transaction.getTradeState();
log.info("微信Native支付回调状态 tradeState:{}", tradeState);
// 返回给微信回调信息成功与否
JSONObject json = new JSONObject();
if (tradeState == Transaction.TradeStateEnum.SUCCESS) {
// 业务逻辑代码
// 将微信返回的订单号参数信息传到Dao层,进行校验
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_code", transaction.getOutTradeNo());
Order order = wdOrderMapper.selectOne(queryWrapper);
log.info("微信支付回调-Order:order:{}", order);
// 订单待支付状态 - 更新订单信息
if(order.getPayStatus().equals(PayStatusEnum.WAIT_PAY.getCode())){
updateOrder(transaction, order);
// 更新权益状态
ProductDurationEnums productDurationEnums = null;
switch (order.getDuration()){
case 1 : productDurationEnums = ProductDurationEnums.ONE_MONTH; break;
case 3 : productDurationEnums = ProductDurationEnums.THREE_MONTH; break;
case 12 : productDurationEnums = ProductDurationEnums.TWELVE_MONTH; break;
case 14 : productDurationEnums = ProductDurationEnums.TWELVE_MONTH2; break;
}
productCompanyService.subscriptionProduct(order.getCompanyId(), order.getProductId().intValue(), order.getOrderCode(), productDurationEnums,order.getResourcePackageNum());
}
response.setStatus(200);
json.put("code", "SUCCESS");
json.put("message", "操作成功");
} else {
response.setStatus(400);
json.put("code", "FAIL");
json.put("message", "验签失败");
}
return json.toString();
}
以上就是接入微信Native支付的流程 申请好对应的相关信息后直接引入微信的sdk 有没有很方便!