持续完善业务逻辑
This commit is contained in:
parent
0fcd26552b
commit
991ab454f1
@ -1,4 +1,7 @@
|
||||
# 当前支付模块写的并不完善,请根据自己的业务需求进行修改
|
||||
# 回调地址使用的内网穿透http://e2vca6.natappfree.cc
|
||||
pay:
|
||||
# https://doc.shouqianba.com/zh-cn/
|
||||
sqb:
|
||||
enabled: false
|
||||
appId: "appId"
|
||||
@ -9,12 +12,14 @@ pay:
|
||||
vendorKey: "vendorKey"
|
||||
publicKey: classpath:pay/sqb/sqb_public_key.pem
|
||||
notifyUrl: http://e2vca6.natappfree.cc/pay/sqb/notify
|
||||
# https://opendocs.alipay.com/open/02np95
|
||||
alipay:
|
||||
enabled: false
|
||||
appId: appid
|
||||
appPrivateKey: classpath:pay/alipay/alipay_private_key.pem
|
||||
alipayPublicKey: classpath:pay/alipay/alipay_public_key.pem
|
||||
notifyUrl: http://e2vca6.natappfree.cc/alipay/notify
|
||||
# https://github.com/wechatpay-apiv3/wechatpay-java
|
||||
wechat:
|
||||
enabled: false
|
||||
appId: appid
|
||||
@ -22,5 +27,5 @@ pay:
|
||||
privateKeyPath: classpath:pay/wx/apiclient_key.pem
|
||||
merchantId: merchantId
|
||||
merchantSerialNumber: merchantSerialNumber
|
||||
# 回调地址,此处使用的内网穿透http://e2vca6.natappfree.cc
|
||||
|
||||
notifyUrl: http://e2vca6.natappfree.cc/pay/wechat/notify
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.ruoyi.auth.controller;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -16,13 +17,27 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.domain.model.LoginBody;
|
||||
import com.ruoyi.common.core.domain.model.RegisterBody;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/auth/<channel>") // dySms mail
|
||||
@RequestMapping("/auth/{channel}") // dySms mail
|
||||
public class TfaController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
@Autowired(required = false)
|
||||
Map<String, TfaService> tfaServiceMap;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (tfaServiceMap == null) {
|
||||
tfaServiceMap = new HashMap<>();
|
||||
logger.warn("请注意,没有加载任何双认证服务");
|
||||
} else {
|
||||
tfaServiceMap.forEach((k, v) -> {
|
||||
logger.info("已加载双认证服务 {}", k);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/send/bind")
|
||||
public AjaxResult send(@PathVariable String channel, @RequestBody LoginBody loginBody) {
|
||||
TfaService tfaService = tfaServiceMap.get(channel + "AuthService");
|
||||
|
@ -8,6 +8,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.alipay.easysdk.factory.Factory;
|
||||
import com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse;
|
||||
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.pay.alipay.service.IAliPayService;
|
||||
@ -63,14 +64,63 @@ public class AliPayService implements IAliPayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String query(PayOrder payOrder) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'query'");
|
||||
public PayOrder query(PayOrder payOrder) {
|
||||
try {
|
||||
// 使用支付宝SDK查询订单状态
|
||||
com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse response = Factory.Payment.Common()
|
||||
.query(payOrder.getOrderNumber());
|
||||
|
||||
// 根据查询结果更新订单状态
|
||||
if ("10000".equals(response.code)) {
|
||||
String tradeStatus = response.tradeStatus;
|
||||
String orderStatus = "";
|
||||
|
||||
// 根据支付宝交易状态映射到系统订单状态
|
||||
switch (tradeStatus) {
|
||||
case "TRADE_SUCCESS":
|
||||
case "TRADE_FINISHED":
|
||||
orderStatus = "已支付";
|
||||
break;
|
||||
case "WAIT_BUYER_PAY":
|
||||
orderStatus = "待支付";
|
||||
break;
|
||||
case "TRADE_CLOSED":
|
||||
orderStatus = "已关闭";
|
||||
break;
|
||||
default:
|
||||
orderStatus = "未知状态";
|
||||
}
|
||||
|
||||
// 更新订单信息
|
||||
payOrderService.updateStatus(payOrder.getOrderNumber(), orderStatus);
|
||||
} else {
|
||||
throw new ServiceException("查询支付宝订单失败:" + response.subMsg);
|
||||
}
|
||||
|
||||
return payOrder;
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("查询支付宝订单异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String refund(PayOrder payOrder) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'refund'");
|
||||
public PayOrder refund(PayOrder payOrder) {
|
||||
try {
|
||||
// 使用支付宝SDK进行退款
|
||||
AlipayTradeRefundResponse response = Factory.Payment.Common().refund(
|
||||
payOrder.getOrderNumber(),
|
||||
payOrder.getActualAmount());
|
||||
|
||||
// 处理退款结果
|
||||
if ("10000".equals(response.code)) {
|
||||
payOrderService.updateStatus(payOrder.getOrderNumber(), "已退款");
|
||||
} else {
|
||||
throw new ServiceException("支付宝退款失败:" + response.subMsg);
|
||||
}
|
||||
|
||||
return payOrder;
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("支付宝退款异常:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,15 @@ public class PayOrder extends BaseEntity {
|
||||
private Long orderId;
|
||||
|
||||
/** 订单号 */
|
||||
@Schema(title = "订单号")
|
||||
@Excel(name = "订单号")
|
||||
@Schema(title = "商户订单号")
|
||||
@Excel(name = "商户订单号")
|
||||
private String orderNumber;
|
||||
|
||||
/** 第三方订单号 */
|
||||
@Schema(title = "第三方订单号")
|
||||
@Excel(name = "第三方订单号")
|
||||
private String thirdNumber;
|
||||
|
||||
/** 订单状态 */
|
||||
@Schema(title = "订单状态")
|
||||
@Excel(name = "订单状态")
|
||||
@ -68,6 +73,14 @@ public class PayOrder extends BaseEntity {
|
||||
return orderNumber;
|
||||
}
|
||||
|
||||
public void setThirdNumber(String thirdNumber) {
|
||||
this.thirdNumber = thirdNumber;
|
||||
}
|
||||
|
||||
public String getThirdNumber() {
|
||||
return thirdNumber;
|
||||
}
|
||||
|
||||
public void setOrderStatus(String orderStatus) {
|
||||
this.orderStatus = orderStatus;
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ public interface PayService {
|
||||
|
||||
String notify(HttpServletRequest servletRequest, HttpServletResponse response);
|
||||
|
||||
String query(PayOrder payOrder);
|
||||
PayOrder query(PayOrder payOrder);
|
||||
|
||||
String refund(PayOrder payOrder);
|
||||
PayOrder refund(PayOrder payOrder);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<resultMap type="PayOrder" id="PayOrderResult">
|
||||
<result property="orderId" column="order_id" />
|
||||
<result property="orderNumber" column="order_number" />
|
||||
<result property="thirdNumber" column="third_number" />
|
||||
<result property="orderStatus" column="order_status" />
|
||||
<result property="totalAmount" column="total_amount" />
|
||||
<result property="actualAmount" column="actual_amount" />
|
||||
@ -27,6 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<include refid="selectPayOrderVo"/>
|
||||
<where>
|
||||
<if test="orderNumber != null and orderNumber != ''"> and order_number = #{orderNumber}</if>
|
||||
<if test="thirdNumber != null and thirdNumber != ''"> and third_number = #{thirdNumber}</if>
|
||||
<if test="orderStatus != null and orderStatus != ''"> and order_status = #{orderStatus}</if>
|
||||
<if test="totalAmount != null and totalAmount != ''"> and total_amount = #{totalAmount}</if>
|
||||
<if test="actualAmount != null and actualAmount != ''"> and actual_amount = #{actualAmount}</if>
|
||||
@ -44,6 +46,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
insert into pay_order
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="orderNumber != null">order_number,</if>
|
||||
<if test="thirdNumber != null">third_number,</if>
|
||||
<if test="orderStatus != null">order_status,</if>
|
||||
<if test="totalAmount != null">total_amount,</if>
|
||||
<if test="actualAmount != null">actual_amount,</if>
|
||||
@ -57,6 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="orderNumber != null">#{orderNumber},</if>
|
||||
<if test="thirdNumber != null">#{thirdNumber},</if>
|
||||
<if test="orderStatus != null">#{orderStatus},</if>
|
||||
<if test="totalAmount != null">#{totalAmount},</if>
|
||||
<if test="actualAmount != null">#{actualAmount},</if>
|
||||
@ -74,6 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
update pay_order
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<if test="orderNumber != null">order_number = #{orderNumber},</if>
|
||||
<if test="thirdNumber != null">third_number = #{thirdNumber},</if>
|
||||
<if test="orderStatus != null">order_status = #{orderStatus},</if>
|
||||
<if test="totalAmount != null">total_amount = #{totalAmount},</if>
|
||||
<if test="actualAmount != null">actual_amount = #{actualAmount},</if>
|
||||
|
@ -28,18 +28,24 @@ import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.http.HttpClientUtil;
|
||||
import com.ruoyi.common.utils.sign.Md5Utils;
|
||||
import com.ruoyi.pay.domain.PayOrder;
|
||||
import com.ruoyi.pay.service.IPayOrderService;
|
||||
import com.ruoyi.pay.sqb.config.SqbConfig;
|
||||
import com.ruoyi.pay.sqb.service.ISqbPayService;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Service("sqbPayService")
|
||||
@ConditionalOnProperty(prefix = "pay.sqb", name = "enabled", havingValue = "true")
|
||||
public class SQBServiceImpl implements ISqbPayService {
|
||||
@Autowired
|
||||
private SqbConfig sqbConfig;
|
||||
|
||||
@Autowired
|
||||
private IPayOrderService payOrderService;
|
||||
|
||||
/**
|
||||
* http POST 请求
|
||||
*
|
||||
@ -146,7 +152,7 @@ public class SQBServiceImpl implements ISqbPayService {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String refund(PayOrder payOrder) {
|
||||
public PayOrder refund(PayOrder payOrder) {
|
||||
String url = sqbConfig.getApiDomain() + "/upay/v2/refund";
|
||||
JSONObject params = new JSONObject();
|
||||
try {
|
||||
@ -158,8 +164,14 @@ public class SQBServiceImpl implements ISqbPayService {
|
||||
|
||||
String sign = getSign(params.toString() + sqbConfig.getTerminalKey());
|
||||
String result = httpPost(url, params, sign, sqbConfig.getTerminalSn());
|
||||
|
||||
return result;
|
||||
JSONObject retObj = JSON.parseObject(result);
|
||||
JSONObject bizResponse = retObj.getJSONObject("biz_response");
|
||||
if ("REFUNDED".equals(bizResponse.getString("order_status"))) {
|
||||
payOrderService.updateStatus(payOrder.getOrderNumber(), "已退款");
|
||||
} else {
|
||||
log.error("退款失败");
|
||||
}
|
||||
return payOrder;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
@ -170,8 +182,8 @@ public class SQBServiceImpl implements ISqbPayService {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
public String query(PayOrder payOrder) {
|
||||
@Override
|
||||
public PayOrder query(PayOrder payOrder) {
|
||||
String url = sqbConfig.getApiDomain() + "/upay/v2/query";
|
||||
JSONObject params = new JSONObject();
|
||||
try {
|
||||
@ -185,8 +197,8 @@ public class SQBServiceImpl implements ISqbPayService {
|
||||
if (!"200".equals(resCode)) {
|
||||
return null;
|
||||
}
|
||||
String responseStr = retObj.get("biz_response").toString();
|
||||
return responseStr;
|
||||
// String responseStr = retObj.get("biz_response").toString();
|
||||
return payOrder;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.ruoyi.pay.controller;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -8,8 +9,8 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
@ -20,19 +21,35 @@ import com.ruoyi.pay.service.PayService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.Parameters;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
@RequestMapping("/pay/<channel>")
|
||||
@RequestMapping("/pay/{channel}")
|
||||
@RestController
|
||||
public class PayController extends BaseController {
|
||||
@Autowired
|
||||
|
||||
@Autowired(required = false)
|
||||
private Map<String, PayService> payServiceMap; // alipay wechat sqb
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (payServiceMap == null) {
|
||||
payServiceMap = new HashMap<>();
|
||||
logger.warn("请注意,没有加载任何支付服务");
|
||||
} else {
|
||||
payServiceMap.forEach((k, v) -> {
|
||||
logger.info("已加载支付服务 {}", k);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private IPayOrderService payOrderService;
|
||||
|
||||
@Operation(summary = "微信支付")
|
||||
@Parameters({
|
||||
@Parameter(name = "channel", description = "支付方式", required = true),
|
||||
@Parameter(name = "orderNumber", description = "订单号", required = true)
|
||||
})
|
||||
@GetMapping("/url/{orderNumber}")
|
||||
@ -44,6 +61,9 @@ public class PayController extends BaseController {
|
||||
|
||||
@Anonymous
|
||||
@Operation(summary = "微信支付查询订单")
|
||||
@Parameters({
|
||||
@Parameter(name = "channel", description = "支付方式", required = true)
|
||||
})
|
||||
@PostMapping("/notify")
|
||||
public String notify(@PathVariable String channel, HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
@ -52,7 +72,8 @@ public class PayController extends BaseController {
|
||||
}
|
||||
|
||||
@Operation(summary = "查询支付状态")
|
||||
@Parameters(value = {
|
||||
@Parameters({
|
||||
@Parameter(name = "channel", description = "支付方式", required = true),
|
||||
@Parameter(name = "orderNumber", description = "订单号", required = true)
|
||||
})
|
||||
@PostMapping("/query/{orderNumber}")
|
||||
@ -64,13 +85,11 @@ public class PayController extends BaseController {
|
||||
}
|
||||
|
||||
@PostMapping("/refund")
|
||||
@Parameters({
|
||||
@Parameter(name = "channel", description = "支付方式", required = true),
|
||||
})
|
||||
public AjaxResult refund(@PathVariable String channel, @RequestBody PayOrder payOrder) {
|
||||
PayService payService = payServiceMap.get(channel + "PayService");
|
||||
String refund = payService.refund(payOrder);
|
||||
if (refund == null) {
|
||||
return error("退款失败");
|
||||
}
|
||||
Object parse = JSON.parse(refund);
|
||||
return success(parse);
|
||||
return success(payService.refund(payOrder));
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import org.springframework.core.io.Resource;
|
||||
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
|
||||
import com.wechat.pay.java.service.refund.RefundService;
|
||||
|
||||
/**
|
||||
* 配置我们自己的信息
|
||||
@ -26,79 +27,54 @@ import com.wechat.pay.java.service.payments.nativepay.NativePayService;
|
||||
@ConditionalOnProperty(prefix = "pay.wechat", name = "enabled", havingValue = "true")
|
||||
public class WxPayConfig {
|
||||
|
||||
/** 商户号 */
|
||||
@Value("${pay.wechat.merchantId}")
|
||||
private String wxchantId;
|
||||
private String merchantId;
|
||||
|
||||
/** 商户证书序列号 */
|
||||
@Value("${pay.wechat.merchantSerialNumber}")
|
||||
private String wxchantSerialNumber;
|
||||
private String merchantSerialNumber;
|
||||
|
||||
/** 商户APIV3密钥 */
|
||||
@Value("${pay.wechat.apiV3Key}")
|
||||
private String wxapiV3Key;
|
||||
private String apiV3Key;
|
||||
|
||||
/** 商户API私钥路径 */
|
||||
@Value("${pay.wechat.privateKeyPath}")
|
||||
private String wxcertPath;
|
||||
private String privateKeyPath;
|
||||
|
||||
@Value("${pay.wechat.appId}")
|
||||
private String appId;
|
||||
|
||||
@Value("${pay.wechat.notifyUrl}")
|
||||
private String notifyUrl;
|
||||
|
||||
@Bean
|
||||
public RSAAutoCertificateConfig wxpayBaseConfig() throws Exception {
|
||||
return new RSAAutoCertificateConfig.Builder()
|
||||
.merchantId(getWxchantId())
|
||||
.privateKeyFromPath(getWxcertPath())
|
||||
.merchantSerialNumber(getWxchantSerialNumber())
|
||||
.apiV3Key(getWxapiV3Key())
|
||||
.build();
|
||||
public String getMerchantId() {
|
||||
return merchantId;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NativePayService nativePayService() throws Exception {
|
||||
return new NativePayService.Builder().config(wxpayBaseConfig()).build();
|
||||
public void setMerchantId(String merchantId) {
|
||||
this.merchantId = merchantId;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NotificationParser notificationParser() throws Exception {
|
||||
return new NotificationParser(wxpayBaseConfig());
|
||||
public String getMerchantSerialNumber() {
|
||||
return merchantSerialNumber;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public String getWxcertPath() throws Exception {
|
||||
if (wxcertPath.startsWith("classpath:")) {
|
||||
Resource resource = applicationContext.getResource(wxcertPath);
|
||||
String tempFilePath = System.getProperty("java.io.tmpdir") + "/temp_wxcert.pem";
|
||||
try (InputStream inputStream = resource.getInputStream()) {
|
||||
Files.copy(inputStream, Paths.get(tempFilePath), StandardCopyOption.REPLACE_EXISTING);
|
||||
wxcertPath = tempFilePath;
|
||||
} catch (Exception e) {
|
||||
Files.deleteIfExists(Paths.get(tempFilePath));
|
||||
throw new RuntimeException("微信支付证书文件读取失败", e);
|
||||
}
|
||||
}
|
||||
return wxcertPath;
|
||||
public void setMerchantSerialNumber(String merchantSerialNumber) {
|
||||
this.merchantSerialNumber = merchantSerialNumber;
|
||||
}
|
||||
|
||||
public String getWxchantId() {
|
||||
return wxchantId;
|
||||
public String getApiV3Key() {
|
||||
return apiV3Key;
|
||||
}
|
||||
|
||||
public void setWxchantId(String wxchantId) {
|
||||
this.wxchantId = wxchantId;
|
||||
public void setApiV3Key(String apiV3Key) {
|
||||
this.apiV3Key = apiV3Key;
|
||||
}
|
||||
|
||||
public String getWxchantSerialNumber() {
|
||||
return wxchantSerialNumber;
|
||||
}
|
||||
|
||||
public void setWxchantSerialNumber(String wxchantSerialNumber) {
|
||||
this.wxchantSerialNumber = wxchantSerialNumber;
|
||||
}
|
||||
|
||||
public String getWxapiV3Key() {
|
||||
return wxapiV3Key;
|
||||
}
|
||||
|
||||
public void setWxapiV3Key(String wxapiV3Key) {
|
||||
this.wxapiV3Key = wxapiV3Key;
|
||||
public void setPrivateKeyPath(String privateKeyPath) {
|
||||
this.privateKeyPath = privateKeyPath;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
@ -116,4 +92,48 @@ public class WxPayConfig {
|
||||
public void setNotifyUrl(String notifyUrl) {
|
||||
this.notifyUrl = notifyUrl;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RSAAutoCertificateConfig wxpayBaseConfig() throws Exception {
|
||||
return new RSAAutoCertificateConfig.Builder()
|
||||
.merchantId(getMerchantId())
|
||||
.privateKeyFromPath(getPrivateKeyPath())
|
||||
.merchantSerialNumber(getMerchantSerialNumber())
|
||||
.apiV3Key(getApiV3Key())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NativePayService nativePayService() throws Exception {
|
||||
return new NativePayService.Builder().config(wxpayBaseConfig()).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RefundService refundService() throws Exception {
|
||||
return new RefundService.Builder().config(wxpayBaseConfig()).build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public NotificationParser notificationParser() throws Exception {
|
||||
return new NotificationParser(wxpayBaseConfig());
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
public String getPrivateKeyPath() throws Exception {
|
||||
if (privateKeyPath.startsWith("classpath:")) {
|
||||
Resource resource = applicationContext.getResource(privateKeyPath);
|
||||
String tempFilePath = System.getProperty("java.io.tmpdir") + "/temp_wxcert.pem";
|
||||
try (InputStream inputStream = resource.getInputStream()) {
|
||||
Files.copy(inputStream, Paths.get(tempFilePath), StandardCopyOption.REPLACE_EXISTING);
|
||||
privateKeyPath = tempFilePath;
|
||||
} catch (Exception e) {
|
||||
Files.deleteIfExists(Paths.get(tempFilePath));
|
||||
throw new RuntimeException("微信支付证书文件读取失败", e);
|
||||
}
|
||||
}
|
||||
return privateKeyPath;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.ruoyi.pay.wx.service;
|
||||
|
||||
import com.ruoyi.pay.service.PayService;
|
||||
import com.wechat.pay.java.service.wexinpayscoreparking.model.Transaction;
|
||||
|
||||
public interface IWxPayService extends PayService {
|
||||
public void callback(Transaction transaction);
|
||||
}
|
||||
|
@ -11,13 +11,20 @@ import com.ruoyi.pay.domain.PayOrder;
|
||||
import com.ruoyi.pay.service.IPayOrderService;
|
||||
import com.ruoyi.pay.wx.config.WxPayConfig;
|
||||
import com.ruoyi.pay.wx.service.IWxPayService;
|
||||
import com.wechat.pay.java.core.exception.ServiceException;
|
||||
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||
import com.wechat.pay.java.core.notification.RequestParam;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction.TradeStateEnum;
|
||||
import com.wechat.pay.java.service.payments.nativepay.NativePayService;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.Amount;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.PrepayRequest;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.PrepayResponse;
|
||||
import com.wechat.pay.java.service.wexinpayscoreparking.model.Transaction;
|
||||
import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByIdRequest;
|
||||
import com.wechat.pay.java.service.refund.RefundService;
|
||||
import com.wechat.pay.java.service.refund.model.CreateRequest;
|
||||
import com.wechat.pay.java.service.refund.model.Refund;
|
||||
import com.wechat.pay.java.service.refund.model.Status;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
@ -38,9 +45,8 @@ public class WxPayService implements IWxPayService {
|
||||
@Autowired
|
||||
private NotificationParser notificationParser;
|
||||
|
||||
public void callback(Transaction transaction) {
|
||||
|
||||
}
|
||||
@Autowired
|
||||
private RefundService refundService;
|
||||
|
||||
@Override
|
||||
public String payUrl(PayOrder payOrder) {
|
||||
@ -49,7 +55,7 @@ public class WxPayService implements IWxPayService {
|
||||
amount.setTotal(Integer.parseInt(payOrder.getActualAmount()));
|
||||
request.setAmount(amount);
|
||||
request.setAppid(wxPayAppConfig.getAppId());
|
||||
request.setMchid(wxPayAppConfig.getWxchantId());
|
||||
request.setMchid(wxPayAppConfig.getMerchantId());
|
||||
request.setDescription(payOrder.getOrderContent());
|
||||
request.setNotifyUrl(wxPayAppConfig.getNotifyUrl());
|
||||
request.setOutTradeNo(payOrder.getOrderNumber());
|
||||
@ -75,7 +81,7 @@ public class WxPayService implements IWxPayService {
|
||||
Transaction transaction = notificationParser.parse(requestParam, Transaction.class);
|
||||
String orderNumber = transaction.getOutTradeNo();
|
||||
String otherOrderNumber = transaction.getTransactionId();
|
||||
String orderState = transaction.getTradeState();
|
||||
TradeStateEnum orderState = transaction.getTradeState();
|
||||
System.out.println("orderNumber: " + orderNumber);
|
||||
System.out.println("otherOrderNumber: " + otherOrderNumber);
|
||||
System.out.println("orderState: " + orderState);
|
||||
@ -87,15 +93,32 @@ public class WxPayService implements IWxPayService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String query(PayOrder payOrder) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'query'");
|
||||
public PayOrder query(PayOrder payOrder) {
|
||||
QueryOrderByIdRequest queryRequest = new QueryOrderByIdRequest();
|
||||
queryRequest.setMchid(wxPayAppConfig.getMerchantId());
|
||||
queryRequest.setTransactionId(payOrder.getOrderNumber());
|
||||
try {
|
||||
Transaction result = nativePayService.queryOrderById(queryRequest);
|
||||
System.out.println(result.getTradeState());
|
||||
} catch (ServiceException e) {
|
||||
System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
|
||||
System.out.printf("reponse body=[%s]\n", e.getResponseBody());
|
||||
}
|
||||
return payOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String refund(PayOrder payOrder) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'refund'");
|
||||
public PayOrder refund(PayOrder payOrder) {
|
||||
CreateRequest request = new CreateRequest();
|
||||
request.setTransactionId(payOrder.getOrderNumber());
|
||||
request.setOutRefundNo(payOrder.getOrderNumber());
|
||||
request.setOutTradeNo(payOrder.getOrderNumber());
|
||||
Refund refund = refundService.create(request);
|
||||
Status status = refund.getStatus();
|
||||
if (status.equals(Status.SUCCESS)) {
|
||||
payOrderService.updateStatus(payOrder.getOrderNumber(), "已退款");
|
||||
}
|
||||
return payOrder;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ DROP TABLE IF EXISTS `pay_order`;
|
||||
CREATE TABLE `pay_order` (
|
||||
order_id bigint NOT NULL AUTO_INCREMENT COMMENT '订单id',
|
||||
order_number varchar(255) NULL DEFAULT NULL COMMENT '订单号',
|
||||
third_number varchar(255) NULL DEFAULT NULL COMMENT '第三方订单号',
|
||||
order_status varchar(255) NULL DEFAULT NULL COMMENT '订单状态',
|
||||
total_amount varchar(255) NULL DEFAULT NULL COMMENT '订单总金额',
|
||||
actual_amount varchar(255) NULL DEFAULT NULL COMMENT '实际支付金额',
|
||||
|
@ -5,6 +5,7 @@ DROP TABLE IF EXISTS pay_order;
|
||||
CREATE TABLE pay_order (
|
||||
order_id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
|
||||
order_number varchar(255) NULL DEFAULT NULL,
|
||||
third_number varchar(255) NULL DEFAULT NULL,
|
||||
order_status varchar(255) NULL DEFAULT NULL,
|
||||
total_amount varchar(255) NULL DEFAULT NULL,
|
||||
actual_amount varchar(255) NULL DEFAULT NULL,
|
||||
@ -19,6 +20,7 @@ CREATE TABLE pay_order (
|
||||
|
||||
COMMENT ON COLUMN pay_order.order_id IS '订单id';
|
||||
COMMENT ON COLUMN pay_order.order_number IS '订单号';
|
||||
COMMENT ON COLUMN pay_order.third_number IS '第三方订单号';
|
||||
COMMENT ON COLUMN pay_order.order_status IS '订单状态';
|
||||
COMMENT ON COLUMN pay_order.total_amount IS '订单总金额';
|
||||
COMMENT ON COLUMN pay_order.actual_amount IS '实际支付金额';
|
||||
|
Loading…
Reference in New Issue
Block a user