From b401d7be19a391fe84999f1d8ac270561cbc61af Mon Sep 17 00:00:00 2001 From: Dftre <3066417822@qq.com> Date: Tue, 21 May 2024 16:42:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=94=AF=E4=BB=98=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/application-pay.yml | 15 ++- .../ruoyi/pay/alipay/config/AliPayConfig.java | 102 ++++++++------- .../alipay/controller/AliPayController.java | 49 ++++---- .../com/ruoyi/pay/mapper/PayOrderMapper.java | 1 + .../ruoyi/pay/service/IPayOrderService.java | 1 + .../pay/service/impl/PayOrderServiceImpl.java | 5 + .../resources/mapper/pay/PayOrderMapper.xml | 90 +++++++------- ruoyi-pay/ruoyi-pay-wx/pom.xml | 9 +- .../ruoyi/pay/wx/config/WxPayAppConfig.java | 32 +++++ .../pay/wx/controller/WxAppPayController.java | 116 ++++++++++++++++++ 10 files changed, 306 insertions(+), 114 deletions(-) create mode 100644 ruoyi-pay/ruoyi-pay-wx/src/main/java/com/ruoyi/pay/wx/config/WxPayAppConfig.java create mode 100644 ruoyi-pay/ruoyi-pay-wx/src/main/java/com/ruoyi/pay/wx/controller/WxAppPayController.java diff --git a/ruoyi-admin/src/main/resources/application-pay.yml b/ruoyi-admin/src/main/resources/application-pay.yml index b7fef48..2a50b6b 100644 --- a/ruoyi-admin/src/main/resources/application-pay.yml +++ b/ruoyi-admin/src/main/resources/application-pay.yml @@ -7,7 +7,14 @@ pay: vendorSn: "vendorSn" vendorKey: "vendorKey" alipay: - appId: "appId" - privateKey: "privateKey" - publicKey: "publicKey" - notifyUrl: "notifyUrl" \ No newline at end of file + appId: appId + appPrivateKey: appPrivateKey #classpath:pay/alipay/alipay_private_key.pem + alipayPublicKey: alipayPublicKey #classpath:pay/alipay/alipay_public_key.pem + notifyUrl: http://www.sdaizy.com/prod-api/alipay/notify + wechat: + merchantId: merchantId + privateKeyPath: privateKeyPath + merchantSerialNumber: merchantSerialNumber + apiV3Key: apiV3Key + appId: appId + notifyUrl: http://g5vdrz.natappfree.cc/wxPay/notify diff --git a/ruoyi-pay/ruoyi-pay-alipay/src/main/java/com/ruoyi/pay/alipay/config/AliPayConfig.java b/ruoyi-pay/ruoyi-pay-alipay/src/main/java/com/ruoyi/pay/alipay/config/AliPayConfig.java index d599f3a..28d5422 100644 --- a/ruoyi-pay/ruoyi-pay-alipay/src/main/java/com/ruoyi/pay/alipay/config/AliPayConfig.java +++ b/ruoyi-pay/ruoyi-pay-alipay/src/main/java/com/ruoyi/pay/alipay/config/AliPayConfig.java @@ -1,66 +1,78 @@ package com.ruoyi.pay.alipay.config; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.kernel.Config; - -import jakarta.annotation.PostConstruct; - -@Component +/** + * @author zlh + */ +@Configuration public class AliPayConfig { @Value("${pay.alipay.appId}") private String appId; - @Value("${pay.alipay.privateKey}") - private String privateKey; - @Value("${pay.alipay.publicKey}") - private String publicKey; @Value("${pay.alipay.notifyUrl}") private String notifyUrl; + @Value("${pay.alipay.appPrivateKey}") + private String appPrivateKey; + @Value("${pay.alipay.alipayPublicKey}") + private String alipayPublicKey; - @PostConstruct - public void init() { + @Autowired + private ApplicationContext applicationContext; + + private String getAppPrivateKey() throws Exception { + if (appPrivateKey.startsWith("classpath")) { + Resource resource = applicationContext.getResource(appPrivateKey); + InputStream inputStream = resource.getInputStream(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + String appPrivateKeyValue = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator())); + bufferedReader.close(); + return appPrivateKeyValue; + } else { + return appPrivateKey; + } + } + + private String getAlipayPublicKey() throws Exception { + if (alipayPublicKey.startsWith("classpath")) { + Resource resource = applicationContext.getResource(alipayPublicKey); + InputStream inputStream = resource.getInputStream(); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + String alipayPublicKeyValue = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator())); + bufferedReader.close(); + return alipayPublicKeyValue; + } else { + return alipayPublicKey; + } + } + + @Bean + protected Config config() throws Exception { + // 设置参数(全局只需设置一次) Config config = new Config(); config.protocol = "https"; - config.gatewayHost = "openapi-sandbox.dl.alipaydev.com"; + config.gatewayHost = "openapi.alipay.com";// openapi-sandbox.dl.alipaydev.com||openapi.alipay.com config.signType = "RSA2"; config.appId = this.appId; - config.merchantPrivateKey = this.privateKey; - config.alipayPublicKey = this.publicKey; + config.merchantPrivateKey = getAppPrivateKey(); + config.alipayPublicKey = getAlipayPublicKey(); + System.out.println(getAlipayPublicKey()); config.notifyUrl = this.notifyUrl; Factory.setOptions(config); + return config; } - public String getAppId() { - return appId; - } +} - public void setAppId(String appId) { - this.appId = appId; - } - - public String getPrivateKey() { - return privateKey; - } - - public void setPrivateKey(String privateKey) { - this.privateKey = privateKey; - } - - public String getPublicKey() { - return publicKey; - } - - public void setPublicKey(String publicKey) { - this.publicKey = publicKey; - } - - public String getNotifyUrl() { - return notifyUrl; - } - - public void setNotifyUrl(String notifyUrl) { - this.notifyUrl = notifyUrl; - } -} \ No newline at end of file +// https://openapi-sandbox.dl.alipaydev.com/gateway.do \ No newline at end of file diff --git a/ruoyi-pay/ruoyi-pay-alipay/src/main/java/com/ruoyi/pay/alipay/controller/AliPayController.java b/ruoyi-pay/ruoyi-pay-alipay/src/main/java/com/ruoyi/pay/alipay/controller/AliPayController.java index 1c48f82..2339c27 100644 --- a/ruoyi-pay/ruoyi-pay-alipay/src/main/java/com/ruoyi/pay/alipay/controller/AliPayController.java +++ b/ruoyi-pay/ruoyi-pay-alipay/src/main/java/com/ruoyi/pay/alipay/controller/AliPayController.java @@ -5,6 +5,7 @@ import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -12,45 +13,50 @@ import org.springframework.web.bind.annotation.RestController; import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse; import com.ruoyi.common.annotation.Anonymous; -import com.ruoyi.pay.alipay.config.AliPayConfig; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.pay.domain.PayOrder; -import com.ruoyi.pay.mapper.PayOrderMapper; +import com.ruoyi.pay.service.IPayOrderService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; - +/** + * @author zlh + */ @RestController @RequestMapping("/alipay") +@Tag(name = "【支付宝】管理") public class AliPayController { @Autowired - private PayOrderMapper payOrderMapper; - - @Autowired - private AliPayConfig aliPayConfig; - - @GetMapping("/init") - public String init() { - aliPayConfig.init(); - return "success"; - } + private IPayOrderService payOrderService; @Anonymous - @GetMapping("/pay") - public String pay(PayOrder payOrder) { + @Operation(summary = "支付宝支付") + @Parameters({ + @Parameter(name = "orderId", description = "订单号", required = true) + }) + @GetMapping("/pay/{orderNumber}") + public AjaxResult pay(@PathVariable String orderNumber) { AlipayTradePagePayResponse response; + PayOrder aliPay = payOrderService.selectPayOrderByOrderNumber(orderNumber); try { // 发起API调用(以创建当面付收款二维码为例) response = Factory.Payment.Page() - .pay(payOrder.getOrderContent(), payOrder.getOrderNumber(), payOrder.getTotalAmount(), ""); + .pay(aliPay.getOrderContent(), aliPay.getOrderNumber(), aliPay.getTotalAmount(), ""); } catch (Exception e) { System.err.println("调用遭遇异常,原因:" + e.getMessage()); throw new RuntimeException(e.getMessage(), e); } - return response.getBody(); + return AjaxResult.success(response.getBody()); } + @Anonymous + @Operation(summary = "支付宝支付回调") @PostMapping("/notify") // 注意这里必须是POST接口 - public String payNotify(HttpServletRequest request) throws Exception { + public AjaxResult payNotify(HttpServletRequest request) throws Exception { if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) { System.out.println("=========支付宝异步回调========"); @@ -74,11 +80,10 @@ public class AliPayController { System.out.println("买家付款时间: " + params.get("gmt_payment")); System.out.println("买家付款金额: " + params.get("buyer_pay_amount")); - PayOrder payOrder = payOrderMapper.selectPayOrderByOrderNumber(orderNumber); - payOrder.setOrderStatus("已支付"); - payOrderMapper.updatePayOrder(payOrder); + // // 更新订单未已支付 + payOrderService.updateStatus(orderNumber, "已支付"); } } - return "success"; + return AjaxResult.success("success"); } } diff --git a/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/mapper/PayOrderMapper.java b/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/mapper/PayOrderMapper.java index 53a3d94..9f88c37 100644 --- a/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/mapper/PayOrderMapper.java +++ b/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/mapper/PayOrderMapper.java @@ -69,4 +69,5 @@ public interface PayOrderMapper public int deletePayOrderByOrderIds(Long[] orderIds); public int deletePayOrderByOrderNumber(String orderNumber); + public int updateStatus(String orderNumber, String orderStatus); } diff --git a/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/service/IPayOrderService.java b/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/service/IPayOrderService.java index f5e28f0..96ee3ef 100644 --- a/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/service/IPayOrderService.java +++ b/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/service/IPayOrderService.java @@ -75,4 +75,5 @@ public interface IPayOrderService { * @return 结果 */ public int deletePayOrderByOrderId(Long orderId); + public int updateStatus(String orderNumber, String orderStatus); } diff --git a/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/service/impl/PayOrderServiceImpl.java b/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/service/impl/PayOrderServiceImpl.java index a5a7a46..7fb88ab 100644 --- a/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/service/impl/PayOrderServiceImpl.java +++ b/ruoyi-pay/ruoyi-pay-common/src/main/java/com/ruoyi/pay/service/impl/PayOrderServiceImpl.java @@ -107,4 +107,9 @@ public class PayOrderServiceImpl implements IPayOrderService { public int deletePayOrderByOrderNumber(String orderNumber) { return payOrderMapper.deletePayOrderByOrderNumber(orderNumber); } + + @Override + public int updateStatus(String orderNumber, String orderStatus) { + return payOrderMapper.updateStatus(orderNumber, orderStatus); + } } diff --git a/ruoyi-pay/ruoyi-pay-common/src/main/resources/mapper/pay/PayOrderMapper.xml b/ruoyi-pay/ruoyi-pay-common/src/main/resources/mapper/pay/PayOrderMapper.xml index 7a707c0..a43062c 100644 --- a/ruoyi-pay/ruoyi-pay-common/src/main/resources/mapper/pay/PayOrderMapper.xml +++ b/ruoyi-pay/ruoyi-pay-common/src/main/resources/mapper/pay/PayOrderMapper.xml @@ -34,62 +34,70 @@ + where pay_order.order_id = #{orderId} + + where pay_order.order_number = #{orderNumber} + - insert into pay_order - order_id, - user_id, - order_number, - + insert into pay_order + + order_id, + user_id, + order_number, + order_status, - total_amount, - order_content, - + total_amount, + order_content, + order_remark, - order_message, - - - #{orderId}, - #{userId}, - #{orderNumber}, - + order_message, + + + #{orderId}, + #{userId}, + #{orderNumber}, + #{orderStatus}, - #{totalAmount}, - #{orderContent}, - + #{totalAmount}, + #{orderContent}, + #{orderRemark}, - #{orderMessage}, - - + #{orderMessage}, + + - update pay_order - user_id = #{userId}, - order_number - = #{orderNumber}, - order_status = #{orderStatus}, - total_amount = #{totalAmount}, - order_content = #{orderContent}, - order_remark = #{orderRemark}, - order_message = #{orderMessage}, - + update pay_order + + user_id = #{userId}, + order_number + = #{orderNumber}, + order_status = #{orderStatus}, + total_amount = #{totalAmount}, + order_content = #{orderContent}, + order_remark = #{orderRemark}, + order_message = #{orderMessage}, + where pay_order.order_id = #{orderId} - + delete from pay_order where order_id = #{orderId} - + - + delete from pay_order where order_number= #{orderNumber} - + - + delete from pay_order where order_id in - + #{orderId} - - + + + + + update pay_order set order_status = #{orderStatus} where order_number = #{orderNumber} + \ No newline at end of file diff --git a/ruoyi-pay/ruoyi-pay-wx/pom.xml b/ruoyi-pay/ruoyi-pay-wx/pom.xml index 11b2537..426b2f4 100644 --- a/ruoyi-pay/ruoyi-pay-wx/pom.xml +++ b/ruoyi-pay/ruoyi-pay-wx/pom.xml @@ -1,7 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> ruoyi-pay com.ruoyi @@ -22,6 +21,12 @@ ruoyi-pay-common + + com.github.wechatpay-apiv3 + wechatpay-java + 0.2.12 + + \ No newline at end of file diff --git a/ruoyi-pay/ruoyi-pay-wx/src/main/java/com/ruoyi/pay/wx/config/WxPayAppConfig.java b/ruoyi-pay/ruoyi-pay-wx/src/main/java/com/ruoyi/pay/wx/config/WxPayAppConfig.java new file mode 100644 index 0000000..21829b6 --- /dev/null +++ b/ruoyi-pay/ruoyi-pay-wx/src/main/java/com/ruoyi/pay/wx/config/WxPayAppConfig.java @@ -0,0 +1,32 @@ +package com.ruoyi.pay.wx.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import lombok.Data; + +/** + * 配置我们自己的信息 + * + * @author ZlH + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "wechat") +public class WxPayAppConfig { + + @Value("${pay.wechat.merchantId}") + private String wxchantId; + @Value("${pay.wechat.merchantSerialNumber}") + private String wxchantSerialNumber; + @Value("${pay.wechat.apiV3Key}") + private String wxapiV3Key; + @Value("${pay.wechat.privateKeyPath}") + private String wxcertPath; + @Value("${pay.wechat.appId}") + private String appId; + @Value("${pay.wechat.notifyUrl}") + private String notifyUrl; + +} diff --git a/ruoyi-pay/ruoyi-pay-wx/src/main/java/com/ruoyi/pay/wx/controller/WxAppPayController.java b/ruoyi-pay/ruoyi-pay-wx/src/main/java/com/ruoyi/pay/wx/controller/WxAppPayController.java new file mode 100644 index 0000000..db11ea8 --- /dev/null +++ b/ruoyi-pay/ruoyi-pay-wx/src/main/java/com/ruoyi/pay/wx/controller/WxAppPayController.java @@ -0,0 +1,116 @@ +package com.ruoyi.pay.wx.controller; + +import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.pay.domain.PayOrder; +import com.ruoyi.pay.service.IPayOrderService; +import com.ruoyi.pay.wx.config.WxPayAppConfig; +import com.wechat.pay.java.core.Config; +import com.wechat.pay.java.core.RSAAutoCertificateConfig; +import com.wechat.pay.java.core.exception.ValidationException; +import com.wechat.pay.java.core.notification.NotificationConfig; +import com.wechat.pay.java.core.notification.NotificationParser; +import com.wechat.pay.java.core.notification.RequestParam; +import com.wechat.pay.java.service.payments.nativepay.model.QueryOrderByIdRequest; +import com.wechat.pay.java.service.wexinpayscoreparking.model.Transaction; +import io.swagger.v3.oas.annotations.Operation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.ruoyi.common.core.controller.BaseController; +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 lombok.extern.slf4j.Slf4j; + +/** + * @author zlh + */ +@Slf4j +@RestController +@RequestMapping("/wxPay") +public class WxAppPayController extends BaseController { + @Autowired + private WxPayAppConfig wxPayAppConfig; + @Autowired + private IPayOrderService payOrderService; + @Anonymous + @Operation(summary = "微信支付") + @GetMapping("/pay/{orderNumber}") + public AjaxResult pay(@PathVariable String orderNumber) { + // 使用自动更新平台证书的RSA配置 + // 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错 + Config config = + new RSAAutoCertificateConfig.Builder() + .merchantId(wxPayAppConfig.getWxchantId()) + .privateKeyFromPath(wxPayAppConfig.getWxcertPath()) + .merchantSerialNumber(wxPayAppConfig.getWxchantSerialNumber()) + .apiV3Key(wxPayAppConfig.getWxapiV3Key()) + .build(); + // 构建service + NativePayService service = new NativePayService.Builder().config(config).build(); + // request.setXxx(val)设置所需参数,具体参数可见Request定义 + PayOrder aliPay = payOrderService.selectPayOrderByOrderNumber(orderNumber); + String amountStr = aliPay.getTotalAmount(); + double amountDouble = Double.parseDouble(amountStr); + int totalAmountInt = (int) (amountDouble * 100); + PrepayRequest request = new PrepayRequest(); + Amount amount = new Amount(); + amount.setTotal(totalAmountInt); + request.setAmount(amount); + request.setAppid(wxPayAppConfig.getAppId()); + request.setMchid(wxPayAppConfig.getWxchantId()); + request.setDescription(aliPay.getOrderContent()); + request.setNotifyUrl(wxPayAppConfig.getNotifyUrl()); + request.setOutTradeNo(aliPay.getOrderNumber()); + // 调用下单方法,得到应答 + PrepayResponse response = service.prepay(request); + // 使用微信扫描 code_url 对应的二维码,即可体验Native支付 + return AjaxResult.success(response.getCodeUrl()); + } + +// @Anonymous +// @Operation(summary = "微信支付查询订单") +// @GetMapping("/notify") +// public AjaxResult WxPayList() { +// System.out.println("=========支付宝异步回调========"); +// // 构造 RequestParam +// RequestParam requestParam = new RequestParam.Builder() +// .serialNumber("wechatPaySerial") +// .nonce("wechatpayNonce") +// .signature("wechatSignature") +// .timestamp("wechatTimestamp") +// .body("requestBody") +// .build(); +// +//// 如果已经初始化了 RSAAutoCertificateConfig,可直接使用 +//// 没有的话,则构造一个 +// NotificationConfig config = new RSAAutoCertificateConfig.Builder() +// .merchantId(merchantId) +// .privateKeyFromPath(privateKeyPath) +// .merchantSerialNumber(merchantSerialNumber) +// .apiV3Key(apiV3Key) +// .build(); +// +//// 初始化 NotificationParser +// NotificationParser parser = new NotificationParser(config); +// +// try { +// // 以支付通知回调为例,验签、解密并转换成 Transaction +// Transaction transaction = parser.parse(requestParam, Transaction.class); +// } catch (ValidationException e) { +// // 签名验证失败,返回 401 UNAUTHORIZED 状态码 +// logger.error("sign verification failed", e); +// return AjaxResult.success(HttpStatus.UNAUTHORIZED); +// } +//// 处理成功,返回 200 OK 状态码 +// return AjaxResult.success(HttpStatus.OK); +// } + +} \ No newline at end of file