# 【小场景训练营】商品下单支付场景,DDD设计实现「支付宝沙箱」

作者:小傅哥
博客:https://bugstack.cn (opens new window)

沉淀、分享、成长,让自己和他人都能有所收获!😄

哈喽,大家伙我是技术UP主小傅哥。

经历了半年多💐,《DDD 技术小册》 整个系列已完成理论知识技术实践两个部分,接下来小傅哥将带着小伙伴们开启DDD 技术小册之场景方案的学习旅程。—— 学理论、练技术、找场景锻炼,综合的学习会快速的提高编程技术。

技术,是承接业务需求提供解决方案的综合运用,而从实际需求中摘取出来的小场景学习,包括;支付、短信、地图、人脸、规则、短信猫、三方登录等,都可以非常好的锻炼思维,提高编码能力。

那么,本节我们先来完成下支付场景在 DDD 领域驱动下的场景设计和编码实现。这里选用支付宝的沙箱支付,因为这个支付对接非常好申请,这样可以方便大家一起参与学习。

文末提供了「星球:码农会锁」优惠加入学习方式,不仅可以学习碎片化的即使知识,还可以综合锻炼实战项目。项目演示地址:https://gaga.plus (opens new window)

# 一、场景说明

在本节小傅哥会带着大家先以最简单的方式完成对接支付验证。再以商品下单模型,通过 DDD 的领域驱动设计,最终完成对支付宝沙箱的对接使用。【如图】

  • 包括;商城、出行、外卖等场景,凡是对接支付,都会先创建一条订单。在基于订单的唯一ID创建支付单。这是因为调用的支付都是外部的接口提供,没法和自己流程做一个统一的事务。那么这里就需要考虑最终一致性问题,要幂等可重试。—— 所以有这样的流程,调单也可以补偿。
  • 商品支付完成后,会收到支付完成的回调。回调调用你提供好的一个接口,用于接收支付完成的通知。这个通知用于变更支付单的状态,以及自己系统内再发一个异步的MQ消息,用于处理后续的流程。
  • 所有的这些流程节点,支付掉单、回调失败、MQ发送失败,在各个流程节点都有唯一ID,所以都可以用定时任务补偿。

# 二、支付申请 - Alipay 沙箱支付

# 1. 沙箱应用

支付宝|开放平台 地址:https://open.alipay.com/develop/manage (opens new window) - 任何人都可以申请,不要企业资质

- 开启沙箱应用以后,还需要下载支付宝秘钥工具。秘钥工具创建的秘钥,需要填写到查看中。 - 📢 【沙箱账号】,里面提供了后续在网页上支付时,输入的账号、密码和支付密码。 - 📢 【沙箱工具】,里面提供了安卓版测试软件,可以在手机扫码支付。

# 2. 秘钥工具

文档中心 | 开放平台 地址:https://opendocs.alipay.com/common/02kipk (opens new window) - 下载支付宝开放平台秘钥工具 在文档的介绍中,也有很详细的说明。

# 3. 秘钥填写

  • 在秘钥工具中生成的应用公钥,复制到如图中填写保存。填写后就可以看到对应的支付宝公钥了。

# 三、简单案例

有了前面这些步骤的申请操作,接下来我们就可以先做一个小支付案例了。这个支付案例在工程代码中 xfg-dev-tech-app ApiTest 下。

# 1. 后端代码

源码cn.bugstack.xfg.dev.tech.test.ApiTest

@Slf4j public class ApiTest { // 「沙箱环境」应用ID - 您的APPID,收款账号既是你的APPID对应支付宝账号。获取地址;https://open.alipay.com/develop/sandbox/app public static String app_id = "9021000132689924"; // 「沙箱环境」商户私钥,你的PKCS8格式RSA2私钥 public static String merchant_private_key = "上文中,【秘钥工具】所创建的公户私钥"; // 「沙箱环境」支付宝公钥 public static String alipay_public_key = "上文中,【秘钥填写】后提供给你的支付宝公钥"; // 「沙箱环境」服务器异步通知页面路径。这里小傅哥用了 natapp.cn 内网穿透工具 public static String notify_url = "https://xfg.natapp.cn/api/v1/alipay/alipay_notify_url"; // 「沙箱环境」页面跳转同步通知页面路径 需http://格式的完整路径,必须外网可以正常访问,才会同步跳转 public static String return_url = "https://gaga.plus"; // 「沙箱环境」 public static String gatewayUrl = "https://openapi-sandbox.dl.alipaydev.com/gateway.do"; // 签名方式 public static String sign_type = "RSA2"; // 字符编码格式 public static String charset = "utf-8"; @Test public void test_AliPay() throws AlipayApiException { AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, app_id, merchant_private_key, "json", charset, alipay_public_key, sign_type); AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); // 发送请求的 Request类 request.setNotifyUrl(notify_url); request.setReturnUrl(return_url); JSONObject bizContent = new JSONObject(); bizContent.put("out_trade_no", "daniel82AAAA000032333361X02"); // 我们自己生成的订单编号 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); } 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

支付配置

