From 267e2508208f3ac1a8f7b76635b05892ca227875 Mon Sep 17 00:00:00 2001
From: zhangsan <646228430@qq.com>
Date: Sun, 13 Jul 2025 14:28:15 +0800
Subject: [PATCH] =?UTF-8?q?7.13=20=E6=94=AF=E4=BB=98=E5=AE=9D=E6=94=AF?=
=?UTF-8?q?=E4=BB=98=E6=B2=99=E7=AE=B1=E7=94=B3=E8=AF=B7=E3=80=81=E5=AF=B9?=
=?UTF-8?q?=E6=8E=A5alipay?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 1 +
docs/dev-ops/mysql/sql/0713paymall.sql | 48 ++++++++
.../dev-ops/mysql/sql/xfg-frame-archetype.sql | 108 -----------------
pay-mall-api/pom.xml | 4 +
.../main/java/edu/whut/api/IPayService.java | 10 ++
.../edu/whut/api/dto/CreatePayRequestDTO.java | 13 ++
.../java/edu/whut/api/dto/package-info.java | 4 -
.../java/edu/whut/config/AliPayConfig.java | 23 ++++
.../whut/config/AliPayConfigProperties.java | 31 +++++
.../src/main/resources/application-dev.yml | 20 +++-
.../src/main/resources/application.yml | 4 +-
.../mybatis/mapper/pay_order_mapper.xml | 5 +
.../test/java/edu/whut/test/AliPayTest.java | 111 ++++++++++++++++++
pay-mall-domain/pom.xml | 5 +
.../adapter/repository/IOrderRepository.java | 2 +
.../order/service/AbstractOrderService.java | 19 ++-
.../domain/order/service/OrderService.java | 47 ++++++++
.../adapter/repository/OrderRepository.java | 14 ++-
.../whut/infrastructure/dao/IOrderDao.java | 2 +
.../whut/trigger/http/AliPayController.java | 107 +++++++++++++++++
.../trigger/http/WeixinPortalController.java | 2 +
.../java/edu/whut/types/common/Constants.java | 1 +
pom.xml | 7 +-
23 files changed, 462 insertions(+), 126 deletions(-)
create mode 100644 docs/dev-ops/mysql/sql/0713paymall.sql
delete mode 100644 docs/dev-ops/mysql/sql/xfg-frame-archetype.sql
create mode 100644 pay-mall-api/src/main/java/edu/whut/api/IPayService.java
create mode 100644 pay-mall-api/src/main/java/edu/whut/api/dto/CreatePayRequestDTO.java
delete mode 100644 pay-mall-api/src/main/java/edu/whut/api/dto/package-info.java
create mode 100644 pay-mall-app/src/main/java/edu/whut/config/AliPayConfig.java
create mode 100644 pay-mall-app/src/main/java/edu/whut/config/AliPayConfigProperties.java
create mode 100644 pay-mall-app/src/test/java/edu/whut/test/AliPayTest.java
create mode 100644 pay-mall-trigger/src/main/java/edu/whut/trigger/http/AliPayController.java
diff --git a/.gitignore b/.gitignore
index 613ee2d..3127462 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,4 @@ build/
.DS_Store
/data/
/.idea/
+/pay-mall-app/src/main/resources/application-local.yml
diff --git a/docs/dev-ops/mysql/sql/0713paymall.sql b/docs/dev-ops/mysql/sql/0713paymall.sql
new file mode 100644
index 0000000..4ef4bc0
--- /dev/null
+++ b/docs/dev-ops/mysql/sql/0713paymall.sql
@@ -0,0 +1,48 @@
+/*
+ Navicat Premium Data Transfer
+
+ Source Server : group_buy_local
+ Source Server Type : MySQL
+ Source Server Version : 80042
+ Source Host : localhost:13306
+ Source Schema : pay-mall
+
+ Target Server Type : MySQL
+ Target Server Version : 80042
+ File Encoding : 65001
+
+ Date: 13/07/2025 14:21:55
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for pay_order
+-- ----------------------------
+DROP TABLE IF EXISTS `pay_order`;
+CREATE TABLE `pay_order` (
+ `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增ID',
+ `user_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户ID',
+ `product_id` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品ID',
+ `product_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品名称',
+ `order_id` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '订单ID',
+ `order_time` datetime NOT NULL COMMENT '下单时间',
+ `total_amount` decimal(8, 2) UNSIGNED NULL DEFAULT NULL COMMENT '订单金额',
+ `status` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '订单状态;create-创建完成、pay_wait-等待支付、pay_success-支付成功、deal_done-交易完成、close-订单关单',
+ `pay_url` varchar(2014) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '支付信息',
+ `pay_time` datetime NULL DEFAULT NULL COMMENT '支付时间',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ PRIMARY KEY (`id`) USING BTREE,
+ UNIQUE INDEX `uq_order_id`(`order_id` ASC) USING BTREE,
+ INDEX `idx_user_id_product_id`(`user_id` ASC, `product_id` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of pay_order
+-- ----------------------------
+INSERT INTO `pay_order` VALUES (5, 'smile01', '10001', '测试商品', '51403944017404', '2025-07-12 05:49:16', 1.68, 'PAY_WAIT', '
\n', NULL, '2025-07-12 13:49:15', '2025-07-13 14:21:33');
+INSERT INTO `pay_order` VALUES (6, '10001', '10001', '测试商品', '66665553128265', '2025-07-13 06:19:11', 1.68, 'PAY_WAIT', '\n', NULL, '2025-07-13 14:19:11', '2025-07-13 14:21:21');
+
+SET FOREIGN_KEY_CHECKS = 1;
diff --git a/docs/dev-ops/mysql/sql/xfg-frame-archetype.sql b/docs/dev-ops/mysql/sql/xfg-frame-archetype.sql
deleted file mode 100644
index 8b598d3..0000000
--- a/docs/dev-ops/mysql/sql/xfg-frame-archetype.sql
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- Navicat Premium Data Transfer
-
- Source Server : 127.0.0.1
- Source Server Type : MySQL
- Source Server Version : 50639
- Source Host : localhost:3306
- Source Schema : road-map
-
- Target Server Type : MySQL
- Target Server Version : 50639
- File Encoding : 65001
-
- Date: 15/07/2023 09:26:39
-*/
-
-SET NAMES utf8mb4;
-SET FOREIGN_KEY_CHECKS = 0;
-
-CREATE database if NOT EXISTS `xfg_frame_archetype` default character set utf8mb4 collate utf8mb4_0900_ai_ci;
-use `xfg_frame_archetype`;
-
--- ----------------------------
--- Table structure for employee
--- ----------------------------
-DROP TABLE IF EXISTS `employee`;
-CREATE TABLE `employee` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `employee_number` varchar(16) NOT NULL DEFAULT '' COMMENT '雇员ID',
- `employee_name` varchar(32) NOT NULL DEFAULT '' COMMENT '雇员姓名',
- `employee_level` varchar(8) NOT NULL DEFAULT '' COMMENT '雇员级别',
- `employee_title` varchar(16) NOT NULL DEFAULT '' COMMENT '雇员岗位Title',
- `create_time` datetime NOT NULL COMMENT '创建时间',
- `update_time` datetime NOT NULL COMMENT '更新时间',
- PRIMARY KEY (`id`),
- UNIQUE KEY `idx_employee_number` (`employee_number`)
-) ENGINE=InnoDB AUTO_INCREMENT=40 DEFAULT CHARSET=utf8;
-
--- ----------------------------
--- Records of employee
--- ----------------------------
-BEGIN;
-INSERT INTO `employee` VALUES (1, '10000001', 'sXvfDpsWnJdLsCVk64tJgw==', 'T-3', '中级工程师', '2023-07-14 15:26:26', '2023-07-14 15:26:26');
-INSERT INTO `employee` VALUES (2, '10000010', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
-INSERT INTO `employee` VALUES (3, '10000011', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
-INSERT INTO `employee` VALUES (4, '10000012', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
-INSERT INTO `employee` VALUES (5, '10000013', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
-INSERT INTO `employee` VALUES (6, '10000014', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-14 15:34:40', '2023-07-14 15:34:40');
-INSERT INTO `employee` VALUES (9, '10000002', 'sXvfDpsWnJdLsCVk64tJgw==', 'T2', '见习工程师', '2023-07-15 07:42:52', '2023-07-15 07:42:52');
-INSERT INTO `employee` VALUES (22, '10000015', 'hMCgLG6WV3CsNBQ1UD6PEQ==', 'T2', '见习工程师', '2023-07-15 08:02:31', '2023-07-15 08:02:31');
-INSERT INTO `employee` VALUES (23, '10000016', 'hMCgLG6WV3CsNBQ1UD6PEQ==', 'T2', '见习工程师', '2023-07-15 08:02:31', '2023-07-15 08:02:31');
-INSERT INTO `employee` VALUES (24, '10000017', 'hMCgLG6WV3CsNBQ1UD6PEQ==', 'T2', '见习工程师', '2023-07-15 08:02:31', '2023-07-15 08:02:31');
-INSERT INTO `employee` VALUES (39, '10000022', 'GyG+V0r6mBCNsdusuKl03g==', 'T1', '实习工程师', '2023-07-15 09:17:49', '2023-07-15 09:17:49');
-COMMIT;
-
--- ----------------------------
--- Table structure for employee_salary
--- ----------------------------
-DROP TABLE IF EXISTS `employee_salary`;
-CREATE TABLE `employee_salary` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `employee_number` varchar(16) NOT NULL DEFAULT '' COMMENT '雇员编号',
- `salary_total_amount` decimal(8,2) NOT NULL COMMENT '薪资总额',
- `salary_merit_amount` decimal(8,2) NOT NULL COMMENT '绩效工资',
- `salary_base_amount` decimal(8,2) NOT NULL COMMENT '基础工资',
- `create_time` datetime NOT NULL COMMENT '创建时间',
- `update_time` datetime DEFAULT NULL COMMENT '更新时间',
- PRIMARY KEY (`id`),
- KEY `idx_employee_number` (`employee_number`)
-) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
-
--- ----------------------------
--- Records of employee_salary
--- ----------------------------
-BEGIN;
-INSERT INTO `employee_salary` VALUES (1, '10000001', 5100.00, 1020.00, 4080.00, '2023-07-14 16:09:06', '2023-07-14 16:09:06');
-INSERT INTO `employee_salary` VALUES (2, '10000010', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
-INSERT INTO `employee_salary` VALUES (3, '10000011', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
-INSERT INTO `employee_salary` VALUES (4, '10000012', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
-INSERT INTO `employee_salary` VALUES (5, '10000013', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
-INSERT INTO `employee_salary` VALUES (6, '10000014', 5000.00, 1000.00, 4000.00, '2023-07-14 16:17:10', '2023-07-14 16:17:10');
-INSERT INTO `employee_salary` VALUES (8, '10000022', 100.00, 10.00, 90.00, '2023-07-15 09:17:49', '2023-07-15 09:17:49');
-COMMIT;
-
--- ----------------------------
--- Table structure for employee_salary_adjust
--- ----------------------------
-DROP TABLE IF EXISTS `employee_salary_adjust`;
-CREATE TABLE `employee_salary_adjust` (
- `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
- `employee_number` varchar(16) NOT NULL DEFAULT '' COMMENT '雇员编号',
- `adjust_order_id` varchar(32) NOT NULL DEFAULT '' COMMENT '调薪单号',
- `adjust_total_amount` decimal(8,2) NOT NULL COMMENT '总额调薪',
- `adjust_base_amount` decimal(8,2) NOT NULL COMMENT '基础调薪',
- `adjust_merit_amount` decimal(8,2) NOT NULL COMMENT '绩效调薪',
- `create_time` datetime NOT NULL COMMENT '创建时间',
- `update_time` datetime NOT NULL COMMENT '更新时间',
- PRIMARY KEY (`id`),
- UNIQUE KEY `idx_order_id` (`adjust_order_id`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-
--- ----------------------------
--- Records of employee_salary_adjust
--- ----------------------------
-BEGIN;
-INSERT INTO `employee_salary_adjust` VALUES (1, '10000001', '109089990198888811', 1000.00, 800.00, 200.00, '2023-07-14 16:55:53', '2023-07-14 16:55:53');
-INSERT INTO `employee_salary_adjust` VALUES (2, '10000001', '100908977676001', 100.00, 20.00, 80.00, '2023-07-14 21:57:39', '2023-07-14 21:57:39');
-COMMIT;
\ No newline at end of file
diff --git a/pay-mall-api/pom.xml b/pay-mall-api/pom.xml
index cb6db6b..68a2b1a 100644
--- a/pay-mall-api/pom.xml
+++ b/pay-mall-api/pom.xml
@@ -20,6 +20,10 @@
jakarta.validation-api
3.0.2
+
+ com.squareup.okhttp3
+ okhttp
+
diff --git a/pay-mall-api/src/main/java/edu/whut/api/IPayService.java b/pay-mall-api/src/main/java/edu/whut/api/IPayService.java
new file mode 100644
index 0000000..a7d285e
--- /dev/null
+++ b/pay-mall-api/src/main/java/edu/whut/api/IPayService.java
@@ -0,0 +1,10 @@
+package edu.whut.api;
+
+import edu.whut.api.dto.CreatePayRequestDTO;
+import edu.whut.api.response.Response;
+
+public interface IPayService {
+
+ Response createPayOrder(CreatePayRequestDTO createPayRequestDTO);
+
+}
diff --git a/pay-mall-api/src/main/java/edu/whut/api/dto/CreatePayRequestDTO.java b/pay-mall-api/src/main/java/edu/whut/api/dto/CreatePayRequestDTO.java
new file mode 100644
index 0000000..3473ab6
--- /dev/null
+++ b/pay-mall-api/src/main/java/edu/whut/api/dto/CreatePayRequestDTO.java
@@ -0,0 +1,13 @@
+package edu.whut.api.dto;
+
+import lombok.Data;
+
+@Data
+public class CreatePayRequestDTO {
+
+ // 用户ID 【实际产生中会通过登录模块获取,不需要透彻】
+ private String userId;
+ // 产品编号
+ private String productId;
+
+}
diff --git a/pay-mall-api/src/main/java/edu/whut/api/dto/package-info.java b/pay-mall-api/src/main/java/edu/whut/api/dto/package-info.java
deleted file mode 100644
index e19888a..0000000
--- a/pay-mall-api/src/main/java/edu/whut/api/dto/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * 数据传输对象 xxxRequestDTO xxxResponseDTO
- */
-package edu.whut.api.dto;
\ No newline at end of file
diff --git a/pay-mall-app/src/main/java/edu/whut/config/AliPayConfig.java b/pay-mall-app/src/main/java/edu/whut/config/AliPayConfig.java
new file mode 100644
index 0000000..294ba42
--- /dev/null
+++ b/pay-mall-app/src/main/java/edu/whut/config/AliPayConfig.java
@@ -0,0 +1,23 @@
+package edu.whut.config;
+
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AliPayConfig {
+
+ @Bean("alipayClient")
+ public AlipayClient alipayClient(AliPayConfigProperties properties) {
+ return new DefaultAlipayClient(properties.getGatewayUrl(),
+ properties.getApp_id(),
+ properties.getMerchant_private_key(),
+ properties.getFormat(),
+ properties.getCharset(),
+ properties.getAlipay_public_key(),
+ properties.getSign_type());
+ }
+
+}
diff --git a/pay-mall-app/src/main/java/edu/whut/config/AliPayConfigProperties.java b/pay-mall-app/src/main/java/edu/whut/config/AliPayConfigProperties.java
new file mode 100644
index 0000000..cda1520
--- /dev/null
+++ b/pay-mall-app/src/main/java/edu/whut/config/AliPayConfigProperties.java
@@ -0,0 +1,31 @@
+package edu.whut.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "alipay", ignoreInvalidFields = true)
+public class AliPayConfigProperties {
+
+ // 「沙箱环境」应用ID - 您的APPID,收款账号既是你的APPID对应支付宝账号。获取地址;https://open.alipay.com/develop/sandbox/app
+ private String app_id;
+ // 「沙箱环境」商户私钥,你的PKCS8格式RSA2私钥
+ private String merchant_private_key;
+ // 「沙箱环境」支付宝公钥
+ private String alipay_public_key;
+ // 「沙箱环境」服务器异步通知页面路径
+ private String notify_url;
+ // 「沙箱环境」页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
+ private String return_url;
+ // 「沙箱环境」
+ private String gatewayUrl;
+ // 签名方式
+ private String sign_type = "RSA2";
+ // 字符编码格式
+ private String charset = "utf-8";
+ // 传输格式
+ private String format = "json";
+
+}
diff --git a/pay-mall-app/src/main/resources/application-dev.yml b/pay-mall-app/src/main/resources/application-dev.yml
index 8ef3c6c..dae3ecb 100644
--- a/pay-mall-app/src/main/resources/application-dev.yml
+++ b/pay-mall-app/src/main/resources/application-dev.yml
@@ -38,11 +38,21 @@ mybatis:
# 微信公众号对接
weixin:
config:
- originalid: gh_b748269e1f4c
- token: asdf
- app-id: wx7cc74be9b340b26e
- app-secret: d4e73551512c6dc7a2e8f746c26b7f2c
- template_id: ARDqdKXuGvASjsDqXzeunq0P8chMQ7tXk_4-BPULJ6U
+ original-id: ${paymall.wechat.original-id}
+ token: ${paymall.wechat.token}
+ app-id: ${paymall.wechat.app-id}
+ app-secret: ${paymall.wechat.app-secret}
+ template_id: ${paymall.wechat.template-id}
+
+# 支付宝支付 - 沙箱 https://opendocs.alipay.com/common/02kkv7
+alipay:
+ enabled: true
+ app_id: ${paymall.alipay.app-id}
+ merchant_private_key: ${paymall.alipay.merchant-private-key}
+ alipay_public_key: ${paymall.alipay.alipay-public-key}
+ notify_url: ${paymall.alipay.notify-url}
+ return_url: ${paymall.alipay.return-url}
+ gateway-url: ${paymall.alipay.gateway-url}
# 日志
logging:
diff --git a/pay-mall-app/src/main/resources/application.yml b/pay-mall-app/src/main/resources/application.yml
index da00f44..7f350e7 100644
--- a/pay-mall-app/src/main/resources/application.yml
+++ b/pay-mall-app/src/main/resources/application.yml
@@ -1,5 +1,3 @@
spring:
- config:
- name: pay-mall-app
profiles:
- active: dev
+ active: dev,local
diff --git a/pay-mall-app/src/main/resources/mybatis/mapper/pay_order_mapper.xml b/pay-mall-app/src/main/resources/mybatis/mapper/pay_order_mapper.xml
index b0eaf7f..3f7f78c 100644
--- a/pay-mall-app/src/main/resources/mybatis/mapper/pay_order_mapper.xml
+++ b/pay-mall-app/src/main/resources/mybatis/mapper/pay_order_mapper.xml
@@ -32,4 +32,9 @@
limit 1
+
+ update pay_order set pay_url = #{payUrl}, status = #{status}, update_time = now()
+ where order_id = #{orderId}
+
+
diff --git a/pay-mall-app/src/test/java/edu/whut/test/AliPayTest.java b/pay-mall-app/src/test/java/edu/whut/test/AliPayTest.java
new file mode 100644
index 0000000..fab6c8b
--- /dev/null
+++ b/pay-mall-app/src/test/java/edu/whut/test/AliPayTest.java
@@ -0,0 +1,111 @@
+package edu.whut.test;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.domain.AlipayTradeQueryModel;
+import com.alipay.api.domain.AlipayTradeRefundModel;
+import com.alipay.api.request.AlipayTradePagePayRequest;
+import com.alipay.api.request.AlipayTradeQueryRequest;
+import com.alipay.api.request.AlipayTradeRefundRequest;
+import com.alipay.api.response.AlipayTradeRefundResponse;
+import edu.whut.config.AliPayConfigProperties;
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.math.BigDecimal;
+
+@Slf4j
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class AliPayTest {
+ @Autowired
+ private AliPayConfigProperties config; // 字段注入
+
+ private AlipayClient alipayClient;
+
+
+ @Before
+ public void init() {
+ log.info(config.getNotify_url());
+ // ④ 用属性里的值来构造 AlipayClient
+ this.alipayClient = new DefaultAlipayClient(
+ config.getGatewayUrl(),
+ config.getApp_id(),
+ config.getMerchant_private_key(),
+ config.getFormat(),
+ config.getCharset(),
+ config.getAlipay_public_key(),
+ config.getSign_type()
+ );
+ }
+
+ @Test
+ public void test_aliPay_pageExecute() throws AlipayApiException {
+ AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); // 发送请求的 Request类
+ request.setNotifyUrl(config.getNotify_url());
+ request.setReturnUrl(config.getReturn_url());
+
+ JSONObject bizContent = new JSONObject();
+ bizContent.put("out_trade_no", "smile000091004001"); // 我们自己生成的订单编号
+ bizContent.put("total_amount", "0.01"); // 订单的总金额
+ bizContent.put("subject", "测试商品"); // 支付的名称
+ bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); // 固定配置
+ request.setBizContent(bizContent.toString());
+
+ String form = alipayClient.pageExecute(request).getBody();
+ log.info("测试结果:{}", form);
+
+ /**
+ * 会生成一个form表单;
+
+
+ */
+ }
+
+ /**
+ * 查询订单
+ */
+ @Test
+ public void test_alipay_certificateExecute() throws AlipayApiException {
+
+ AlipayTradeQueryModel bizModel = new AlipayTradeQueryModel();
+ bizModel.setOutTradeNo("daniel82AAAA000032333361Y001");
+
+ AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
+ request.setBizModel(bizModel);
+
+ String body = alipayClient.execute(request).getBody();
+ log.info("测试结果:{}", body);
+ }
+
+ /**
+ * 退款接口
+ */
+ @Test
+ public void test_alipay_refund() throws AlipayApiException {
+ AlipayTradeRefundRequest request =new AlipayTradeRefundRequest();
+ AlipayTradeRefundModel refundModel =new AlipayTradeRefundModel();
+ refundModel.setOutTradeNo("daniel82AAAA000032333361X03");
+ refundModel.setRefundAmount("1.00");
+ refundModel.setRefundReason("退款说明");
+ request.setBizModel(refundModel);
+
+ AlipayTradeRefundResponse execute = alipayClient.execute(request);
+ log.info("测试结果:{}", execute.isSuccess());
+ }
+
+ public static void main(String[] args) {
+ System.out.println(new BigDecimal("9.99").doubleValue());
+ }
+
+}
\ No newline at end of file
diff --git a/pay-mall-domain/pom.xml b/pay-mall-domain/pom.xml
index e321001..bf1f15d 100644
--- a/pay-mall-domain/pom.xml
+++ b/pay-mall-domain/pom.xml
@@ -38,6 +38,11 @@
commons-codec
commons-codec
+
+
+ com.alipay.sdk
+ alipay-sdk-java
+
edu.whut
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/order/adapter/repository/IOrderRepository.java b/pay-mall-domain/src/main/java/edu/whut/domain/order/adapter/repository/IOrderRepository.java
index 86a2512..70e2f5d 100644
--- a/pay-mall-domain/src/main/java/edu/whut/domain/order/adapter/repository/IOrderRepository.java
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/order/adapter/repository/IOrderRepository.java
@@ -2,6 +2,7 @@ package edu.whut.domain.order.adapter.repository;
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
import edu.whut.domain.order.model.entity.OrderEntity;
+import edu.whut.domain.order.model.entity.PayOrderEntity;
import edu.whut.domain.order.model.entity.ShopCartEntity;
public interface IOrderRepository {
@@ -9,4 +10,5 @@ public interface IOrderRepository {
OrderEntity queryUnPayOrder(ShopCartEntity shopCartEntity);
+ void updateOrderPayInfo(PayOrderEntity payOrderEntity);
}
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/order/service/AbstractOrderService.java b/pay-mall-domain/src/main/java/edu/whut/domain/order/service/AbstractOrderService.java
index f6cdbfb..78ae7ec 100644
--- a/pay-mall-domain/src/main/java/edu/whut/domain/order/service/AbstractOrderService.java
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/order/service/AbstractOrderService.java
@@ -1,5 +1,6 @@
package edu.whut.domain.order.service;
+import com.alipay.api.AlipayApiException;
import edu.whut.domain.order.adapter.port.IProductPort;
import edu.whut.domain.order.adapter.repository.IOrderRepository;
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
@@ -10,6 +11,8 @@ import edu.whut.domain.order.model.entity.ShopCartEntity;
import edu.whut.domain.order.model.valobj.OrderStatusVO;
import lombok.extern.slf4j.Slf4j;
+import java.math.BigDecimal;
+
@Slf4j
public abstract class AbstractOrderService implements IOrderService {
@@ -36,9 +39,14 @@ public abstract class AbstractOrderService implements IOrderService {
.orderId(unpaidOrderEntity.getOrderId())
.payUrl(unpaidOrderEntity.getPayUrl())
.build();
- // TODO: 如果存在“已创建未支付”状态
- } else if (null != unpaidOrderEntity && OrderStatusVO.CREATE.equals(unpaidOrderEntity.getOrderStatusVO())) {
+ } else if (null != unpaidOrderEntity && OrderStatusVO.CREATE.equals(unpaidOrderEntity.getOrderStatusVO())) {
+ log.info("创建订单-存在,存在未创建'支付单'订单,创建支付单开始 userId:{} productId:{} orderId:{}", shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId());
+ PayOrderEntity payOrderEntity = doPrepayOrder(shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getProductName(), unpaidOrderEntity.getOrderId(), unpaidOrderEntity.getTotalAmount());
+ return PayOrderEntity.builder()
+ .orderId(payOrderEntity.getOrderId())
+ .payUrl(payOrderEntity.getPayUrl())
+ .build();
}
// 2. 调用产品服务,查询商品详细信息
@@ -57,10 +65,14 @@ public abstract class AbstractOrderService implements IOrderService {
// 5. 交由子类实现,保存订单聚合
this.doSaveOrder(orderAggregate);
+ PayOrderEntity payOrderEntity = doPrepayOrder(shopCartEntity.getUserId(), productEntity.getProductId(), productEntity.getProductName(), orderEntity.getOrderId(), productEntity.getPrice());
+ log.info("创建订单-完成,生成支付单。userId: {} orderId: {} payUrl: {}", shopCartEntity.getUserId(), orderEntity.getOrderId(), payOrderEntity.getPayUrl());
+
+
// 6. 返回支付实体
return PayOrderEntity.builder()
.orderId(orderEntity.getOrderId())
- .payUrl("暂无")
+ .payUrl(payOrderEntity.getPayUrl())
.build();
}
@@ -69,4 +81,5 @@ public abstract class AbstractOrderService implements IOrderService {
*/
protected abstract void doSaveOrder(CreateOrderAggregate orderAggregate);
+ protected abstract PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount) throws AlipayApiException;
}
diff --git a/pay-mall-domain/src/main/java/edu/whut/domain/order/service/OrderService.java b/pay-mall-domain/src/main/java/edu/whut/domain/order/service/OrderService.java
index 2d0ee41..c376a77 100644
--- a/pay-mall-domain/src/main/java/edu/whut/domain/order/service/OrderService.java
+++ b/pay-mall-domain/src/main/java/edu/whut/domain/order/service/OrderService.java
@@ -1,14 +1,32 @@
package edu.whut.domain.order.service;
+import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.request.AlipayTradePagePayRequest;
import edu.whut.domain.order.adapter.port.IProductPort;
import edu.whut.domain.order.adapter.repository.IOrderRepository;
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
+import edu.whut.domain.order.model.entity.PayOrderEntity;
+import edu.whut.domain.order.model.valobj.OrderStatusVO;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+
@Slf4j
@Service
public class OrderService extends AbstractOrderService{
+ @Value("${alipay.notify_url}")
+ private String notifyUrl;
+ @Value("${alipay.return_url}")
+ private String returnUrl;
+
+ @Resource
+ private AlipayClient alipayClient;
+
public OrderService(IOrderRepository repository, IProductPort port) {
super(repository, port);
}
@@ -18,4 +36,33 @@ public class OrderService extends AbstractOrderService{
repository.doSaveOrder(orderAggregate);
}
+ /**
+ * 预支付订单
+ */
+ @Override
+ protected PayOrderEntity doPrepayOrder(String userId, String productId, String productName, String orderId, BigDecimal totalAmount) throws AlipayApiException {
+ AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
+ request.setNotifyUrl(notifyUrl);
+ request.setReturnUrl(returnUrl);
+
+ JSONObject bizContent = new JSONObject();
+ bizContent.put("out_trade_no", orderId);
+ bizContent.put("total_amount", totalAmount.toString());
+ bizContent.put("subject", productName);
+ bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
+ request.setBizContent(bizContent.toString());
+
+ String form = alipayClient.pageExecute(request).getBody();
+
+ PayOrderEntity payOrderEntity = new PayOrderEntity();
+ payOrderEntity.setOrderId(orderId);
+ payOrderEntity.setPayUrl(form);
+ //等待支付
+ payOrderEntity.setOrderStatus(OrderStatusVO.PAY_WAIT);
+
+ repository.updateOrderPayInfo(payOrderEntity);
+
+ return payOrderEntity;
+ }
+
}
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/OrderRepository.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/OrderRepository.java
index 2cdf6d7..24b5b30 100644
--- a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/OrderRepository.java
+++ b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/adapter/repository/OrderRepository.java
@@ -3,6 +3,7 @@ package edu.whut.infrastructure.adapter.repository;
import edu.whut.domain.order.adapter.repository.IOrderRepository;
import edu.whut.domain.order.model.aggregate.CreateOrderAggregate;
import edu.whut.domain.order.model.entity.OrderEntity;
+import edu.whut.domain.order.model.entity.PayOrderEntity;
import edu.whut.domain.order.model.entity.ProductEntity;
import edu.whut.domain.order.model.entity.ShopCartEntity;
import edu.whut.domain.order.model.valobj.OrderStatusVO;
@@ -11,8 +12,6 @@ import edu.whut.infrastructure.dao.po.PayOrder;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
-import javax.annotation.Resource;
-
@Repository
@RequiredArgsConstructor
public class OrderRepository implements IOrderRepository {
@@ -59,4 +58,15 @@ public class OrderRepository implements IOrderRepository {
.payUrl(order.getPayUrl())
.build();
}
+
+ @Override
+ public void updateOrderPayInfo(PayOrderEntity payOrderEntity) {
+ PayOrder payOrderReq = PayOrder.builder()
+ .userId(payOrderEntity.getUserId())
+ .orderId(payOrderEntity.getOrderId())
+ .status(payOrderEntity.getOrderStatus().getCode())
+ .payUrl(payOrderEntity.getPayUrl())
+ .build();
+ orderDao.updateOrderPayInfo(payOrderReq);
+ }
}
diff --git a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/IOrderDao.java b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/IOrderDao.java
index ea24e9b..17ff527 100644
--- a/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/IOrderDao.java
+++ b/pay-mall-infrastructure/src/main/java/edu/whut/infrastructure/dao/IOrderDao.java
@@ -9,4 +9,6 @@ public interface IOrderDao {
PayOrder queryUnPayOrder(PayOrder payOrder);
+ void updateOrderPayInfo(PayOrder payOrder);
+
}
diff --git a/pay-mall-trigger/src/main/java/edu/whut/trigger/http/AliPayController.java b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/AliPayController.java
new file mode 100644
index 0000000..3aba484
--- /dev/null
+++ b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/AliPayController.java
@@ -0,0 +1,107 @@
+package edu.whut.trigger.http;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.internal.util.AlipaySignature;
+import edu.whut.api.IPayService;
+import edu.whut.api.dto.CreatePayRequestDTO;
+import edu.whut.api.response.Response;
+import edu.whut.domain.order.model.entity.PayOrderEntity;
+import edu.whut.domain.order.model.entity.ShopCartEntity;
+import edu.whut.domain.order.service.IOrderService;
+import edu.whut.types.common.Constants;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+@RestController()
+@CrossOrigin("*")
+@RequiredArgsConstructor
+@RequestMapping("/api/v1/alipay")
+public class AliPayController implements IPayService {
+
+ @Value("${alipay.alipay_public_key}")
+ private String alipayPublicKey;
+
+ private final IOrderService orderService;
+
+ /**
+ * {
+ * "userId": "10001",
+ * "productId": "10001"
+ * }
+ */
+ @PostMapping("/create_pay_order")
+ @Override
+ public Response createPayOrder(@RequestBody CreatePayRequestDTO createPayRequestDTO) {
+ try {
+ log.info("商品下单,根据商品ID创建支付单开始 userId:{} productId:{}", createPayRequestDTO.getUserId(), createPayRequestDTO.getUserId());
+ String userId = createPayRequestDTO.getUserId();
+ String productId = createPayRequestDTO.getProductId();
+ // 下单
+ PayOrderEntity payOrderEntity = orderService.createOrder(ShopCartEntity.builder()
+ .userId(userId)
+ .productId(productId)
+ .build());
+
+ log.info("商品下单,根据商品ID创建支付单完成 userId:{} productId:{} orderId:{}", userId, productId, payOrderEntity.getOrderId());
+ return Response.builder()
+ .code(Constants.ResponseCode.SUCCESS.getCode())
+ .info(Constants.ResponseCode.SUCCESS.getInfo())
+ .data(payOrderEntity.getPayUrl())
+ .build();
+ } catch (Exception e) {
+ log.error("商品下单,根据商品ID创建支付单失败 userId:{} productId:{}", createPayRequestDTO.getUserId(), createPayRequestDTO.getUserId(), e);
+ return Response.builder()
+ .code(Constants.ResponseCode.UN_ERROR.getCode())
+ .info(Constants.ResponseCode.UN_ERROR.getInfo())
+ .build();
+ }
+ }
+
+ @PostMapping("/alipay_notify_url")
+ public String payNotify(HttpServletRequest request) throws AlipayApiException {
+ log.info("支付回调,消息接收 {}", request.getParameter("trade_status"));
+
+ if (!request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
+ return "false";
+ }
+
+ Map params = new HashMap<>();
+ Map requestParams = request.getParameterMap();
+ for (String name : requestParams.keySet()) {
+ params.put(name, request.getParameter(name));
+ }
+
+ String tradeNo = params.get("out_trade_no");
+ String gmtPayment = params.get("gmt_payment");
+ String alipayTradeNo = params.get("trade_no");
+
+ String sign = params.get("sign");
+ String content = AlipaySignature.getSignCheckContentV1(params);
+ boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, alipayPublicKey, "UTF-8"); // 验证签名
+ // 支付宝验签
+ if (!checkSignature) {
+ return "false";
+ }
+
+ // 验签通过
+ log.info("支付回调,交易名称: {}", params.get("subject"));
+ log.info("支付回调,交易状态: {}", params.get("trade_status"));
+ log.info("支付回调,支付宝交易凭证号: {}", params.get("trade_no"));
+ log.info("支付回调,商户订单号: {}", params.get("out_trade_no"));
+ log.info("支付回调,交易金额: {}", params.get("total_amount"));
+ log.info("支付回调,买家在支付宝唯一id: {}", params.get("buyer_id"));
+ log.info("支付回调,买家付款时间: {}", params.get("gmt_payment"));
+ log.info("支付回调,买家付款金额: {}", params.get("buyer_pay_amount"));
+ log.info("支付回调,支付回调,更新订单 {}", tradeNo);
+
+ return "success";
+ }
+
+}
diff --git a/pay-mall-trigger/src/main/java/edu/whut/trigger/http/WeixinPortalController.java b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/WeixinPortalController.java
index be9498e..4c4b06a 100644
--- a/pay-mall-trigger/src/main/java/edu/whut/trigger/http/WeixinPortalController.java
+++ b/pay-mall-trigger/src/main/java/edu/whut/trigger/http/WeixinPortalController.java
@@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
/**
+ * 微信会回调该接口
* https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index 平台地址
* https://pay.bitday.top/api/v1/weixin/portal/receive 内网穿透
*/
@@ -73,6 +74,7 @@ public class WeixinPortalController {
MessageTextEntity message = XmlUtil.xmlToBean(requestBody, MessageTextEntity.class);
if ("event".equals(message.getMsgType()) && "SCAN".equals(message.getEvent())) {
+ //存储用户登录状态
loginService.saveLoginState(message.getTicket(), openid);
return buildMessageTextEntity(openid, "登录成功");
}
diff --git a/pay-mall-types/src/main/java/edu/whut/types/common/Constants.java b/pay-mall-types/src/main/java/edu/whut/types/common/Constants.java
index a0c2b99..b36cfdd 100644
--- a/pay-mall-types/src/main/java/edu/whut/types/common/Constants.java
+++ b/pay-mall-types/src/main/java/edu/whut/types/common/Constants.java
@@ -21,4 +21,5 @@ public class Constants {
private String info;
}
+
}
diff --git a/pom.xml b/pom.xml
index ad612de..732d994 100644
--- a/pom.xml
+++ b/pom.xml
@@ -130,7 +130,12 @@
adapter-rxjava2
2.9.0
-
+
+
+ com.alipay.sdk
+ alipay-sdk-java
+ 4.38.157.ALL
+
edu.whut