小程序微信支付
This commit is contained in:
@@ -10,6 +10,12 @@
|
|||||||
</server>
|
</server>
|
||||||
</servers>
|
</servers>
|
||||||
<mirrors>
|
<mirrors>
|
||||||
|
<mirror>
|
||||||
|
<id>alimaven</id>
|
||||||
|
<name>aliyun maven</name>
|
||||||
|
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||||
|
<mirrorOf>central</mirrorOf>
|
||||||
|
</mirror>
|
||||||
<mirror>
|
<mirror>
|
||||||
<id>nexus</id>
|
<id>nexus</id>
|
||||||
<name>collcollege</name>
|
<name>collcollege</name>
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.cool.store.dto.wx;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态下单参数
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ApiModel
|
||||||
|
public class PreOrderDTO {
|
||||||
|
/**
|
||||||
|
* 订单号(业务)
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("订单号")
|
||||||
|
private String outTradeNo;
|
||||||
|
/**
|
||||||
|
* 用户openId
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("用户openId")
|
||||||
|
private String wxOpenId;
|
||||||
|
/**
|
||||||
|
* 订单描述
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("订单描述")
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 订单总金额,单位为分
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("订单总金额")
|
||||||
|
private int total;
|
||||||
|
|
||||||
|
public PreOrderDTO(String outTradeNo, String wxOpenId, String description, int total) {
|
||||||
|
this.outTradeNo = outTradeNo;
|
||||||
|
this.wxOpenId = wxOpenId;
|
||||||
|
this.description = description;
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -109,6 +109,10 @@
|
|||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||||
|
<artifactId>wechatpay-java</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.cool.store.config.weixin;
|
||||||
|
|
||||||
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 微信支付证书自动更新配置
|
||||||
|
* @date 2024-03-13 14:28
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class WxPayAutoCertificateConfig {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WxPayConfig wxPayConfig;
|
||||||
|
/**
|
||||||
|
* 初始化商户配置
|
||||||
|
* 使用自动更新平台证书的RSA配置
|
||||||
|
* 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RSAAutoCertificateConfig rsaAutoCertificateConfig() {
|
||||||
|
RSAAutoCertificateConfig config = new RSAAutoCertificateConfig.Builder()
|
||||||
|
.merchantId(wxPayConfig.getMerchantId())
|
||||||
|
.privateKeyFromPath(wxPayConfig.getPrivateKeyPath())
|
||||||
|
.merchantSerialNumber(wxPayConfig.getMerchantSerialNumber())
|
||||||
|
.apiV3Key(wxPayConfig.getApiV3Key())
|
||||||
|
.build();
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.cool.store.config.weixin;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 微信支付配置类
|
||||||
|
* @date 2024-03-13 14:28
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "wx.pay")
|
||||||
|
public class WxPayConfig {
|
||||||
|
|
||||||
|
//mchid
|
||||||
|
private String merchantId;
|
||||||
|
/** 商户API私钥路径 */
|
||||||
|
private String privateKeyPath;
|
||||||
|
//商户证书序列号
|
||||||
|
private String merchantSerialNumber;
|
||||||
|
//商户APIv3密钥
|
||||||
|
private String apiV3Key;
|
||||||
|
//支付通知地址
|
||||||
|
private String payNotifyUrl;
|
||||||
|
//退款回调地址
|
||||||
|
private String backNotifyUrl;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package com.cool.store.service;
|
||||||
|
|
||||||
|
import com.cool.store.dto.wx.PreOrderDTO;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
|
||||||
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||||
|
import com.wechat.pay.java.service.refund.model.Refund;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付V3
|
||||||
|
*/
|
||||||
|
public interface WxPayService {
|
||||||
|
/**
|
||||||
|
* JSAPI下单
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
PrepayWithRequestPaymentResponse jsApiOrder(PreOrderDTO preOrderDTO);
|
||||||
|
/**
|
||||||
|
* 支付回调
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
ResponseEntity payNotify(HttpServletRequest request) throws IOException;
|
||||||
|
/**
|
||||||
|
* 根据商户订单号查询订单
|
||||||
|
*
|
||||||
|
* @param outTradeNo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Transaction queryOrderByOutTradeNo(String outTradeNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据支付订单号查询订单
|
||||||
|
*
|
||||||
|
* @param paymentNo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Transaction queryOrderByPaymentNo(String paymentNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请退款
|
||||||
|
* @param orderID
|
||||||
|
* @param outRefundNo
|
||||||
|
* @param backAmount
|
||||||
|
*/
|
||||||
|
void applyRefund(String orderID, String outRefundNo, BigDecimal backAmount);
|
||||||
|
|
||||||
|
ResponseEntity refundNotify(HttpServletRequest request) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取订单退款结果信息
|
||||||
|
* @param outRefundNo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Refund getRefundOrderInfo(String outRefundNo);
|
||||||
|
/**
|
||||||
|
* 关闭订单
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void closePay(String outTradeNo);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,273 @@
|
|||||||
|
package com.cool.store.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.cool.store.config.weixin.WxPayConfig;
|
||||||
|
import com.cool.store.dto.wx.PreOrderDTO;
|
||||||
|
import com.cool.store.service.WxPayService;
|
||||||
|
import com.cool.store.utils.HttpServletUtils;
|
||||||
|
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||||
|
import com.wechat.pay.java.core.exception.HttpException;
|
||||||
|
import com.wechat.pay.java.core.exception.MalformedMessageException;
|
||||||
|
import com.wechat.pay.java.core.exception.ServiceException;
|
||||||
|
import com.wechat.pay.java.core.exception.ValidationException;
|
||||||
|
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||||
|
import com.wechat.pay.java.core.notification.RequestParam;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.*;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
|
||||||
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||||
|
import com.wechat.pay.java.service.refund.RefundService;
|
||||||
|
import com.wechat.pay.java.service.refund.model.*;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付相关
|
||||||
|
* @author
|
||||||
|
* @date 2024-03-13 14:28
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class WxPayServiceImpl implements WxPayService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RSAAutoCertificateConfig rsaAutoCertificateConfig;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WxPayConfig wxPayConfig;
|
||||||
|
|
||||||
|
@Value("${weixin.appId}")
|
||||||
|
private String wxAppId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public PrepayWithRequestPaymentResponse jsApiOrder(PreOrderDTO order) {
|
||||||
|
log.info("微信预支付下单:{}", JSONObject.toJSONString(order));
|
||||||
|
//请求微信支付相关配置
|
||||||
|
PrepayWithRequestPaymentResponse response = new PrepayWithRequestPaymentResponse();
|
||||||
|
try {
|
||||||
|
PrepayRequest request = new PrepayRequest();
|
||||||
|
request.setAppid(wxAppId);
|
||||||
|
request.setMchid(wxPayConfig.getMerchantId());
|
||||||
|
request.setDescription(order.getDescription());
|
||||||
|
request.setOutTradeNo(order.getOutTradeNo());
|
||||||
|
request.setNotifyUrl(wxPayConfig.getPayNotifyUrl());
|
||||||
|
Amount amount = new Amount();
|
||||||
|
amount.setTotal(order.getTotal());
|
||||||
|
amount.setCurrency("CNY");
|
||||||
|
request.setAmount(amount);
|
||||||
|
Payer payer = new Payer();
|
||||||
|
payer.setOpenid(order.getWxOpenId());
|
||||||
|
request.setPayer(payer);
|
||||||
|
log.info("请求预支付下单,请求参数:{}", JSONObject.toJSONString(request));
|
||||||
|
// 调用预下单接口
|
||||||
|
response = getJsapiService().prepayWithRequestPayment(request);
|
||||||
|
log.info("订单【{}】发起预支付成功,返回信息:{}", order.getOutTradeNo(), response);
|
||||||
|
} catch (HttpException e) {
|
||||||
|
// 发送HTTP请求失败
|
||||||
|
log.error("微信下单发送HTTP请求失败,错误信息:{}", e.getHttpRequest());
|
||||||
|
} catch (ServiceException e) {
|
||||||
|
// 服务返回状态小于200或大于等于300,例如500
|
||||||
|
log.error("微信下单服务状态错误,错误信息:{}", e.getErrorMessage());
|
||||||
|
} catch (MalformedMessageException e) {
|
||||||
|
// 服务返回成功,返回体类型不合法,或者解析返回体失败
|
||||||
|
log.error("服务返回成功,返回体类型不合法,或者解析返回体失败,错误信息:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信回调
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
@Override
|
||||||
|
public ResponseEntity payNotify(HttpServletRequest request) throws IOException {
|
||||||
|
log.info("------收到支付通知------");
|
||||||
|
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(HttpServletUtils.getRequestBody(request))
|
||||||
|
.build();
|
||||||
|
// 初始化 NotificationParser
|
||||||
|
NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
|
||||||
|
// 以支付通知回调为例,验签、解密并转换成 Transaction
|
||||||
|
log.info("验签参数:{}", requestParam);
|
||||||
|
try {
|
||||||
|
// 验签、解密并转换成 Transaction(返回参数对象)
|
||||||
|
Transaction transaction = parser.parse(requestParam, Transaction.class);
|
||||||
|
log.info("验签成功!-支付回调结果:{}", JSON.toJSONString(transaction));
|
||||||
|
// TODO 处理你的业务逻辑
|
||||||
|
//修改订单前,建议主动请求微信查询订单是否支付成功,防止恶意post
|
||||||
|
|
||||||
|
//修改订单信息
|
||||||
|
// 处理成功,返回 200 OK 状态码
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).build();
|
||||||
|
} catch (ValidationException e) {
|
||||||
|
log.error("sign verification failed", e);
|
||||||
|
log.error("微信支付回调v3java失败=" + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Transaction queryOrderByOutTradeNo(String outTradeNo) {
|
||||||
|
QueryOrderByOutTradeNoRequest request = new QueryOrderByOutTradeNoRequest();
|
||||||
|
request.setMchid(wxPayConfig.getMerchantId());
|
||||||
|
request.setOutTradeNo(outTradeNo);
|
||||||
|
Transaction result = getJsapiService().queryOrderByOutTradeNo(request);
|
||||||
|
if (Transaction.TradeStateEnum.SUCCESS != result.getTradeState()) {
|
||||||
|
log.info("内部订单号【{}】,微信支付订单号【{}】支付未成功", result.getOutTradeNo(), result.getTransactionId());
|
||||||
|
}
|
||||||
|
// TODO 处理业务逻辑
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Transaction queryOrderByPaymentNo(String paymentNo) {
|
||||||
|
QueryOrderByIdRequest queryRequest = new QueryOrderByIdRequest();
|
||||||
|
queryRequest.setMchid(wxPayConfig.getMerchantId());
|
||||||
|
queryRequest.setTransactionId(paymentNo);
|
||||||
|
Transaction result = getJsapiService().queryOrderById(queryRequest);
|
||||||
|
if (Transaction.TradeStateEnum.SUCCESS != result.getTradeState()) {
|
||||||
|
log.info("内部订单号【{}】,微信支付订单号【{}】支付未成功", result.getOutTradeNo(), result.getTransactionId());
|
||||||
|
}
|
||||||
|
// TODO 处理业务逻辑
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请退款
|
||||||
|
* @param orderID
|
||||||
|
* @param outRefundNo
|
||||||
|
* @param backAmount
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void applyRefund(String orderID, String outRefundNo, BigDecimal backAmount) {
|
||||||
|
Transaction transaction = queryOrderByOutTradeNo(orderID);
|
||||||
|
CreateRequest request = new CreateRequest();
|
||||||
|
request.setTransactionId(transaction.getTransactionId());
|
||||||
|
request.setNotifyUrl(wxPayConfig.getBackNotifyUrl());
|
||||||
|
request.setOutTradeNo(transaction.getOutTradeNo());
|
||||||
|
request.setOutRefundNo(outRefundNo);
|
||||||
|
request.setReason("测试退款");
|
||||||
|
AmountReq amountReq = new AmountReq();
|
||||||
|
amountReq.setCurrency(transaction.getAmount().getCurrency());
|
||||||
|
amountReq.setTotal(Long.parseLong((transaction.getAmount().getTotal().toString())));
|
||||||
|
amountReq.setRefund((backAmount.multiply(new BigDecimal(100))).longValue());
|
||||||
|
request.setAmount(amountReq);
|
||||||
|
getRefundService().create(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResponseEntity refundNotify(HttpServletRequest request) throws IOException {
|
||||||
|
log.info("------收到退款回调通知------");
|
||||||
|
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(HttpServletUtils.getRequestBody(request))
|
||||||
|
.build();
|
||||||
|
// 如果已经初始化了 RSAAutoCertificateConfig,可以直接使用 config
|
||||||
|
// 初始化 NotificationParser
|
||||||
|
NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
|
||||||
|
log.info("验签参数:{}", requestParam);
|
||||||
|
try {
|
||||||
|
// 验签、解密并转换成 Refund
|
||||||
|
Refund refund = parser.parse(requestParam, Refund.class);
|
||||||
|
log.info("验签成功!-退款回调结果:{}", JSON.toJSONString(refund));
|
||||||
|
//记录日志信息
|
||||||
|
Status state = refund.getStatus();
|
||||||
|
String orderID = refund.getOutTradeNo();
|
||||||
|
String backID = refund.getOutRefundNo();
|
||||||
|
System.out.println("订单ID:" + orderID);
|
||||||
|
System.out.println("退款ID:" + backID);
|
||||||
|
if (state == Status.PROCESSING) {
|
||||||
|
//TODO------
|
||||||
|
//根据自己的需求处理相应的业务逻辑,异步
|
||||||
|
|
||||||
|
//通知微信回调成功
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).build();
|
||||||
|
} else if (state == Status.SUCCESS) {
|
||||||
|
//TODO------
|
||||||
|
//根据自己的需求处理相应的业务逻辑,异步
|
||||||
|
|
||||||
|
//通知微信回调成功
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).build();
|
||||||
|
} else {
|
||||||
|
System.out.println("微信回调失败,JsapiPayController.Refund:" + state.toString());
|
||||||
|
//通知微信回调失败
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
|
}
|
||||||
|
} catch (ValidationException e) {
|
||||||
|
log.error("sign verification failed", e);
|
||||||
|
log.error("微信支付回调v3java失败=" + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取订单退款结果信息
|
||||||
|
* @param outRefundNo
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Refund getRefundOrderInfo(String outRefundNo) {
|
||||||
|
QueryByOutRefundNoRequest request = new QueryByOutRefundNoRequest();
|
||||||
|
request.setOutRefundNo(outRefundNo);
|
||||||
|
// 调用request.setXxx(val)设置所需参数,具体参数可见Request定义
|
||||||
|
// 调用接口
|
||||||
|
return getRefundService().queryByOutRefundNo(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭微信支付
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void closePay(String outTradeNo) {
|
||||||
|
CloseOrderRequest closeRequest = new CloseOrderRequest();
|
||||||
|
closeRequest.setMchid(wxPayConfig.getMerchantId());
|
||||||
|
closeRequest.setOutTradeNo(outTradeNo);
|
||||||
|
getJsapiService().closeOrder(closeRequest);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 创建小程序支付服务
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected JsapiServiceExtension getJsapiService() {
|
||||||
|
JsapiServiceExtension jsapiServiceExtension =
|
||||||
|
new JsapiServiceExtension.Builder()
|
||||||
|
.config(rsaAutoCertificateConfig)
|
||||||
|
.signType("RSA") // 不填默认为RSA
|
||||||
|
.build();
|
||||||
|
return jsapiServiceExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected RefundService getRefundService() {
|
||||||
|
RefundService refundService = new RefundService.Builder()
|
||||||
|
.config(rsaAutoCertificateConfig)
|
||||||
|
.build();
|
||||||
|
return refundService;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.cool.store.utils;
|
||||||
|
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author
|
||||||
|
* @date 2023/07/26 上午9:17
|
||||||
|
**/
|
||||||
|
public class HttpServletUtils {
|
||||||
|
/**
|
||||||
|
* 获取请求体
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static String getRequestBody(HttpServletRequest request) throws IOException {
|
||||||
|
ServletInputStream stream = null;
|
||||||
|
BufferedReader reader = null;
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
try {
|
||||||
|
stream = request.getInputStream();
|
||||||
|
// 获取响应
|
||||||
|
reader = new BufferedReader(new InputStreamReader(stream));
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
sb.append(line);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IOException("读取返回支付接口数据流出现异常!");
|
||||||
|
} finally {
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,6 @@ import javax.annotation.Resource;
|
|||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zhangchenbiao
|
|
||||||
* @FileName: MiniProgramAppController
|
* @FileName: MiniProgramAppController
|
||||||
* @Description:
|
* @Description:
|
||||||
* @date 2023-05-29 14:28
|
* @date 2023-05-29 14:28
|
||||||
@@ -22,7 +21,7 @@ import javax.validation.Valid;
|
|||||||
|
|
||||||
@Api(tags = "微信小程序app接口")
|
@Api(tags = "微信小程序app接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping({"/v1/partnerManage/miniProgram" })
|
@RequestMapping({"/mini/miniProgram" })
|
||||||
public class MiniProgramAppController {
|
public class MiniProgramAppController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
package com.cool.store.controller.webc;
|
||||||
|
|
||||||
|
import com.cool.store.dto.wx.PreOrderDTO;
|
||||||
|
import com.cool.store.response.ResponseResult;
|
||||||
|
import com.cool.store.service.WxPayService;
|
||||||
|
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;
|
||||||
|
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||||
|
import com.wechat.pay.java.service.refund.model.Refund;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @FileName: WechatPayController
|
||||||
|
* @Description:
|
||||||
|
* @date 2024-03-13 14:28
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Api(tags = "微信小程序支付接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping({"/mini/wechatPay"})
|
||||||
|
public class WechatPayController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WxPayService wxPayService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "预支付订单", notes = "预支付订单")
|
||||||
|
@PostMapping("/create")
|
||||||
|
public ResponseResult<PrepayWithRequestPaymentResponse> createOrder(@Validated @RequestBody PreOrderDTO preOrderDTO) {
|
||||||
|
//创建初始化订单
|
||||||
|
PrepayWithRequestPaymentResponse response = wxPayService.jsApiOrder(preOrderDTO);
|
||||||
|
//更新订单状态
|
||||||
|
return ResponseResult.success(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("根据商户订单号查询订单")
|
||||||
|
@GetMapping("/queryOrderByOutTradeNo")
|
||||||
|
public ResponseResult<Transaction> queryOrderByOutTradeNo(@RequestParam(value = "outTradeNo",required = true)String outTradeNo) {
|
||||||
|
return ResponseResult.success(wxPayService.queryOrderByOutTradeNo(outTradeNo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("根据支付订单号查询订单")
|
||||||
|
@GetMapping("/queryOrderByOutTradeNo")
|
||||||
|
public ResponseResult<Transaction> queryOrderByPaymentNo(@RequestParam(value = "paymentNo",required = true)String paymentNo) {
|
||||||
|
return ResponseResult.success(wxPayService.queryOrderByPaymentNo(paymentNo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "预支付-回调")
|
||||||
|
@PostMapping("/payNotify")
|
||||||
|
public ResponseEntity payNotify(HttpServletRequest request) throws IOException {
|
||||||
|
ResponseEntity responseEntity = wxPayService.payNotify(request);
|
||||||
|
return responseEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "退款申请")
|
||||||
|
@PostMapping("/applyRefund")
|
||||||
|
public ResponseResult applyRefund(@RequestBody Map<String, Object> params){
|
||||||
|
String orderID = String.valueOf(params.get("orderID"));
|
||||||
|
String backID = String.valueOf(params.get("backID"));
|
||||||
|
BigDecimal backAmount = new BigDecimal(String.valueOf(params.get("backAmount")));
|
||||||
|
wxPayService.applyRefund(orderID, backID, backAmount);
|
||||||
|
return ResponseResult.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "退款回调")
|
||||||
|
@PostMapping("/refundNotify")
|
||||||
|
public ResponseEntity refundNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
|
ResponseEntity responseEntity = wxPayService.refundNotify(request);
|
||||||
|
return responseEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/getRefundOrderInfo")
|
||||||
|
@ApiOperation("退款查询")
|
||||||
|
public ResponseResult<Refund> getRefundOrderInfo(@RequestParam(value = "outRefundNo",required = true)String outRefundNo){
|
||||||
|
Refund refund = wxPayService.getRefundOrderInfo(outRefundNo);
|
||||||
|
return ResponseResult.success(refund);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -50,4 +50,11 @@ server.connection-timeout=18000000
|
|||||||
server.tomcat.basedir=/tmp/tomcat/partner-b
|
server.tomcat.basedir=/tmp/tomcat/partner-b
|
||||||
|
|
||||||
log4j2.formatMsgNoLookups=true
|
log4j2.formatMsgNoLookups=true
|
||||||
mybatis.configuration.variables.enterpriseId=e17cd2dc350541df8a8b0af9bd27f77d
|
mybatis.configuration.variables.enterpriseId=e17cd2dc350541df8a8b0af9bd27f77d
|
||||||
|
|
||||||
|
wx.pay.merchantId=1670560201
|
||||||
|
wx.pay.privateKeyPath=/home/admin/apiclient/apiclient_key.pem
|
||||||
|
wx.pay.merchantSerialNumber=66B8E966AFE796BA06006664FCBFBC3F0E2F5A1B
|
||||||
|
wx.pay.apiV3Key=wxpayzhenghu123JKJHkjafWXCertUt1
|
||||||
|
wx.pay.payNotifyUrl=https://abstore-api.coolstore.cn/xfsg/mini/wechatPay/payNotify
|
||||||
|
wx.pay.backNotifyUrl=https://abstore-api.coolstore.cn/xfsg/mini/wechatPay/backNotify
|
||||||
7
pom.xml
7
pom.xml
@@ -221,6 +221,13 @@
|
|||||||
<artifactId>logback-kafka-appender</artifactId>
|
<artifactId>logback-kafka-appender</artifactId>
|
||||||
<version>0.2.0-RC2</version>
|
<version>0.2.0-RC2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.wechatpay-apiv3</groupId>
|
||||||
|
<artifactId>wechatpay-java</artifactId>
|
||||||
|
<version>0.2.11</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user