  • app_id:应用ID - 您的APPID,收款账号既是你的APPID对应支付宝账号。获取地址;https://open.alipay.com/develop/sandbox/app (opens new window)
  • merchant_private_key:商户私钥,【通过支付宝开放平台秘钥工具】创建出来的私钥。公钥填写到网页上,私钥程序里使用。
  • alipay_public_key:支付宝公钥,在网页上填写公钥后,会给你一个支付宝的公钥。
  • notify_url:服务器异步通知回调地址,也就是你支付完成后,支付宝调用你的地址。因为我们是在本地做测试,外网是访问不到的。所以为了能做这样的测试,可以回调到我们。那么这里需要使用 natapp.cn 做一个内网穿透。
  • return_url:支付完成后跳转的地址
  • gatewayUrl:支付宝沙箱环境的地址,固定的。
  • sign_type:签名方式固定的
  • charset:字符编码固定的

调用配置

  • out_trade_no:你的单号,用你的单号类生成支付单信息。
  • total_amount:支付金额
  • subject:商品名称
  • product_code:固定值;FAST_INSTANT_TRADE_PAY

测试结果

<form name="punchout_form" method="post" action="https://openapi-sandbox.dl.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=J1BBEkS9SIRKTL9sdyFhJ4rUCkJL0HaSOnQ%2BIr5Iy9TdYUigoNfplYfSTFlfjHP8Fq5Me33k7LWNJUH0HzubXxL1vg7P1QOcgzG5K%2Bu5HzWDCkbG4TYhJ%2FOHjYw0nTeRdu%2BkEw%2FMfWr3y4YYpO5oUPEtFMjmvB1UrKmx2%2Buwx0zJk1qrpQWAOfmuS27hf2qda1SVUMs4vdNrKIEKZy1Fysaoo2J6Bqzw2CAFS1QtwN5wm2%2F%2F4uQpxA3TlV1%2BaDvh3Ve5NNTFhiREqW7QPNalFHI0AvGQq6MYKnamaEiNPTFMXUDVsOPFcVqsLZKSvovNlK1CPFp67ZfCTMZP%2BZK3Rw%3D%3D&return_url=https%3A%2F%2Fgaga.plus&notify_url=https%3A%2F%2Fxfg.natapp.cn%2Fapi%2Fv1%2Falipay%2Falipay_notify_url&version=1.0&app_id=9021000132689924&sign_type=RSA2&timestamp=2023-12-17+11%3A55%3A51&alipay_sdk=alipay-sdk-java-4.38.157.ALL&format=json"> <input type="hidden" name="biz_content" value="{&quot;out_trade_no&quot;:&quot;daniel82AAAA000032333361X03&quot;,&quot;total_amount&quot;:&quot;0.01&quot;,&quot;subject&quot;:&quot;测试商品&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;}"> <input type="submit" value="立即支付" style="display:none" > </form> <script>document.forms[0].submit();</script> 
1
2
3
4
5
  • 运行后你会得到一份 HTML 脚本,这份脚本就可以在浏览器打开。
  • 如果你想少量的存储信息,也可以把必要的数据存到数据库,不用全存储。

# 2. 前端代码

到这支付宝的沙箱申请和简单案例已经做完了,之后我们进入场景应用的训练。

# 四、场景介绍

支付,可以说是一个对接的渠道,那么结合到我们的实际场景中应该如何使用呢?比如流程的执行、订单的创建、数据的保存、回调的处理等,这些都是实际业务中要做的东西,接下来我们就做下这个场景学习。

# 1. 支付界面

# 2. 业务流程

# 3. 库表设计

# 五、工程实现

此项目为「星球:码农会锁」小场景训练营的一部分 —— 地址:https://gitcode.net/KnowledgePlanet/ddd-scene-solution (opens new window) - 星球内还包括了大量的实战项目;大营销平台、OpenAI项目、API网关、Lottery抽奖、IM通信、SpringBoot Starter 组件开发、IDEA Plugin 插件开发等

# 1. 工程结构

分层介绍:

