Commit 6dc65234ef8f71320c120b3e88b888da2de3d39a

Authored by YunaiV
1 parent 6e3aa8a7

增加支付相关表的 SQL,调整相关的实体

Showing 29 changed files with 664 additions and 105 deletions
sql/pay2.sql 0 → 100644
  1 +/*
  2 + Navicat Premium Data Transfer
  3 +
  4 + Source Server : 127.0.0.1
  5 + Source Server Type : MySQL
  6 + Source Server Version : 80026
  7 + Source Host : localhost:3306
  8 + Source Schema : ruoyi-vue-pro
  9 +
  10 + Target Server Type : MySQL
  11 + Target Server Version : 80026
  12 + File Encoding : 65001
  13 +
  14 + Date: 23/10/2021 17:46:45
  15 +*/
  16 +
  17 +SET NAMES utf8mb4;
  18 +SET FOREIGN_KEY_CHECKS = 0;
  19 +
  20 +-- ----------------------------
  21 +-- Table structure for pay_app
  22 +-- ----------------------------
  23 +DROP TABLE IF EXISTS `pay_app`;
  24 +CREATE TABLE `pay_app` (
  25 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '应用编号',
  26 + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '应用名',
  27 + `status` tinyint NOT NULL COMMENT '开启状态',
  28 + `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  29 + `pay_notify_url` varchar(1024) NOT NULL COMMENT '支付结果的回调地址',
  30 + `notify_notify_url` varchar(1024) NOT NULL COMMENT '退款结果的回调地址',
  31 + `merchant_id` bigint NOT NULL COMMENT '商户编号',
  32 + `creator` varchar(64) DEFAULT '' COMMENT '创建者',
  33 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  34 + `updater` varchar(64) DEFAULT '' COMMENT '更新者',
  35 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  36 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  37 + PRIMARY KEY (`id`) USING BTREE
  38 +) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='支付应用信息';
  39 +
  40 +-- ----------------------------
  41 +-- Records of pay_app
  42 +-- ----------------------------
  43 +BEGIN;
  44 +INSERT INTO `pay_app` VALUES (6, '芋道', 0, '我是一个公众号', 'http://127.0.0.1', 'http://127.0.0.1', 1, '', '2021-10-23 08:49:25', '', '2021-10-23 08:49:25', b'0');
  45 +COMMIT;
  46 +
  47 +-- ----------------------------
  48 +-- Table structure for pay_channel
  49 +-- ----------------------------
  50 +DROP TABLE IF EXISTS `pay_channel`;
  51 +CREATE TABLE `pay_channel` (
  52 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商户编号',
  53 + `code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '渠道编码',
  54 + `status` tinyint NOT NULL COMMENT '开启状态',
  55 + `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  56 + `fee_rate` double NOT NULL DEFAULT '0' COMMENT '渠道费率,单位:百分比',
  57 + `merchant_id` bigint NOT NULL COMMENT '商户编号',
  58 + `app_id` bigint NOT NULL COMMENT '应用编号',
  59 + `config` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '支付渠道配置',
  60 + `creator` varchar(64) DEFAULT '' COMMENT '创建者',
  61 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  62 + `updater` varchar(64) DEFAULT '' COMMENT '更新者',
  63 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  64 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  65 + PRIMARY KEY (`id`) USING BTREE
  66 +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='支付渠道\n';
  67 +
  68 +-- ----------------------------
  69 +-- Records of pay_channel
  70 +-- ----------------------------
  71 +BEGIN;
  72 +INSERT INTO `pay_channel` VALUES (9, 'wx_pub', 0, NULL, 1, 1, 6, '{\"@class\":\"cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig\",\"appId\":\"wx041349c6f39b268b\",\"mchId\":\"1545083881\",\"apiVersion\":\"v2\",\"mchKey\":\"0alL64UDQdlCwiKZ73ib7ypaIjMns06p\",\"privateKeyContent\":\"-----BEGIN PRIVATE KEY-----\\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5q2hYE3loOQoH\\nl/2kh/epuj17W8VpV5vBl7ysJWAbBXux6mlq4gKTHD0QUQdiKtDEUm/bKC9Bi6VU\\nuklM5Y8oCaCbhjklHRbET8jsgd9phSNGviHclYRLsQRO8oXnN89kN0y7DYKm0hYd\\nmaiS12Z3v8VaImSTr4HVeHlC/z3S6mdwSr263stKt931YTcbTj/QFH7znsv9Na0u\\nX6LaMBEEAsJctWdm8Ndrd1tGh9Fzf0DA5VRXsJR3kkWspy+IwiDTPV/FDKOU9NJC\\nSxMmDePerTfkoZ2s1rltqBK0ykDJrXtxR+hTzEsKZ/KpNi8tyYpfNZsviHIlUsLP\\nFJ5UvUhpAgMBAAECggEAd90NltazqTIxpGdeCwrwOzWNnYbIclJprlhMKIJUgf1P\\nNrPTbHoOGXTAgzkcYCat8iAaMEzH/TOu/3zn92m3uqxEcEL9v1UBLqknWHAbkB6w\\ngGocqDAqYUcdNe5hvbyM+fCta5C0SQgV2PQrHOlMMICwYpkTfzhtxCdreXIYMoGg\\nJEIRkZWgrm/N7LTtNgizznuUjy6OURWjXaWKPcs3b3j6G1gLj9Vp++z4y0u51nqM\\n4R6fcvl8M6BjlcC8zo6DbOvCW8cXtuXsnru+2TPrUnsGeybJok4fEQsfW1BvpvPo\\nief38rYJn4OWxIrHcpWrhNtXtgRPeiMGFfIsEQDmVQKBgQDzXK6Nn3Nr3TFfGVTy\\n8QYrzOuY2NqzH8nnsLL6qn3HoKxTv+PcFKOTPsi6f4hIYCzBP0esRrPv0ffMu9oQ\\nJvFtCJvMmcKGtp0Q5hcj0y/XkbC3AWuahJtBv8lhKXVnQXSL0j3+ombljw4/8yN0\\nAzgBz+j/skQQgZ3sN5h+DHGtgwKBgQDDT784/2pd4m86c/uBmrwYfqu6MJo0eHJh\\n1XPtE+u8pOHyNTFk77rKobKDqN5VlrF0uEmBc/08LKhyxJ3vh/zAbcmqT1Mq778y\\nAKKUtVmvcaVDrvSQHsnhj0zt4SHGmmU34U2b9hV+nocq5VszX6/jp//HJi9bs3We\\ndAzfFCmaowKBgC1MmDVGc+6lCraf+X8LPFHU4Bnga70h8qxM6NPd/nG1R76DHn/t\\n25DiA+0rJgwK0unZxJadxoqic9TJNssA5Lmd+5o3GM2Imm311mLVwbcHqHQ4MHZf\\nrqKrd2m9lNv2hCIurVmDk1Gxsj5XHMdQfhFgSQengCHubp30r07vNA3PAoGAUEAE\\nIjdQTSMs8KeXP7mEb8wcY3R05/pVhT1fVJpK0kgtTofss7yM05V88/v+3sv8Pik6\\niqZN9tuimwWOn00Q3UA/DGtrkMjRlooMQ24AW8YmUZkhg9YivTtUMKnAZwopbLx2\\nVw7V5iDdCRMUVheK/c+ZmQpnixZBzcmBQGfYcGECgYBjEq3Mem+Aw6pXOu6+0FwH\\n9y6Xi4HhBkq0OOZZuXFtWVry7YrD3pBgzWVAZJqJCkyPKKZzCzwdbFd3u0lYBs35\\nzYgx7ug4hR+wfI980a3vxjcWGOqnOUUnUJ7ucIa+KDgnYV/bBy4jqpVreXmWAJXl\\nfyjG3eLWBrtrsI9YX6zeAA==\\n-----END PRIVATE KEY-----\\n\",\"privateCertContent\":\"-----BEGIN CERTIFICATE-----\\nMIID6TCCAtGgAwIBAgIUNkEHq6aQcF80NSYqWS58ybsJzI4wDQYJKoZIhvcNAQEL\\nBQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\\nFFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\\nQ0EwHhcNMjExMDIxMDU0NTQxWhcNMjYxMDIwMDU0NTQxWjB7MRMwEQYDVQQDDAox\\nNTQ1MDgzODgxMRswGQYDVQQKDBLlvq7kv6HllYbmiLfns7vnu58xJzAlBgNVBAsM\\nHuWOhuWfjuWMuuWkp+adjuWwp+aXpeeUqOWTgeW6lzELMAkGA1UEBgwCQ04xETAP\\nBgNVBAcMCFNoZW5aaGVuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\\nuatoWBN5aDkKB5f9pIf3qbo9e1vFaVebwZe8rCVgGwV7seppauICkxw9EFEHYirQ\\nxFJv2ygvQYulVLpJTOWPKAmgm4Y5JR0WxE/I7IHfaYUjRr4h3JWES7EETvKF5zfP\\nZDdMuw2CptIWHZmoktdmd7/FWiJkk6+B1Xh5Qv890upncEq9ut7LSrfd9WE3G04/\\n0BR+857L/TWtLl+i2jARBALCXLVnZvDXa3dbRofRc39AwOVUV7CUd5JFrKcviMIg\\n0z1fxQyjlPTSQksTJg3j3q035KGdrNa5bagStMpAya17cUfoU8xLCmfyqTYvLcmK\\nXzWbL4hyJVLCzxSeVL1IaQIDAQABo4GBMH8wCQYDVR0TBAIwADALBgNVHQ8EBAMC\\nBPAwZQYDVR0fBF4wXDBaoFigVoZUaHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1\\nYmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMw\\nMUMzRThFQkQyMA0GCSqGSIb3DQEBCwUAA4IBAQBe7XgncAY/1PLbCsnMsYt11k3V\\n2cdNZ+yuCxhlOEKk3nHE6WCTL6zL0qWlTKKpnw1rE/+4OS76Tg72wWXcHfHDAOgt\\n9icp62cKx1WO3QweeZpSvLDmtdLgKKrqeIWh+rL8+ZhuAOxSkaRwcsMTWDaLeDOi\\n0pGeqvfG8WNhPxkkaSI8xbiTK641Yg9WT/Q4yfHS7Q6wg1dj9YQdo0dvVB0S2Nir\\nX9IK6PUaHDnQeFKDmKgLkDGLaKaiijEvC91wMEE6qB8b0eNhciaxq2YhGHcFmSRP\\nWUyc5CmBadt7wIOH5Z3bfuwWGxqxKjNw/baM/d+nk7hlDr01YL9c0g16B9MW\\n-----END CERTIFICATE-----\\n\",\"apiV3Key\":\"joerVi8y5DJ3o4ttA0o1uH47Xz1u2Ase\"}', NULL, '2021-10-23 17:12:10', NULL, '2021-10-23 17:12:10', b'0');
  73 +COMMIT;
  74 +
  75 +-- ----------------------------
  76 +-- Table structure for pay_merchant
  77 +-- ----------------------------
  78 +DROP TABLE IF EXISTS `pay_merchant`;
  79 +CREATE TABLE `pay_merchant` (
  80 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '商户编号',
  81 + `no` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商户号',
  82 + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商户全称',
  83 + `short_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商户简称',
  84 + `status` tinyint NOT NULL COMMENT '开启状态',
  85 + `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  86 + `creator` varchar(64) DEFAULT '' COMMENT '创建者',
  87 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  88 + `updater` varchar(64) DEFAULT '' COMMENT '更新者',
  89 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  90 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  91 + PRIMARY KEY (`id`) USING BTREE
  92 +) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='支付商户信息';
  93 +
  94 +-- ----------------------------
  95 +-- Records of pay_merchant
  96 +-- ----------------------------
  97 +BEGIN;
  98 +INSERT INTO `pay_merchant` VALUES (1, 'M233666999', '芋道源码', '芋艿', 0, '我是备注', '', '2021-10-23 08:31:14', '', '2021-10-23 08:44:04', b'0');
  99 +COMMIT;
  100 +
  101 +-- ----------------------------
  102 +-- Table structure for pay_order
  103 +-- ----------------------------
  104 +DROP TABLE IF EXISTS `pay_order`;
  105 +CREATE TABLE `pay_order` (
  106 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '支付订单编号',
  107 + `merchant_id` bigint NOT NULL COMMENT '商户编号',
  108 + `app_id` bigint NOT NULL COMMENT '应用编号',
  109 + `channel_id` bigint NOT NULL COMMENT '渠道编号',
  110 + `channel_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '渠道编码',
  111 + `merchant_order_id` varchar(64) NOT NULL COMMENT '商户订单编号',
  112 + `subject` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品标题',
  113 + `body` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品描述',
  114 + `amount` bigint NOT NULL COMMENT '支付金额,单位:分',
  115 + `channel_fee_rate` double NOT NULL DEFAULT '0' COMMENT '渠道手续费,单位:百分比',
  116 + `channel_fee_amount` bigint NOT NULL DEFAULT '0' COMMENT '渠道手续金额,单位:分',
  117 + `status` tinyint NOT NULL COMMENT '支付状态',
  118 + `notify_status` tinyint NOT NULL COMMENT '通知商户支付结果的回调状态',
  119 + `user_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户 IP',
  120 + `expire_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '订单失效时间',
  121 + `success_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '订单支付成功时间',
  122 + `success_extension_id` bigint DEFAULT NULL COMMENT '支付成功的订单拓展单编号',
  123 + `channel_extras` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '支付渠道的额外参数',
  124 + `notify_url` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '异步通知地址',
  125 + `refund_status` tinyint NOT NULL COMMENT '退款状态',
  126 + `refund_times` tinyint NOT NULL COMMENT '退款次数',
  127 + `refund_amount` bigint NOT NULL COMMENT '退款总金额,单位:分',
  128 + `channel_user_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '渠道用户编号',
  129 + `channel_order_no` varchar(64) DEFAULT NULL COMMENT '渠道订单号',
  130 + `creator` varchar(64) DEFAULT '' COMMENT '创建者',
  131 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  132 + `updater` varchar(64) DEFAULT '' COMMENT '更新者',
  133 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  134 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  135 + PRIMARY KEY (`id`) USING BTREE
  136 +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='支付订单\n';
  137 +
  138 +-- ----------------------------
  139 +-- Records of pay_order
  140 +-- ----------------------------
  141 +BEGIN;
  142 +COMMIT;
  143 +
  144 +-- ----------------------------
  145 +-- Table structure for pay_order_extension
  146 +-- ----------------------------
  147 +DROP TABLE IF EXISTS `pay_order_extension`;
  148 +CREATE TABLE `pay_order_extension` (
  149 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '支付订单编号',
  150 + `no` varchar(64) NOT NULL COMMENT '支付订单号',
  151 + `order_id` bigint NOT NULL COMMENT '支付订单编号',
  152 + `channel_id` bigint NOT NULL COMMENT '渠道编号',
  153 + `channel_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '渠道编码',
  154 + `channel_callback_data` varchar(1024) NOT NULL COMMENT '支付渠道异步通知的内容',
  155 + `user_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户 IP',
  156 + `status` tinyint NOT NULL COMMENT '支付状态',
  157 + `creator` varchar(64) DEFAULT '' COMMENT '创建者',
  158 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  159 + `updater` varchar(64) DEFAULT '' COMMENT '更新者',
  160 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  161 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  162 + PRIMARY KEY (`id`) USING BTREE
  163 +) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='支付订单\n';
  164 +
  165 +-- ----------------------------
  166 +-- Records of pay_order_extension
  167 +-- ----------------------------
  168 +BEGIN;
  169 +INSERT INTO `pay_order_extension` VALUES (9, '', 1, 0, '', '2021-10-23 09:27:37', '', 0, NULL, '2021-10-23 17:12:10', NULL, '2021-10-23 17:12:10', b'0');
  170 +COMMIT;
  171 +
  172 +SET FOREIGN_KEY_CHECKS = 1;
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/service/sms/SysSmsChannelService.java
@@ -11,7 +11,7 @@ import java.util.Collection; @@ -11,7 +11,7 @@ import java.util.Collection;
11 import java.util.List; 11 import java.util.List;
12 12
13 /** 13 /**
14 - * 短信渠道Service接口 14 + * 短信渠道 Service 接口
15 * 15 *
16 * @author zzf 16 * @author zzf
17 * @date 2021/1/25 9:24 17 * @date 2021/1/25 9:24
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/convert/order/PayOrderCoreConvert.java
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO; @@ -4,6 +4,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderDO;
4 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO; 4 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order.PayOrderExtensionDO;
5 import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO; 5 import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderCreateReqDTO;
6 import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO; 6 import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitReqDTO;
  7 +import cn.iocoder.yudao.framework.pay.core.client.dto.PayOrderUnifiedReqDTO;
7 import org.mapstruct.Mapper; 8 import org.mapstruct.Mapper;
8 import org.mapstruct.factory.Mappers; 9 import org.mapstruct.factory.Mappers;
9 10
@@ -16,4 +17,6 @@ public interface PayOrderCoreConvert { @@ -16,4 +17,6 @@ public interface PayOrderCoreConvert {
16 17
17 PayOrderExtensionDO convert(PayOrderSubmitReqDTO bean); 18 PayOrderExtensionDO convert(PayOrderSubmitReqDTO bean);
18 19
  20 + PayOrderUnifiedReqDTO convert2(PayOrderSubmitReqDTO bean);
  21 +
19 } 22 }
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayAppDO.java
@@ -3,7 +3,8 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant; @@ -3,7 +3,8 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant;
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 import com.baomidou.mybatisplus.annotation.TableId; 5 import com.baomidou.mybatisplus.annotation.TableId;
6 -import lombok.Data; 6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
7 8
8 /** 9 /**
9 * 支付应用 DO 10 * 支付应用 DO
@@ -14,7 +15,13 @@ import lombok.Data; @@ -14,7 +15,13 @@ import lombok.Data;
14 * 15 *
15 * @author 芋道源码 16 * @author 芋道源码
16 */ 17 */
  18 +@TableName("pay_app")
17 @Data 19 @Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
18 public class PayAppDO extends BaseDO { 25 public class PayAppDO extends BaseDO {
19 26
20 /** 27 /**
@@ -37,11 +44,6 @@ public class PayAppDO extends BaseDO { @@ -37,11 +44,6 @@ public class PayAppDO extends BaseDO {
37 */ 44 */
38 private String remark; 45 private String remark;
39 /** 46 /**
40 - * 应用私钥  
41 - * TODO 芋艿:用途  
42 - */  
43 - private String secret;  
44 - /**  
45 * 支付结果的回调地址 47 * 支付结果的回调地址
46 */ 48 */
47 private String payNotifyUrl; 49 private String payNotifyUrl;
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDO.java
1 package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant; 1 package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant;
2 2
3 -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;  
4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
6 -import lombok.Data; 5 +import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
  6 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  7 +import com.baomidou.mybatisplus.annotation.TableField;
  8 +import com.baomidou.mybatisplus.annotation.TableName;
  9 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  10 +import lombok.*;
7 11
8 /** 12 /**
9 * 支付渠道 DO 13 * 支付渠道 DO
@@ -14,6 +18,12 @@ import lombok.Data; @@ -14,6 +18,12 @@ import lombok.Data;
14 * @author 芋道源码 18 * @author 芋道源码
15 */ 19 */
16 @Data 20 @Data
  21 +@TableName(value = "pay_channel", autoResultMap = true)
  22 +@EqualsAndHashCode(callSuper = true)
  23 +@ToString(callSuper = true)
  24 +@Builder
  25 +@NoArgsConstructor
  26 +@AllArgsConstructor
17 public class PayChannelDO extends BaseDO { 27 public class PayChannelDO extends BaseDO {
18 28
19 /** 29 /**
@@ -48,8 +58,11 @@ public class PayChannelDO extends BaseDO { @@ -48,8 +58,11 @@ public class PayChannelDO extends BaseDO {
48 * 58 *
49 * 关联 {@link PayAppDO#getId()} 59 * 关联 {@link PayAppDO#getId()}
50 */ 60 */
51 - private String appId;  
52 -  
53 - // TODO 芋艿:不同渠道的配置。暂时考虑硬编码 61 + private Long appId;
  62 + /**
  63 + * 支付渠道配置
  64 + */
  65 + @TableField(typeHandler = JacksonTypeHandler.class)
  66 + private PayClientConfig config;
54 67
55 } 68 }
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayMerchantDO.java
@@ -3,15 +3,22 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant; @@ -3,15 +3,22 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant;
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 4 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
5 import com.baomidou.mybatisplus.annotation.TableId; 5 import com.baomidou.mybatisplus.annotation.TableId;
6 -import lombok.Data; 6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
7 8
8 /** 9 /**
9 - * 商户信息 DO 10 + * 支付商户信息 DO
10 * 目前暂时没有特别的用途,主要为未来多商户提供基础。 11 * 目前暂时没有特别的用途,主要为未来多商户提供基础。
11 * 12 *
12 * @author 芋道源码 13 * @author 芋道源码
13 */ 14 */
14 @Data 15 @Data
  16 +@TableName("pay_merchant")
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
15 public class PayMerchantDO extends BaseDO { 22 public class PayMerchantDO extends BaseDO {
16 23
17 /** 24 /**
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderDO.java
@@ -3,15 +3,16 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order; @@ -3,15 +3,16 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.order;
3 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO; 3 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayAppDO;
4 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; 4 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
5 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO; 5 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayMerchantDO;
6 -import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;  
7 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; 6 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum;
8 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 7 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  8 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  9 +import com.baomidou.mybatisplus.annotation.TableField;
9 import com.baomidou.mybatisplus.annotation.TableName; 10 import com.baomidou.mybatisplus.annotation.TableName;
10 -import lombok.Data;  
11 -import lombok.EqualsAndHashCode;  
12 -import lombok.ToString; 11 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  12 +import lombok.*;
13 13
14 import java.util.Date; 14 import java.util.Date;
  15 +import java.util.Map;
15 16
16 /** 17 /**
17 * 支付订单 DO 18 * 支付订单 DO
@@ -22,6 +23,9 @@ import java.util.Date; @@ -22,6 +23,9 @@ import java.util.Date;
22 @Data 23 @Data
23 @EqualsAndHashCode(callSuper = true) 24 @EqualsAndHashCode(callSuper = true)
24 @ToString(callSuper = true) 25 @ToString(callSuper = true)
  26 +@Builder
  27 +@NoArgsConstructor
  28 +@AllArgsConstructor
25 public class PayOrderDO extends BaseDO { 29 public class PayOrderDO extends BaseDO {
26 30
27 /** 31 /**
@@ -68,10 +72,10 @@ public class PayOrderDO extends BaseDO { @@ -68,10 +72,10 @@ public class PayOrderDO extends BaseDO {
68 * 商品描述信息 72 * 商品描述信息
69 */ 73 */
70 private String body; 74 private String body;
71 - /**  
72 - * 商户拓展参数  
73 - */  
74 - private String merchantExtra; 75 +// /**
  76 +// * 商户拓展参数
  77 +// */
  78 +// private Map<String, String> merchantExtras;
75 79
76 // ========== 订单相关字段 ========== 80 // ========== 订单相关字段 ==========
77 81
@@ -80,13 +84,13 @@ public class PayOrderDO extends BaseDO { @@ -80,13 +84,13 @@ public class PayOrderDO extends BaseDO {
80 */ 84 */
81 private Long amount; 85 private Long amount;
82 /** 86 /**
83 - * 渠道手续费 87 + * 渠道手续费,单位:百分比
84 * 88 *
85 * 冗余 {@link PayChannelDO#getFeeRate()} 89 * 冗余 {@link PayChannelDO#getFeeRate()}
86 */ 90 */
87 private Double channelFeeRate; 91 private Double channelFeeRate;
88 /** 92 /**
89 - * 渠道手续金额 93 + * 渠道手续金额,单位:分
90 */ 94 */
91 private Long channelFeeAmount; 95 private Long channelFeeAmount;
92 /** 96 /**
@@ -101,47 +105,34 @@ public class PayOrderDO extends BaseDO { @@ -101,47 +105,34 @@ public class PayOrderDO extends BaseDO {
101 */ 105 */
102 private Integer notifyStatus; 106 private Integer notifyStatus;
103 /** 107 /**
104 - * 客户端 IP 108 + * 用户 IP
105 */ 109 */
106 - private String clientIp;  
107 - /**  
108 - * 订单支付成功时间  
109 - */  
110 - private Date successTime; 110 + private String userIp;
111 /** 111 /**
112 * 订单失效时间 112 * 订单失效时间
113 */ 113 */
114 private Date expireTime; 114 private Date expireTime;
115 /** 115 /**
116 - * 支付渠道的额外参数  
117 - *  
118 - * 参见 https://www.pingxx.com/api/支付渠道%20extra%20参数说明.html  
119 - */  
120 - private String channelExtra;  
121 - /**  
122 - * 异步通知地址  
123 - */  
124 - private String notifyUrl;  
125 - /**  
126 - * 页面跳转地址 116 + * 订单支付成功时间
127 */ 117 */
128 - private String returnUrl; 118 + private Date successTime;
129 /** 119 /**
130 * 支付成功的订单拓展单编号 120 * 支付成功的订单拓展单编号
131 * 121 *
132 * 关联 {@link PayOrderDO#getId()} 122 * 关联 {@link PayOrderDO#getId()}
133 */ 123 */
134 private Long successExtensionId; 124 private Long successExtensionId;
135 -  
136 - // TODO 芋艿:可能要优化  
137 /** 125 /**
138 - * 渠道支付错误码 126 + * 支付渠道的额外参数
  127 + *
  128 + * 参见 https://www.pingxx.com/api/支付渠道%20extra%20参数说明.html
139 */ 129 */
140 - private String errorCode; 130 + @TableField(typeHandler = JacksonTypeHandler.class)
  131 + private Map<String, String> channelExtras;
141 /** 132 /**
142 - * 渠道支付错误消息 133 + * 异步通知地址
143 */ 134 */
144 - private String errorMessage; 135 + private String notifyUrl;
145 136
146 // ========== 退款相关字段 ========== 137 // ========== 退款相关字段 ==========
147 /** 138 /**
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayOrderExtensionDO.java
@@ -4,9 +4,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChann @@ -4,9 +4,7 @@ import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChann
4 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum; 4 import cn.iocoder.yudao.coreservice.modules.pay.enums.order.PayOrderStatusEnum;
5 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 5 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
6 import com.baomidou.mybatisplus.annotation.TableName; 6 import com.baomidou.mybatisplus.annotation.TableName;
7 -import lombok.Data;  
8 -import lombok.EqualsAndHashCode;  
9 -import lombok.experimental.Accessors; 7 +import lombok.*;
10 8
11 /** 9 /**
12 * 支付订单拓展 DO 10 * 支付订单拓展 DO
@@ -17,7 +15,10 @@ import lombok.experimental.Accessors; @@ -17,7 +15,10 @@ import lombok.experimental.Accessors;
17 @TableName("pay_order_extension") 15 @TableName("pay_order_extension")
18 @Data 16 @Data
19 @EqualsAndHashCode(callSuper = true) 17 @EqualsAndHashCode(callSuper = true)
20 -@Accessors(chain = true) 18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
21 public class PayOrderExtensionDO extends BaseDO { 22 public class PayOrderExtensionDO extends BaseDO {
22 23
23 /** 24 /**
@@ -25,7 +26,7 @@ public class PayOrderExtensionDO extends BaseDO { @@ -25,7 +26,7 @@ public class PayOrderExtensionDO extends BaseDO {
25 */ 26 */
26 private Long id; 27 private Long id;
27 /** 28 /**
28 - * 订单号,根据规则生成 29 + * 支付订单号,根据规则生成
29 * 调用支付渠道时,使用该字段作为对接的订单号。 30 * 调用支付渠道时,使用该字段作为对接的订单号。
30 * 1. 调用微信支付 https://api.mch.weixin.qq.com/pay/unifiedorder 时,使用该字段作为 out_trade_no 31 * 1. 调用微信支付 https://api.mch.weixin.qq.com/pay/unifiedorder 时,使用该字段作为 out_trade_no
31 * 2. 调用支付宝 https://opendocs.alipay.com/apis 时,使用该字段作为 out_trade_no 32 * 2. 调用支付宝 https://opendocs.alipay.com/apis 时,使用该字段作为 out_trade_no
@@ -50,9 +51,9 @@ public class PayOrderExtensionDO extends BaseDO { @@ -50,9 +51,9 @@ public class PayOrderExtensionDO extends BaseDO {
50 */ 51 */
51 private Integer channelCode; 52 private Integer channelCode;
52 /** 53 /**
53 - * 客户端 IP 54 + * 用户 IP
54 */ 55 */
55 - private String clientIp; 56 + private String userIp;
56 /** 57 /**
57 * 支付状态 58 * 支付状态
58 * 59 *
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/order/PayRefundDO.java
@@ -67,10 +67,10 @@ public class PayRefundDO extends BaseDO { @@ -67,10 +67,10 @@ public class PayRefundDO extends BaseDO {
67 * 例如说,内部系统 A 的退款订单号。需要保证每个 PayMerchantDO 唯一 TODO 芋艿:需要在测试下 67 * 例如说,内部系统 A 的退款订单号。需要保证每个 PayMerchantDO 唯一 TODO 芋艿:需要在测试下
68 */ 68 */
69 private String merchantRefundNo; 69 private String merchantRefundNo;
70 - /**  
71 - * 商户拓展参数  
72 - */  
73 - private String merchantExtra; 70 +// /**
  71 +// * 商户拓展参数
  72 +// */
  73 +// private String merchantExtra;
74 74
75 // ========== 退款相关字段 ========== 75 // ========== 退款相关字段 ==========
76 /** 76 /**
@@ -85,9 +85,9 @@ public class PayRefundDO extends BaseDO { @@ -85,9 +85,9 @@ public class PayRefundDO extends BaseDO {
85 */ 85 */
86 private Integer notifyStatus; 86 private Integer notifyStatus;
87 /** 87 /**
88 - * 客户端 IP 88 + * 用户 IP
89 */ 89 */
90 - private String clientIp; 90 + private String userIp;
91 /** 91 /**
92 * 退款金额,单位:分 92 * 退款金额,单位:分
93 */ 93 */
@@ -115,16 +115,6 @@ public class PayRefundDO extends BaseDO { @@ -115,16 +115,6 @@ public class PayRefundDO extends BaseDO {
115 */ 115 */
116 private String notifyUrl; 116 private String notifyUrl;
117 117
118 - // TODO 芋艿:可能要优化  
119 - /**  
120 - * 渠道支付错误码  
121 - */  
122 - private String errorCode;  
123 - /**  
124 - * 渠道支付错误消息  
125 - */  
126 - private String errorMessage;  
127 -  
128 // ========== 渠道相关字段 ========== 118 // ========== 渠道相关字段 ==========
129 /** 119 /**
130 * 渠道订单号 120 * 渠道订单号
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayChannelCoreMapper.java
@@ -3,6 +3,9 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant; @@ -3,6 +3,9 @@ package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant;
3 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; 3 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import org.apache.ibatis.annotations.Mapper; 5 import org.apache.ibatis.annotations.Mapper;
  6 +import org.apache.ibatis.annotations.Select;
  7 +
  8 +import java.util.Date;
6 9
7 @Mapper 10 @Mapper
8 public interface PayChannelCoreMapper extends BaseMapperX<PayChannelDO> { 11 public interface PayChannelCoreMapper extends BaseMapperX<PayChannelDO> {
@@ -11,4 +14,7 @@ public interface PayChannelCoreMapper extends BaseMapperX&lt;PayChannelDO&gt; { @@ -11,4 +14,7 @@ public interface PayChannelCoreMapper extends BaseMapperX&lt;PayChannelDO&gt; {
11 return selectOne("app_id", appId, "code", code); 14 return selectOne("app_id", appId, "code", code);
12 } 15 }
13 16
  17 + @Select("SELECT id FROM pay_channel WHERE update_time > #{maxUpdateTime} LIMIT 1")
  18 + Long selectExistsByUpdateTimeAfter(Date maxUpdateTime);
  19 +
14 } 20 }
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeConstants.java renamed to yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/enums/PayErrorCodeCoreConstants.java
@@ -3,11 +3,11 @@ package cn.iocoder.yudao.coreservice.modules.pay.enums; @@ -3,11 +3,11 @@ package cn.iocoder.yudao.coreservice.modules.pay.enums;
3 import cn.iocoder.yudao.framework.common.exception.ErrorCode; 3 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
4 4
5 /** 5 /**
6 - * Pay 错误码枚举类 6 + * Pay 错误码 Core 枚举类
7 * 7 *
8 * pay 系统,使用 1-007-000-000 段 8 * pay 系统,使用 1-007-000-000 段
9 */ 9 */
10 -public interface PayErrorCodeConstants { 10 +public interface PayErrorCodeCoreConstants {
11 11
12 // ========== APP 模块 1-007-000-000 ========== 12 // ========== APP 模块 1-007-000-000 ==========
13 ErrorCode PAY_APP_NOT_FOUND = new ErrorCode(1007000000, "App 不存在"); 13 ErrorCode PAY_APP_NOT_FOUND = new ErrorCode(1007000000, "App 不存在");
@@ -15,7 +15,8 @@ public interface PayErrorCodeConstants { @@ -15,7 +15,8 @@ public interface PayErrorCodeConstants {
15 15
16 // ========== CHANNEL 模块 1-007-001-000 ========== 16 // ========== CHANNEL 模块 1-007-001-000 ==========
17 ErrorCode PAY_CHANNEL_NOT_FOUND = new ErrorCode(1007001000, "支付渠道的配置不存在"); 17 ErrorCode PAY_CHANNEL_NOT_FOUND = new ErrorCode(1007001000, "支付渠道的配置不存在");
18 - ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001000, "支付渠道已经禁用"); 18 + ErrorCode PAY_CHANNEL_IS_DISABLE = new ErrorCode(1007001001, "支付渠道已经禁用");
  19 + ErrorCode PAY_CHANNEL_CLIENT_NOT_FOUND = new ErrorCode(1007001002, "支付渠道的客户端不存在");
19 20
20 // ========== ORDER 模块 1-007-002-000 ========== 21 // ========== ORDER 模块 1-007-002-000 ==========
21 ErrorCode PAY_ORDER_NOT_FOUND = new ErrorCode(100401000, "支付订单不存在"); 22 ErrorCode PAY_ORDER_NOT_FOUND = new ErrorCode(100401000, "支付订单不存在");
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/PayChannelCoreService.java
@@ -11,6 +11,11 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException; @@ -11,6 +11,11 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
11 public interface PayChannelCoreService { 11 public interface PayChannelCoreService {
12 12
13 /** 13 /**
  14 + * 初始化支付客户端
  15 + */
  16 + void initPayClients();
  17 +
  18 + /**
14 * 支付渠道的合法性 19 * 支付渠道的合法性
15 * 20 *
16 * 如果不合法,抛出 {@link ServiceException} 业务异常 21 * 如果不合法,抛出 {@link ServiceException} 业务异常
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayAppCoreServiceImpl.java
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Service; @@ -10,7 +10,7 @@ import org.springframework.stereotype.Service;
10 import javax.annotation.Resource; 10 import javax.annotation.Resource;
11 import javax.validation.Valid; 11 import javax.validation.Valid;
12 12
13 -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeConstants.*; 13 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
14 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 14 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
15 15
16 /** 16 /**
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/merchant/impl/PayChannelCoreServiceImpl.java
1 package cn.iocoder.yudao.coreservice.modules.pay.service.merchant.impl; 1 package cn.iocoder.yudao.coreservice.modules.pay.service.merchant.impl;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO; 4 import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
4 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant.PayChannelCoreMapper; 5 import cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant.PayChannelCoreMapper;
5 -import cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeConstants; 6 +import cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants;
6 import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayChannelCoreService; 7 import cn.iocoder.yudao.coreservice.modules.pay.service.merchant.PayChannelCoreService;
7 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 8 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  9 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  10 +import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
8 import lombok.extern.slf4j.Slf4j; 11 import lombok.extern.slf4j.Slf4j;
  12 +import org.springframework.scheduling.annotation.Scheduled;
9 import org.springframework.stereotype.Service; 13 import org.springframework.stereotype.Service;
10 14
11 import javax.annotation.Resource; 15 import javax.annotation.Resource;
12 import javax.validation.Valid; 16 import javax.validation.Valid;
13 17
14 -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeConstants.*; 18 +import java.util.Comparator;
  19 +import java.util.Date;
  20 +import java.util.List;
  21 +
  22 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
15 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
16 24
17 /** 25 /**
@@ -24,9 +32,67 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU @@ -24,9 +32,67 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
24 @Slf4j 32 @Slf4j
25 public class PayChannelCoreServiceImpl implements PayChannelCoreService { 33 public class PayChannelCoreServiceImpl implements PayChannelCoreService {
26 34
  35 + /**
  36 + * 定时执行 {@link #schedulePeriodicRefresh()} 的周期
  37 + * 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
  38 + */
  39 + private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
  40 +
  41 + /**
  42 + * 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
  43 + */
  44 + private volatile Date maxUpdateTime;
  45 +
27 @Resource 46 @Resource
28 private PayChannelCoreMapper payChannelCoreMapper; 47 private PayChannelCoreMapper payChannelCoreMapper;
29 48
  49 + @Resource
  50 + private PayClientFactory payClientFactory;
  51 +
  52 + @Override
  53 + public void initPayClients() {
  54 + // 获取支付渠道,如果有更新
  55 + List<PayChannelDO> payChannels = this.loadPayChannelIfUpdate(maxUpdateTime);
  56 + if (CollUtil.isEmpty(payChannels)) {
  57 + return;
  58 + }
  59 +
  60 + // 创建或更新支付 Client
  61 + payChannels.forEach(payChannel -> payClientFactory.createOrUpdatePayClient(payChannel.getId(),
  62 + payChannel.getCode(), payChannel.getConfig()));
  63 +
  64 + // 写入缓存
  65 + assert payChannels.size() > 0; // 断言,避免告警
  66 + maxUpdateTime = payChannels.stream().max(Comparator.comparing(BaseDO::getUpdateTime)).get().getUpdateTime();
  67 + log.info("[initPayClients][初始化 PayChannel 数量为 {}]", payChannels.size());
  68 + }
  69 +
  70 + @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
  71 + public void schedulePeriodicRefresh() {
  72 + initPayClients();
  73 + }
  74 +
  75 + /**
  76 + * 如果支付渠道发生变化,从数据库中获取最新的全量支付渠道。
  77 + * 如果未发生变化,则返回空
  78 + *
  79 + * @param maxUpdateTime 当前支付渠道的最大更新时间
  80 + * @return 支付渠道列表
  81 + */
  82 + private List<PayChannelDO> loadPayChannelIfUpdate(Date maxUpdateTime) {
  83 + // 第一步,判断是否要更新。
  84 + if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
  85 + log.info("[loadPayChannelIfUpdate][首次加载全量支付渠道]");
  86 + } else { // 判断数据库中是否有更新的支付渠道
  87 + if (payChannelCoreMapper.selectExistsByUpdateTimeAfter(maxUpdateTime) == null) {
  88 + return null;
  89 + }
  90 + log.info("[loadPayChannelIfUpdate][增量加载全量支付渠道]");
  91 + }
  92 + // 第二步,如果有更新,则从数据库加载所有支付渠道
  93 + return payChannelCoreMapper.selectList();
  94 + }
  95 +
30 @Override 96 @Override
31 public PayChannelDO validPayChannel(Long appId, String code) { 97 public PayChannelDO validPayChannel(Long appId, String code) {
32 PayChannelDO channel = payChannelCoreMapper.selectByAppIdAndCode(appId, code); 98 PayChannelDO channel = payChannelCoreMapper.selectByAppIdAndCode(appId, code);
@@ -34,7 +100,7 @@ public class PayChannelCoreServiceImpl implements PayChannelCoreService { @@ -34,7 +100,7 @@ public class PayChannelCoreServiceImpl implements PayChannelCoreService {
34 throw exception(PAY_CHANNEL_NOT_FOUND); 100 throw exception(PAY_CHANNEL_NOT_FOUND);
35 } 101 }
36 if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) { 102 if (CommonStatusEnum.DISABLE.getStatus().equals(channel.getStatus())) {
37 - throw exception(PayErrorCodeConstants.PAY_CHANNEL_IS_DISABLE); 103 + throw exception(PayErrorCodeCoreConstants.PAY_CHANNEL_IS_DISABLE);
38 } 104 }
39 return channel; 105 return channel;
40 } 106 }
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderCreateReqDTO.java
@@ -21,10 +21,10 @@ public class PayOrderCreateReqDTO implements Serializable { @@ -21,10 +21,10 @@ public class PayOrderCreateReqDTO implements Serializable {
21 @NotEmpty(message = "应用编号不能为空") 21 @NotEmpty(message = "应用编号不能为空")
22 private Long appId; 22 private Long appId;
23 /** 23 /**
24 - * 客户端 IP 24 + * 用户 IP
25 */ 25 */
26 - @NotEmpty(message = "客户端 IP 不能为空")  
27 - private String clientIp; 26 + @NotEmpty(message = "用户 IP 不能为空")
  27 + private String userIp;
28 28
29 // ========== 商户相关字段 ========== 29 // ========== 商户相关字段 ==========
30 30
@@ -40,7 +40,7 @@ public class PayOrderCreateReqDTO implements Serializable { @@ -40,7 +40,7 @@ public class PayOrderCreateReqDTO implements Serializable {
40 @Length(max = 32, message = "商品标题不能超过 32") 40 @Length(max = 32, message = "商品标题不能超过 32")
41 private String subject; 41 private String subject;
42 /** 42 /**
43 - * 商品描述信息 43 + * 商品描述
44 */ 44 */
45 @NotEmpty(message = "商品描述信息不能为空") 45 @NotEmpty(message = "商品描述信息不能为空")
46 @Length(max = 128, message = "商品描述信息长度不能超过128") 46 @Length(max = 128, message = "商品描述信息长度不能超过128")
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/dto/PayOrderSubmitReqDTO.java
@@ -33,9 +33,9 @@ public class PayOrderSubmitReqDTO implements Serializable { @@ -33,9 +33,9 @@ public class PayOrderSubmitReqDTO implements Serializable {
33 private String channelCode; 33 private String channelCode;
34 34
35 /** 35 /**
36 - * 客户端 IP 36 + * 用户 IP
37 */ 37 */
38 - @NotEmpty(message = "客户端 IP 不能为空")  
39 - private String clientIp; 38 + @NotEmpty(message = "用户 IP 不能为空")
  39 + private String userIp;
40 40
41 } 41 }
yudao-core-service/src/main/java/cn/iocoder/yudao/coreservice/modules/pay/service/order/impl/PayOrderCoreServiceImpl.java
@@ -18,6 +18,8 @@ import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmit @@ -18,6 +18,8 @@ import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmit
18 import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitRespDTO; 18 import cn.iocoder.yudao.coreservice.modules.pay.service.order.dto.PayOrderSubmitRespDTO;
19 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 19 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
20 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 20 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  21 +import cn.iocoder.yudao.framework.pay.core.client.PayClient;
  22 +import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
21 import lombok.extern.slf4j.Slf4j; 23 import lombok.extern.slf4j.Slf4j;
22 import org.springframework.stereotype.Service; 24 import org.springframework.stereotype.Service;
23 25
@@ -25,8 +27,7 @@ import javax.annotation.Resource; @@ -25,8 +27,7 @@ import javax.annotation.Resource;
25 import javax.validation.Valid; 27 import javax.validation.Valid;
26 import java.util.Date; 28 import java.util.Date;
27 29
28 -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeConstants.PAY_ORDER_NOT_FOUND;  
29 -import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeConstants.PAY_ORDER_STATUS_IS_NOT_WAITING; 30 +import static cn.iocoder.yudao.coreservice.modules.pay.enums.PayErrorCodeCoreConstants.*;
30 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
31 32
32 /** 33 /**
@@ -45,6 +46,9 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { @@ -45,6 +46,9 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService {
45 private PayChannelCoreService payChannelCoreService; 46 private PayChannelCoreService payChannelCoreService;
46 47
47 @Resource 48 @Resource
  49 + private PayClientFactory payClientFactory;
  50 +
  51 + @Resource
48 private PayOrderCoreMapper payOrderCoreMapper; 52 private PayOrderCoreMapper payOrderCoreMapper;
49 @Resource 53 @Resource
50 private PayOrderExtensionCoreMapper payOrderExtensionCoreMapper; 54 private PayOrderExtensionCoreMapper payOrderExtensionCoreMapper;
@@ -79,6 +83,12 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { @@ -79,6 +83,12 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService {
79 PayAppDO app = payAppCoreService.validPayApp(reqDTO.getId()); 83 PayAppDO app = payAppCoreService.validPayApp(reqDTO.getId());
80 // 校验支付渠道是否有效 84 // 校验支付渠道是否有效
81 PayChannelDO channel = payChannelCoreService.validPayChannel(reqDTO.getId(), reqDTO.getChannelCode()); 85 PayChannelDO channel = payChannelCoreService.validPayChannel(reqDTO.getId(), reqDTO.getChannelCode());
  86 + // 校验支付客户端是否正确初始化
  87 + PayClient client = payClientFactory.getPayClient(channel.getId());
  88 + if (client == null) {
  89 + log.error("[submitPayOrder][渠道编号({}) 找不到对应的支付客户端]", channel.getId());
  90 + throw exception(PAY_CHANNEL_CLIENT_NOT_FOUND);
  91 + }
82 92
83 // 获得 PayOrderDO ,并校验其是否存在 93 // 获得 PayOrderDO ,并校验其是否存在
84 PayOrderDO order = payOrderCoreMapper.selectById(reqDTO.getId()); 94 PayOrderDO order = payOrderCoreMapper.selectById(reqDTO.getId());
@@ -96,13 +106,14 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService { @@ -96,13 +106,14 @@ public class PayOrderCoreServiceImpl implements PayOrderCoreService {
96 payOrderExtensionCoreMapper.insert(orderExtension); 106 payOrderExtensionCoreMapper.insert(orderExtension);
97 107
98 // 调用三方接口 108 // 调用三方接口
99 - AbstractThirdPayClient thirdPayClient = ThirdPayClientFactory.getThirdPayClient(submitReqDTO.getPayChannel());  
100 - CommonResult<String> invokeResult = thirdPayClient.submitTransaction(payTransaction, orderExtension, null); // TODO 暂时传入 extra = null 109 + // TODO 暂时传入 extra = null
  110 + CommonResult<?> invokeResult = client.unifiedOrder(PayOrderCoreConvert.INSTANCE.convert2(reqDTO));
101 invokeResult.checkError(); 111 invokeResult.checkError();
102 112
103 // TODO 轮询三方接口,是否已经支付的任务 113 // TODO 轮询三方接口,是否已经支付的任务
104 // 返回成功 114 // 返回成功
105 - return new PayOrderSubmitRespDTO().setExtensionId(orderExtension.getId()).setInvokeResponse(invokeResult.getData()); 115 + return new PayOrderSubmitRespDTO().setExtensionId(orderExtension.getId())
  116 + .setInvokeResponse(JsonUtils.toJsonString(invokeResult));
106 } 117 }
107 118
108 private String generateOrderExtensionNo() { 119 private String generateOrderExtensionNo() {
yudao-core-service/src/test-integration/java/cn/iocoder/yudao/coreservice/BaseDbAndRedisIntegrationTest.java 0 → 100644
  1 +package cn.iocoder.yudao.coreservice;
  2 +
  3 +import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
  4 +import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
  5 +import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
  6 +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
  7 +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
  8 +import org.redisson.spring.starter.RedissonAutoConfiguration;
  9 +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
  10 +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  11 +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
  12 +import org.springframework.boot.test.context.SpringBootTest;
  13 +import org.springframework.context.annotation.Import;
  14 +import org.springframework.test.context.ActiveProfiles;
  15 +
  16 +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbAndRedisIntegrationTest.Application.class)
  17 +@ActiveProfiles("integration-test") // 设置使用 application-integration-test 配置文件
  18 +public class BaseDbAndRedisIntegrationTest {
  19 +
  20 + @Import({
  21 + // DB 配置类
  22 + DynamicDataSourceAutoConfiguration.class, // Dynamic Datasource 配置类
  23 + YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
  24 + DataSourceAutoConfiguration.class, // Spring DB 自动配置类
  25 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
  26 + // MyBatis 配置类
  27 + YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
  28 + MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
  29 +
  30 + // Redis 配置类
  31 + RedisAutoConfiguration.class, // Spring Redis 自动配置类
  32 + YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
  33 + RedissonAutoConfiguration.class, // Redisson 自动高配置类
  34 + })
  35 + public static class Application {
  36 + }
  37 +
  38 +}
yudao-core-service/src/test-integration/java/cn/iocoder/yudao/coreservice/BaseDbIntegrationTest.java 0 → 100644
  1 +package cn.iocoder.yudao.coreservice;
  2 +
  3 +import cn.iocoder.yudao.framework.datasource.config.YudaoDataSourceAutoConfiguration;
  4 +import cn.iocoder.yudao.framework.mybatis.config.YudaoMybatisAutoConfiguration;
  5 +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
  6 +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration;
  7 +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
  8 +import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
  9 +import org.springframework.boot.test.context.SpringBootTest;
  10 +import org.springframework.context.annotation.Import;
  11 +import org.springframework.test.context.ActiveProfiles;
  12 +
  13 +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseDbIntegrationTest.Application.class)
  14 +@ActiveProfiles("integration-test") // 设置使用 application-integration-test 配置文件
  15 +public class BaseDbIntegrationTest {
  16 +
  17 + @Import({
  18 + // DB 配置类
  19 + DynamicDataSourceAutoConfiguration.class, // Dynamic Datasource 配置类
  20 + YudaoDataSourceAutoConfiguration.class, // 自己的 DB 配置类
  21 + DataSourceAutoConfiguration.class, // Spring DB 自动配置类
  22 + DataSourceTransactionManagerAutoConfiguration.class, // Spring 事务自动配置类
  23 + // MyBatis 配置类
  24 + YudaoMybatisAutoConfiguration.class, // 自己的 MyBatis 配置类
  25 + MybatisPlusAutoConfiguration.class, // MyBatis 的自动配置类
  26 + })
  27 + public static class Application {
  28 + }
  29 +
  30 +}
yudao-core-service/src/test-integration/java/cn/iocoder/yudao/coreservice/BaseRedisIntegrationTest.java 0 → 100644
  1 +package cn.iocoder.yudao.coreservice;
  2 +
  3 +import cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguration;
  4 +import org.redisson.spring.starter.RedissonAutoConfiguration;
  5 +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
  6 +import org.springframework.boot.test.context.SpringBootTest;
  7 +import org.springframework.context.annotation.Import;
  8 +import org.springframework.test.context.ActiveProfiles;
  9 +
  10 +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = BaseRedisIntegrationTest.Application.class)
  11 +@ActiveProfiles("integration-test") // 设置使用 application-integration-test 配置文件
  12 +public class BaseRedisIntegrationTest {
  13 +
  14 + @Import({
  15 + // Redis 配置类
  16 + RedisAutoConfiguration.class, // Spring Redis 自动配置类
  17 + YudaoRedisAutoConfiguration.class, // 自己的 Redis 配置类
  18 + RedissonAutoConfiguration.class, // Redisson 自动高配置类
  19 + })
  20 + public static class Application {
  21 + }
  22 +
  23 +}
yudao-core-service/src/test-integration/java/cn/iocoder/yudao/coreservice/modules/pay/dal/dataobject/merchant/PayChannelDOTest.java 0 → 100644
  1 +package cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
  4 +import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
  5 +import org.junit.jupiter.api.Test;
  6 +
  7 +public class PayChannelDOTest {
  8 +
  9 + @Test
  10 + public void testSerialization() {
  11 + PayChannelDO payChannelDO = new PayChannelDO();
  12 + // 创建配置
  13 + WXPayClientConfig config = new WXPayClientConfig();
  14 + config.setAppId("wx041349c6f39b268b");
  15 + config.setMchId("1545083881");
  16 + config.setApiVersion(WXPayClientConfig.API_VERSION_V2);
  17 + config.setMchKey("0alL64UDQdlCwiKZ73ib7ypaIjMns06p");
  18 + payChannelDO.setConfig(config);
  19 +
  20 + // 序列化
  21 + String text = JsonUtils.toJsonString(payChannelDO);
  22 + System.out.println(text);
  23 +
  24 + // 反序列化
  25 + payChannelDO = JsonUtils.parseObject(text, PayChannelDO.class);
  26 + System.out.println(payChannelDO.getConfig().getClass());
  27 + }
  28 +
  29 +}
yudao-core-service/src/test-integration/java/cn/iocoder/yudao/coreservice/modules/pay/dal/mysql/merchant/PayChannelCoreMapperTest.java 0 → 100644
  1 +package cn.iocoder.yudao.coreservice.modules.pay.dal.mysql.merchant;
  2 +
  3 +import cn.hutool.core.io.IoUtil;
  4 +import cn.iocoder.yudao.coreservice.BaseDbAndRedisIntegrationTest;
  5 +import cn.iocoder.yudao.coreservice.modules.pay.dal.dataobject.merchant.PayChannelDO;
  6 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  7 +import cn.iocoder.yudao.framework.pay.core.client.impl.wx.WXPayClientConfig;
  8 +import cn.iocoder.yudao.framework.pay.core.enums.PayChannelEnum;
  9 +import org.junit.jupiter.api.Test;
  10 +
  11 +import javax.annotation.Resource;
  12 +import java.io.FileInputStream;
  13 +import java.io.FileNotFoundException;
  14 +import java.util.List;
  15 +
  16 +@Resource
  17 +public class PayChannelCoreMapperTest extends BaseDbAndRedisIntegrationTest {
  18 +
  19 + @Resource
  20 + private PayChannelCoreMapper payChannelCoreMapper;
  21 +
  22 + /**
  23 + * 插入初始配置
  24 + */
  25 + @Test
  26 + public void testInsert() throws FileNotFoundException {
  27 + PayChannelDO payChannelDO = new PayChannelDO();
  28 + payChannelDO.setCode(PayChannelEnum.WX_PUB.getCode());
  29 + payChannelDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
  30 + payChannelDO.setFeeRate(1D);
  31 + payChannelDO.setMerchantId(1L);
  32 + payChannelDO.setAppId(6L);
  33 + // 配置
  34 + WXPayClientConfig config = new WXPayClientConfig();
  35 + config.setAppId("wx041349c6f39b268b");
  36 + config.setMchId("1545083881");
  37 + config.setApiVersion(WXPayClientConfig.API_VERSION_V2);
  38 + config.setMchKey("0alL64UDQdlCwiKZ73ib7ypaIjMns06p");
  39 + config.setPrivateKeyContent(IoUtil.readUtf8(new FileInputStream("/Users/yunai/Downloads/wx_pay/apiclient_key.pem")));
  40 + config.setPrivateCertContent(IoUtil.readUtf8(new FileInputStream("/Users/yunai/Downloads/wx_pay/apiclient_cert.pem")));
  41 + config.setApiV3Key("joerVi8y5DJ3o4ttA0o1uH47Xz1u2Ase");
  42 + payChannelDO.setConfig(config);
  43 + // 执行插入
  44 + payChannelCoreMapper.insert(payChannelDO);
  45 + }
  46 +
  47 + /**
  48 + * 查询所有支付配置,看看是否都是 ok 的
  49 + */
  50 + @Test
  51 + public void testSelectList() {
  52 + List<PayChannelDO> payChannels = payChannelCoreMapper.selectList();
  53 + System.out.println(payChannels.size());
  54 + }
  55 +
  56 +}
yudao-core-service/src/test-integration/resources/application-integration-test.yaml 0 → 100644
  1 +spring:
  2 + main:
  3 + lazy-initialization: true # 开启懒加载,加快速度
  4 + banner-mode: off # 单元测试,禁用 Banner
  5 +
  6 +--- #################### 数据库相关配置 ####################
  7 +
  8 +spring:
  9 + # 数据源配置项
  10 + autoconfigure:
  11 + exclude:
  12 + - com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure # 排除 Druid 的自动配置,使用 dynamic-datasource-spring-boot-starter 配置多数据源
  13 + datasource:
  14 + druid: # Druid 【监控】相关的全局配置
  15 + web-stat-filter:
  16 + enabled: true
  17 + dynamic: # 多数据源配置
  18 + druid: # Druid 【连接池】相关的全局配置
  19 + initial-size: 5 # 初始连接数
  20 + min-idle: 10 # 最小连接池数量
  21 + max-active: 20 # 最大连接池数量
  22 + max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒
  23 + time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒
  24 + min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒
  25 + max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒
  26 + validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效
  27 + test-while-idle: true
  28 + test-on-borrow: false
  29 + test-on-return: false
  30 + primary: master
  31 + datasource:
  32 + master:
  33 + name: ruoyi-vue-pro
  34 + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
  35 + driver-class-name: com.mysql.jdbc.Driver
  36 + username: root
  37 + password: 123456
  38 + slave: # 模拟从库,可根据自己需要修改
  39 + name: ruoyi-vue-pro
  40 + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT
  41 + driver-class-name: com.mysql.jdbc.Driver
  42 + username: root
  43 + password: 123456
  44 +
  45 + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
  46 + redis:
  47 + host: 127.0.0.1 # 地址
  48 + port: 6379 # 端口
  49 + database: 0 # 数据库索引
  50 +
  51 +mybatis:
  52 + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
  53 +mybatis-plus:
  54 + configuration:
  55 + map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
  56 + log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印日志
  57 + global-config:
  58 + db-config:
  59 + id-type: AUTO # 自增 ID
  60 + logic-delete-value: 1 # 逻辑已删除值(默认为 1)
  61 + logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  62 + mapper-locations: classpath*:mapper/*.xml
  63 + type-aliases-package: ${yudao.info.base-package}.modules.*.dal.dataobject, ${yudao.core-service.base-package}.modules.*.dal.dataobject
  64 +
  65 +--- #################### 定时任务相关配置 ####################
  66 +
  67 +--- #################### 配置中心相关配置 ####################
  68 +
  69 +--- #################### 服务保障相关配置 ####################
  70 +
  71 +# Lock4j 配置项(单元测试,禁用 Lock4j)
  72 +
  73 +# Resilience4j 配置项
  74 +resilience4j:
  75 + ratelimiter:
  76 + instances:
  77 + backendA:
  78 + limit-for-period: 1 # 每个周期内,允许的请求数。默认为 50
  79 + limit-refresh-period: 60s # 每个周期的时长,单位:微秒。默认为 500
  80 + timeout-duration: 1s # 被限流时,阻塞等待的时长,单位:微秒。默认为 5s
  81 + register-health-indicator: true # 是否注册到健康监测
  82 +
  83 +--- #################### 监控相关配置 ####################
  84 +
  85 +--- #################### 芋道相关配置 ####################
  86 +
  87 +yudao:
  88 + info:
  89 + version: 1.0.0
  90 + base-package: cn.iocoder.yudao.adminserver
  91 + core-service:
  92 + base-package: cn.iocoder.yudao.coreservice
yudao-framework/yudao-spring-boot-starter-biz-pay/pom.xml
@@ -22,6 +22,12 @@ @@ -22,6 +22,12 @@
22 <artifactId>yudao-common</artifactId> 22 <artifactId>yudao-common</artifactId>
23 </dependency> 23 </dependency>
24 24
  25 + <!-- Spring 核心 -->
  26 + <dependency>
  27 + <groupId>org.springframework.boot</groupId>
  28 + <artifactId>spring-boot-starter</artifactId>
  29 + </dependency>
  30 +
25 <!-- 工具类相关 --> 31 <!-- 工具类相关 -->
26 <dependency> 32 <dependency>
27 <groupId>jakarta.validation</groupId> 33 <groupId>jakarta.validation</groupId>
@@ -47,16 +53,6 @@ @@ -47,16 +53,6 @@
47 </dependency> 53 </dependency>
48 54
49 <!-- 三方云服务相关 --> 55 <!-- 三方云服务相关 -->
50 -<!-- <dependency>-->  
51 -<!-- <groupId>com.github.javen205</groupId>-->  
52 -<!-- <artifactId>IJPay-AliPay</artifactId>-->  
53 -<!-- <version>2.7.8</version>-->  
54 -<!-- </dependency>-->  
55 -<!-- <dependency>-->  
56 -<!-- <groupId>com.github.javen205</groupId>-->  
57 -<!-- <artifactId>IJPay-WxPay</artifactId>-->  
58 -<!-- <version>2.7.8</version>-->  
59 -<!-- </dependency>-->  
60 <dependency> 56 <dependency>
61 <groupId>com.alipay.sdk</groupId> 57 <groupId>com.alipay.sdk</groupId>
62 <artifactId>alipay-sdk-java</artifactId> 58 <artifactId>alipay-sdk-java</artifactId>
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/config/YudaoPayAutoConfiguration.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.pay.config;
  2 +
  3 +import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
  4 +import cn.iocoder.yudao.framework.pay.core.client.impl.PayClientFactoryImpl;
  5 +import org.springframework.context.annotation.Bean;
  6 +import org.springframework.context.annotation.Configuration;
  7 +
  8 +/**
  9 + * 支付配置类
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +@Configuration
  14 +public class YudaoPayAutoConfiguration {
  15 +
  16 + @Bean
  17 + public PayClientFactory payClientFactory() {
  18 + return new PayClientFactoryImpl();
  19 + }
  20 +
  21 +}
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/PayClientConfig.java
1 package cn.iocoder.yudao.framework.pay.core.client; 1 package cn.iocoder.yudao.framework.pay.core.client;
2 2
  3 +import com.fasterxml.jackson.annotation.JsonTypeInfo;
  4 +
3 /** 5 /**
4 * 支付客户端的配置,本质是支付渠道的配置 6 * 支付客户端的配置,本质是支付渠道的配置
5 * 每个不同的渠道,需要不同的配置,通过子类来定义 7 * 每个不同的渠道,需要不同的配置,通过子类来定义
6 * 8 *
7 * @author 芋道源码 9 * @author 芋道源码
8 */ 10 */
  11 +@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
  12 +// @JsonTypeInfo 注解的作用,Jackson 多态
  13 +// 1. 序列化到时数据库时,增加 @class 属性。
  14 +// 2. 反序列化到内存对象时,通过 @class 属性,可以创建出正确的类型
9 public interface PayClientConfig { 15 public interface PayClientConfig {
10 } 16 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/PayOrderUnifiedReqDTO.java
@@ -16,10 +16,10 @@ import java.util.Date; @@ -16,10 +16,10 @@ import java.util.Date;
16 public class PayOrderUnifiedReqDTO { 16 public class PayOrderUnifiedReqDTO {
17 17
18 /** 18 /**
19 - * 客户端 IP 19 + * 用户 IP
20 */ 20 */
21 - @NotEmpty(message = "客户端 IP 不能为空")  
22 - private String clientIp; 21 + @NotEmpty(message = "用户 IP 不能为空")
  22 + private String userIp;
23 23
24 // ========== 商户相关字段 ========== 24 // ========== 商户相关字段 ==========
25 25
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java
@@ -49,7 +49,7 @@ public class AlipayQrPayClient extends AbstractPayClient&lt;AlipayPayClientConfig&gt; @@ -49,7 +49,7 @@ public class AlipayQrPayClient extends AbstractPayClient&lt;AlipayPayClientConfig&gt;
49 model.setSubject(reqDTO.getSubject()); 49 model.setSubject(reqDTO.getSubject());
50 model.setBody(reqDTO.getBody()); 50 model.setBody(reqDTO.getBody());
51 model.setTotalAmount(calculateAmount(reqDTO.getAmount()).toString()); // 单位:元 51 model.setTotalAmount(calculateAmount(reqDTO.getAmount()).toString()); // 单位:元
52 - // TODO 芋艿:clientIp + expireTime 52 + // TODO 芋艿:userIp + expireTime
53 // 构建 AlipayTradePrecreateRequest 53 // 构建 AlipayTradePrecreateRequest
54 AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest(); 54 AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
55 request.setBizModel(model); 55 request.setBizModel(model);
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
@@ -46,7 +46,7 @@ public class AlipayWapPayClient extends AbstractPayClient&lt;AlipayPayClientConfig&gt; @@ -46,7 +46,7 @@ public class AlipayWapPayClient extends AbstractPayClient&lt;AlipayPayClientConfig&gt;
46 model.setTotalAmount(calculateAmount(reqDTO.getAmount()).toString()); 46 model.setTotalAmount(calculateAmount(reqDTO.getAmount()).toString());
47 model.setProductCode("QUICK_WAP_PAY"); // TODO 芋艿:这里咋整 47 model.setProductCode("QUICK_WAP_PAY"); // TODO 芋艿:这里咋整
48 model.setSellerId("2088102147948060"); // TODO 芋艿:这里咋整 48 model.setSellerId("2088102147948060"); // TODO 芋艿:这里咋整
49 - // TODO 芋艿:clientIp + expireTime 49 + // TODO 芋艿:userIp + expireTime
50 // 构建 AlipayTradeWapPayRequest 50 // 构建 AlipayTradeWapPayRequest
51 AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest(); 51 AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
52 request.setBizModel(model); 52 request.setBizModel(model);