  • docs:这里提供了工程所需的资源,docker 安装 msyql、natapp 内网穿透【需要自己申请一个地址】、front 前端页面。
  • app:应用的启动层,处理 config 配置和 resources 资源加载。以及 test 模块的测试。
  • domain:领域层,处理核心业务逻辑。
  • infrastructure:基础设施层,如管理持久化数据。
  • trigger:触发器层,统一管理 http、mq、listener、job 等入口调用。

# 2. 环境安装

# 2.1 MySQL

# 命令执行 docker-compose up -d version: '3.9' services: mysql: image: mysql:8.0.32 container_name: mysql command: --default-authentication-plugin=mysql_native_password restart: always environment: TZ: Asia/Shanghai MYSQL_ROOT_PASSWORD: 123456 MYSQL_USER: xfg MYSQL_PASSWORD: 123456 depends_on: - mysql-job-dbdata ports: - "13306:3306" volumes: - ./sql:/docker-entrypoint-initdb.d volumes_from: - mysql-job-dbdata healthcheck: test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ] interval: 5s timeout: 10s retries: 10 start_period: 15s networks: - my-network # phpmyadmin https://hub.docker.com/_/phpmyadmin phpmyadmin: image: phpmyadmin:5.2.1 container_name: phpmyadmin hostname: phpmyadmin ports: - 8899:80 environment: - PMA_HOST=mysql - PMA_PORT=3306 - MYSQL_ROOT_PASSWORD=123qwe!@#QWE depends_on: mysql: condition: service_healthy networks: - my-network # 自动加载数据 mysql-job-dbdata: image: alpine:3.18.2 container_name: mysql-job-dbdata volumes: - /var/lib/mysql networks: my-network: driver: bridge 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  • 直接在 docker 下安装环境,安装时会自动的帮你把 dev-ops/mysql/sql 下的脚本创建到数据库中。
  • 并且这里提供了 phpmyadmin 可以让你直接在线上就能管理数据库。
  • 如果你本地有 msyql 8.x 那么可以直接导入数据库脚本。dev-ops/mysql/sql/xfg-dev-tech-alipay-sandbox.sql

# 2.2 内网穿透

登录:https://natapp.cn/ (opens new window) - 内网穿透的主要作用就是让你的本地应用地址,可以被支付宝回调调用到

  1. 开通自己的免费/付费渠道,用于内网穿透。本地内网穿透的地址,就可以被公网访问,也就是可以被支付回调。
  2. 开通后,登录后复制自己的渠道 token 粘贴到 config.ini 文件 authtoken 下。如果是Windows电脑,可以自己在官网下载。地址:https://natapp.cn/#download (opens new window)

# 3. 工程配置

源码cn.bugstack.xfg.dev.tech.config.AliPayConfig

@Configuration @EnableConfigurationProperties(AliPayConfigProperties.class) public class AliPayConfig { @Bean(name = "alipayClient") @ConditionalOnProperty(value = "alipay.enabled", havingValue = "true", matchIfMissing = false) 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()); } } 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# application-dev.yml # 支付宝支付 - 沙箱 https://opendocs.alipay.com/common/02kkv7 alipay: enabled: true app_id: 9021000132689924 merchant_private_key: alipay_public_key: notify_url: http://xfg-studio.natapp1.cc/api/v1/alipay/pay_notify return_url: https://gaga.plus gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do 
1
2
3
4
5
6
7
8
9
10
  • 你可以参照【简单案例】配置以上内容,包括;app_id、merchant_private_key、alipay_public_key、notify_url 这些参数。

# 4. 代码实现

# 4.1 订单服务

源码cn.bugstack.xfg.dev.tech.domain.service.IOrderService

public interface IOrderService { /** * 通过购物车实体对象,创建支付单实体(用于支付)—— 所有的订单下单都从购物车开始触发 * * @param shopCartEntity 购物车实体 * @return 支付单实体 */ PayOrderEntity createOrder(ShopCartEntity shopCartEntity) throws Exception; /** * 更新订单状态 * @param orderId 订单ID */ void changeOrderPaySuccess(String orderId); } 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 4.2 模板模式

源码cn.bugstack.xfg.dev.tech.domain.service.AbstractOrderService

@Override public PayOrderEntity createOrder(ShopCartEntity shopCartEntity) throws Exception{ // 1. 查询当前用户是否存在掉单和未支付订单 OrderEntity unpaidOrderEntity = repository.queryUnPayOrder(shopCartEntity); if (null != unpaidOrderEntity && OrderStatusVO.PAY_WAIT.equals(unpaidOrderEntity.getOrderStatus())) { log.info("创建订单-存在,已存在未支付订单。userId:{} productId:{} orderId:{}", shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId()); return PayOrderEntity.builder() .orderId(unpaidOrderEntity.getOrderId()) .payUrl(unpaidOrderEntity.getPayUrl()) .build(); } else if (null != unpaidOrderEntity && OrderStatusVO.CREATE.equals(unpaidOrderEntity.getOrderStatus())) { log.info("创建订单-存在,存在未创建支付单订单,创建支付单开始 userId:{} productId:{} orderId:{}", shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId()); PayOrderEntity payOrderEntity = this.doPrepayOrder(shopCartEntity.getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getProductName(), unpaidOrderEntity.getOrderId(), unpaidOrderEntity.getTotalAmount()); return PayOrderEntity.builder() .orderId(payOrderEntity.getOrderId()) .payUrl(payOrderEntity.getPayUrl()) .build(); } // 2. 查询商品 & 聚合订单 ProductEntity productEntity = repository.queryProductByProductId(shopCartEntity.getProductId()); OrderEntity orderEntity = OrderEntity.builder() .productId(productEntity.getProductId()) .productName(productEntity.getProductName()) .orderId(RandomStringUtils.randomNumeric(16)) .orderTime(new Date()) .orderStatus(OrderStatusVO.CREATE) .build(); CreateOrderAggregate orderAggregate = CreateOrderAggregate.builder() .userId(shopCartEntity.getUserId()) .productEntity(productEntity) .orderEntity(orderEntity) .build(); // 3. 保存订单 - 保存一份订单,再用订单生成ID生成支付单信息 this.doSaveOrder(orderAggregate); // 4. 创建支付单 PayOrderEntity payOrderEntity = this.doPrepayOrder(shopCartEntity.getUserId(), productEntity.getProductId(), productEntity.getProductName(), orderEntity.getOrderId(), productEntity.getPrice()); log.info("创建订单-完成,生成支付单。userId: {} orderId: {} payUrl: {}", shopCartEntity.getUserId(), orderEntity.getOrderId(), payOrderEntity.getPayUrl()); return PayOrderEntity.builder() .orderId(payOrderEntity.getOrderId()) .payUrl(payOrderEntity.getPayUrl()) .build(); } 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  • 通过模板模式,定义出整个下单过程的标准流程和抽象方法。

# 4.3 支付接口

源码cn.bugstack.xfg.dev.tech.trigger.http.AliPayController#createParOrder

@RequestMapping(value = "create_pay_order", method = RequestMethod.POST) public Response<String> createParOrder(@RequestParam String userId, @RequestParam String productId) { try { log.info("商品下单,根据商品ID创建支付单开始 userId:{} productId:{}", userId, productId); ShopCartEntity shopCartEntity = ShopCartEntity.builder().userId(userId).productId(productId).build(); PayOrderEntity payOrderEntity = orderService.createOrder(shopCartEntity); log.info("商品下单,根据商品ID创建支付单完成 userId:{} productId:{} orderId:{}", userId, productId, payOrderEntity.getOrderId()); return Response.<String>builder() .code(ResponseCode.SUCCESS.getCode()) .info(ResponseCode.SUCCESS.getInfo()) .data(payOrderEntity.getPayUrl()) .build(); } catch (Exception e) { log.error("商品下单,根据商品ID创建支付单失败 userId:{} productId:{}", userId, productId, e); return Response.<String>builder() .code(ResponseCode.UN_ERROR.getCode()) .info(ResponseCode.UN_ERROR.getInfo()) .build(); } } 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 4.4 回调接口

源码cn.bugstack.xfg.dev.tech.trigger.http.AliPayController#payNotify

@RequestMapping(value = "pay_notify", method = RequestMethod.POST) public String payNotify(HttpServletRequest request) { try { log.info("支付回调,消息接收 {}", request.getParameter("trade_status")); if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) { Map<String, String> params = new HashMap<>(); Map<String, String[]> 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) { // 验签通过 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); // 更新订单未已支付 orderService.changeOrderPaySuccess(tradeNo); // 推送消息【自己的业务场景中可以使用MQ消息】 eventBus.post(tradeNo); } } return "success"; } catch (Exception e) { log.error("支付回调,处理失败", e); return "false"; } } 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 六、功能验证

# 1. 前置

  1. 安装 MySQL 8.0 数据库 + 初始化库表。如果你是低版本的数据库,需要自己创建下库表。
  2. 打开 natapp.cn 配置一个自己的内网穿透渠道,渠道内配置工程映射地址 8091 如果你是其他端口则配置为其他的地址即可。之后本地启动 natapp
  3. 启动 xfg-dev-tech-alipay-sandbox 应用。

# 2. 测试

# 2.1 启动 natapp

# 2.2 启动工程

# 2.3 下单页面

进入到工程 docs/dev-ops/front 下,打开 index.html 文件。点击下单,这个时候你会进入到支付页面。

# 2.4 商品支付

# 2.5 库表数据

# 3. 日志

23-12-17.15:11:55.692 [http-nio-8091-exec-4] INFO AliPayController - 商品下单,根据商品ID创建支付单开始 userId:xiaofuge productId:100010090091 23-12-17.15:11:55.908 [http-nio-8091-exec-4] INFO AbstractOrderService - 创建订单-完成,生成支付单。userId: xiaofuge orderId: 1620564694789743 payUrl: <form name="punchout_form" method="post" action="https://openapi-sandbox.dl.alipaydev.com/gateway.do?charset=utf-8&method=alipay.trade.page.pay&sign=dh959MC1wu4JD%2B5%2Fxs5HMLaapqFB2zpH5ceDI5B9tIDsNxq22lRawhQcBL%2BNt8zKpb%2BB9fua5VJnm6PGnq0GRqpE2CIwb99stQuTbwyZDRtRq327Dm%2FvQTXw5vil%2FrIkRC9j8SRH9sCk5ZdiedQqoCXZfacNK2dO87T%2BrOACJDT1RkGxJNl4aZ%2FJCrZlGuEcXccc%2BrZVVRY9spBLXOLJwwNcDZkqJtFkxbZUJbZ86hfkW4ihIDf2Q7nMwTyobyINnNgkbfk2z2dxeK8YAccp16Z5P9uMGvhlIqF6u5itcsFFsxoR43n8%2Fj77aKsFbfLUftJ%2BGpEUEY4smAfSV0eyxw%3D%3D&return_url=https%3A%2F%2Fgaga.plus&notify_url=http%3A%2F%2Fxfg-studio.natapp1.cc%2Fapi%2Fv1%2Falipay%2Fpay_notify&version=1.0&app_id=9021000132689924&sign_type=RSA2&timestamp=2023-12-17+15%3A11%3A55&alipay_sdk=alipay-sdk-java-4.38.157.ALL&format=json"> <input type="hidden" name="biz_content" value="{&quot;out_trade_no&quot;:&quot;1620564694789743&quot;,&quot;total_amount&quot;:&quot;1.68&quot;,&quot;subject&quot;:&quot;测试商品&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;}"> <input type="submit" value="立即支付" style="display:none" > </form> <script>document.forms[0].submit();</script> 23-12-17.15:11:55.909 [http-nio-8091-exec-4] INFO AliPayController - 商品下单,根据商品ID创建支付单完成 userId:xiaofuge productId:100010090091 orderId:1620564694789743 23-12-17.15:12:37.553 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,消息接收 TRADE_SUCCESS 23-12-17.15:12:37.558 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,交易名称: 测试商品 23-12-17.15:12:37.558 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,交易状态: TRADE_SUCCESS 23-12-17.15:12:37.558 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,支付宝交易凭证号: 2023121722001413370501437659 23-12-17.15:12:37.558 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,商户订单号: 1620564694789743 23-12-17.15:12:37.558 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,交易金额: 1.68 23-12-17.15:12:37.562 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,买家在支付宝唯一id: 2088722024513370 23-12-17.15:12:37.562 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,买家付款时间: 2023-12-17 15:12:35 23-12-17.15:12:37.562 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,买家付款金额: 1.68 23-12-17.15:12:37.562 [http-nio-8091-exec-5] INFO AliPayController - 支付回调,支付回调,更新订单 1620564694789743 23-12-17.15:12:37.584 [http-nio-8091-exec-5] INFO OrderPaySuccessListener - 收到支付成功消息,可以做接下来的事情了【发货、充值、开会员】orderId:1620564694789743 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • 以上为整个项目运行过程所产生的日志数据。通过日志可清楚知道每一步的操作过程。

# 七、加入学习

注意📢,本项目也只是【星球:码农会锁】众多项目中的1个,其他的项目还包括:大营销平台系统、OpenAI 大模型应用、API网关、Lottery抽奖、IM通信、SpringBoot Starter 组件开发、IDEA Plugin 插件开发等,并还有开源项目学习。

如果大家希望通过做有价值的编程项目,提高自己的编程思维和编码能力,可以加入小傅哥的【星球:码农会锁】。加入后解锁🔓所有往期项目,还可以学习后续新开发的项目。

🧧加入学习 (opens new window)

加入后即可解锁全部学习资源,项目演示地址:https://gaga.plus (opens new window)