mirror of
http://124.126.16.154:8888/singularity/hdk-pay.git
synced 2026-01-15 07:15:06 +08:00
Compare commits
90 Commits
v1.0.0-bet
...
v1.11.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e92a6f46a4 | ||
|
|
e0748e444b | ||
|
|
244dd1220a | ||
|
|
8a9971bc59 | ||
|
|
4c5dde9020 | ||
|
|
1cb20a7c7e | ||
|
|
028721feb1 | ||
|
|
bd00102081 | ||
|
|
7763b088df | ||
|
|
cd56a6214b | ||
|
|
31559fdf5d | ||
|
|
41d768ba82 | ||
|
|
c552dd8ed0 | ||
|
|
e7e1c7f6c9 | ||
|
|
7e0d711e99 | ||
|
|
eb44b6e3b6 | ||
|
|
3af39e4254 | ||
|
|
8bbc8ed629 | ||
|
|
48e6fafe8e | ||
|
|
874a6f4fa9 | ||
|
|
8ac850fc62 | ||
|
|
8f8f7b08b0 | ||
|
|
203dd34353 | ||
|
|
87b09ef34c | ||
|
|
a59d979076 | ||
|
|
686d835a91 | ||
|
|
65b060e5d3 | ||
|
|
3b12216344 | ||
|
|
7354abb99a | ||
|
|
93f923181c | ||
|
|
fb3327b252 | ||
|
|
975a5ee301 | ||
|
|
580c2f6ca0 | ||
|
|
15c0ecb6fe | ||
|
|
fb54e19366 | ||
|
|
366f1d64ad | ||
|
|
72f7d37382 | ||
|
|
2a40b3b219 | ||
|
|
86f375b18a | ||
|
|
8a70e35de7 | ||
|
|
06a198714e | ||
|
|
c2358ae19b | ||
|
|
5a4edf9258 | ||
|
|
d17a67f58e | ||
|
|
23aa9b68bf | ||
|
|
48f44f4c4c | ||
|
|
25612823a5 | ||
|
|
c8681a6d54 | ||
|
|
c8f3acd62b | ||
|
|
d3b861a7f7 | ||
|
|
630d4ba7a4 | ||
|
|
b3317c5f8d | ||
|
|
66a468e702 | ||
|
|
dd212ad8a2 | ||
|
|
0d4f561ef0 | ||
|
|
aa8742923c | ||
|
|
738d225fd8 | ||
|
|
38ce644c73 | ||
|
|
f2a51fa1da | ||
|
|
59b5118b93 | ||
|
|
c468fdda0e | ||
|
|
24709acf09 | ||
|
|
f141989a8d | ||
|
|
fd6548e144 | ||
|
|
acc3121320 | ||
|
|
b521e7c9e0 | ||
|
|
2276885ac1 | ||
|
|
8d2d3c8ba5 | ||
|
|
86939ea421 | ||
|
|
960e3f1877 | ||
|
|
2ea5227185 | ||
|
|
c7f94bb396 | ||
|
|
9d61106e2e | ||
|
|
c3a256cb3d | ||
|
|
245f13b26d | ||
|
|
fc5cf453ae | ||
|
|
8f71cbeb65 | ||
|
|
9517b5bd62 | ||
|
|
c8ee3bb23b | ||
|
|
80dc1a3706 | ||
|
|
ca6000a5c8 | ||
|
|
1814adc30e | ||
|
|
06dc4a2e65 | ||
|
|
a2fc4cecf8 | ||
|
|
1bb8666b5e | ||
|
|
5559f2c2a5 | ||
|
|
4f0d402538 | ||
|
|
336cb3a9b9 | ||
|
|
3d91f76dc0 | ||
|
|
7f7fe100e7 |
@@ -17,6 +17,8 @@ jobs:
|
||||
ls ${{ gitea.workspace }}
|
||||
- name: Zip files in the repository
|
||||
run: |
|
||||
sed -i 's|deb.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list
|
||||
sed -i 's|security.debian.org|mirrors.aliyun.com|g' /etc/apt/sources.list
|
||||
apt-get update
|
||||
apt-get install zip
|
||||
zip -r dist.zip *
|
||||
|
||||
297
CHANGELOG.md
297
CHANGELOG.md
@@ -1,4 +1,301 @@
|
||||
# 版本更新日志
|
||||
### [1.11.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.11.0...v1.11.1) (2025-11-27)
|
||||
|
||||
## [1.11.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.10.0...v1.11.0) (2025-11-27)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **invoice:** 添加发票金额和货币支持 ([244dd12](http://124.126.16.154:8888/singularity/hdk-pay/commit/244dd1220a2c19197ef08f41a82bcb273d0900e8))
|
||||
|
||||
## [1.10.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.7...v1.10.0) (2025-11-25)
|
||||
|
||||
|
||||
### 🚀 Chore | 构建/工程依赖/工具
|
||||
|
||||
* **deps:** 移除 Carbon 依赖包 ([028721f](http://124.126.16.154:8888/singularity/hdk-pay/commit/028721feb1079eaa4fe80f20066912d46634f3df))
|
||||
|
||||
|
||||
### ✅ Tests | 测试
|
||||
|
||||
* **product:** 移除测试中的 only 标记 ([1cb20a7](http://124.126.16.154:8888/singularity/hdk-pay/commit/1cb20a7c7e2c1a26c7b72669e6885d39f8d16005))
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **invoice:** 引入点数价格值对象并更新发票产品结构 ([4c5dde9](http://124.126.16.154:8888/singularity/hdk-pay/commit/4c5dde9020364573d0e9673138620d967149e9f0))
|
||||
|
||||
### [1.9.7](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.6...v1.9.7) (2025-10-30)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **account:** 添加4D X无限奖励积分类型 ([7763b08](http://124.126.16.154:8888/singularity/hdk-pay/commit/7763b088dff711f2d95e65ec8437000322931f50))
|
||||
|
||||
### [1.9.6](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.5...v1.9.6) (2025-09-19)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **Domain:** 重构 ExchangeRepoInterface 接口 ([31559fd](http://124.126.16.154:8888/singularity/hdk-pay/commit/31559fdf5ddec048680f520563fa7de56eae3e90))
|
||||
|
||||
### [1.9.5](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.4...v1.9.5) (2025-09-19)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **domain:** 更新汇率接口并添加 UID 参数 ([e7e1c7f](http://124.126.16.154:8888/singularity/hdk-pay/commit/e7e1c7f6c946fa171cdbf8049f1d90864a043685))
|
||||
* **ProductRepo:** 优化 getRate 方法参数处理 ([c552dd8](http://124.126.16.154:8888/singularity/hdk-pay/commit/c552dd8ed0b00f58fefa47c02219ce4de972e85c))
|
||||
|
||||
### [1.9.4](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.3...v1.9.4) (2025-09-19)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **product:** 修复产品列表中点数显示问题 ([eb44b6e](http://124.126.16.154:8888/singularity/hdk-pay/commit/eb44b6e3b6e9a2e3f757076d0d4438163e7d1f51))
|
||||
|
||||
### [1.9.3](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.2...v1.9.3) (2025-09-19)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **PointType:** 添加 ScanToModel 作为点类型 ([8bbc8ed](http://124.126.16.154:8888/singularity/hdk-pay/commit/8bbc8ed629e5c15e42db0adf758505e531ff3dca))
|
||||
|
||||
### [1.9.2](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.1...v1.9.2) (2025-09-19)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **Account:** 添加新的积分类型 ([874a6f4](http://124.126.16.154:8888/singularity/hdk-pay/commit/874a6f4fa96b09a4c6c652b6d285d4b6631a3c66))
|
||||
|
||||
### [1.9.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.9.0...v1.9.1) (2025-09-17)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **account:** 修复初始账户命令和测试 ([8f8f7b0](http://124.126.16.154:8888/singularity/hdk-pay/commit/8f8f7b08b03d9b810bb09ce4b1f15a27cbd43e68))
|
||||
|
||||
## [1.9.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.8.2...v1.9.0) (2025-09-17)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **account:** 添加初始化账户余额功能 ([87b09ef](http://124.126.16.154:8888/singularity/hdk-pay/commit/87b09ef34cd3427816ef2c357406a74975ada8a9))
|
||||
|
||||
### [1.8.2](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.8.1...v1.8.2) (2025-09-17)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **ProductRepo:** 修复产品仓库中的数组为空的处理逻辑 ([686d835](http://124.126.16.154:8888/singularity/hdk-pay/commit/686d835a9130d60768eef37a3c9a67c6526cb418))
|
||||
|
||||
### [1.8.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.8.0...v1.8.1) (2025-09-05)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **PointLog:** 添加获取病人姓名的方法并更新相关代码 ([3b12216](http://124.126.16.154:8888/singularity/hdk-pay/commit/3b1221634419f0ca39359e36c0363602b075b9b8))
|
||||
|
||||
## [1.8.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.7.0...v1.8.0) (2025-09-05)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **invoice:** 添加发票详情查询功能 ([93f9231](http://124.126.16.154:8888/singularity/hdk-pay/commit/93f923181c41ce7e96077f304efe6e980231f1f6))
|
||||
|
||||
## [1.7.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.6.1...v1.7.0) (2025-09-04)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **account:** 增加积分日志详情查询功能并支持发票信息 ([975a5ee](http://124.126.16.154:8888/singularity/hdk-pay/commit/975a5ee30110f27ceba0ef11fba751639189d57b))
|
||||
|
||||
### [1.6.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.6.0...v1.6.1) (2025-09-04)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **invoice:** 添加发票下载和发送功能 ([15c0ecb](http://124.126.16.154:8888/singularity/hdk-pay/commit/15c0ecb6fe8f227b09c4d4618ffb2f5560e4b261))
|
||||
|
||||
## [1.6.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.5.3...v1.6.0) (2025-09-04)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **invoice:** 添加发票下载功能并优化测试 ([366f1d6](http://124.126.16.154:8888/singularity/hdk-pay/commit/366f1d64add68d1bb8a9b3e5f17b23963a91d3bc))
|
||||
* **invoice:** 添加发票发送功能并进行测试 ([72f7d37](http://124.126.16.154:8888/singularity/hdk-pay/commit/72f7d37382752047ed4c15809f16c3f1d07e16e0))
|
||||
|
||||
### [1.5.3](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.5.2...v1.5.3) (2025-09-04)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **invoice:** 重构发票创建流程和积分日志接口 ([8a70e35](http://124.126.16.154:8888/singularity/hdk-pay/commit/8a70e35de72d269bbbd0b5e05c3fa4bccdf1878c))
|
||||
* **PointLogRepo:** 优化 getList 方法参数类型 ([86f375b](http://124.126.16.154:8888/singularity/hdk-pay/commit/86f375b18a0c3213e405b6fcaec20224979dd991))
|
||||
|
||||
### [1.5.2](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.5.1...v1.5.2) (2025-09-02)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **AccountBalanceRepo:** 修复积分余额过期时间解析 ([c2358ae](http://124.126.16.154:8888/singularity/hdk-pay/commit/c2358ae19b072dc0f84a76949ce748f9ce15da4f))
|
||||
|
||||
### [1.5.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.5.0...v1.5.1) (2025-09-01)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **RechargeProductRepoInterface:** 添加查找 FTAI 产品的方法 ([d17a67f](http://124.126.16.154:8888/singularity/hdk-pay/commit/d17a67f58ee2772191e30eb52c09923f43425989))
|
||||
|
||||
## [1.5.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.4.1...v1.5.0) (2025-09-01)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **product:** 支持查询 FTAI 产品 ([48f44f4](http://124.126.16.154:8888/singularity/hdk-pay/commit/48f44f4c4ceef95e7315ce52924ea3729f8214f5))
|
||||
|
||||
### [1.4.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.4.0...v1.4.1) (2025-08-29)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **invoice:** 移除 getCaseProduct 方法中未使用的参数 ([c8681a6](http://124.126.16.154:8888/singularity/hdk-pay/commit/c8681a6d5445b8b9177a236e41aee25d63d50315))
|
||||
|
||||
## [1.4.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.3.1...v1.4.0) (2025-08-28)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **invoice:** 更新 InvoiceProduct 类的位置 ([66a468e](http://124.126.16.154:8888/singularity/hdk-pay/commit/66a468e702a0b550ce7445c66164b10b4edcc41a))
|
||||
* **invoice:** 重构发票相关类的命名空间 ([630d4ba](http://124.126.16.154:8888/singularity/hdk-pay/commit/630d4ba7a427bc7bece24093f783634d3e707b2f))
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **invoice:** 新增发票商品查询功能 ([dd212ad](http://124.126.16.154:8888/singularity/hdk-pay/commit/dd212ad8a26f03f2b6e204e5485120e267ba73a2))
|
||||
* **invoice:** 添加创建发票功能 ([b3317c5](http://124.126.16.154:8888/singularity/hdk-pay/commit/b3317c5f8d65aae811130f4af9d09cce514047ff))
|
||||
* **invoice:** 添加查询用户常用发票地址功能 ([d3b861a](http://124.126.16.154:8888/singularity/hdk-pay/commit/d3b861a7f75281168ec16562aec290f1904fda7e))
|
||||
|
||||
### [1.3.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.3.0...v1.3.1) (2025-08-27)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **account:** 优化点数日志仓库接口和实现类 ([aa87429](http://124.126.16.154:8888/singularity/hdk-pay/commit/aa8742923c38ae90386c83b8a280a47dacc3537b))
|
||||
|
||||
## [1.3.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.7...v1.3.0) (2025-08-27)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **Account:** 重构账户相关类的命名空间 ([f2a51fa](http://124.126.16.154:8888/singularity/hdk-pay/commit/f2a51fa1da67d5169761bc47cbe2b6da605051ae))
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **account:** 添加积分日志相关功能 ([38ce644](http://124.126.16.154:8888/singularity/hdk-pay/commit/38ce644c7351740641901a0497351f45c0119339))
|
||||
|
||||
### [1.2.7](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.6...v1.2.7) (2025-08-26)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* 更新发布流程以使用阿里云镜像源 ([c468fdd](http://124.126.16.154:8888/singularity/hdk-pay/commit/c468fdda0e4fd8bf5b2253527b368362ccb81954))
|
||||
|
||||
### [1.2.6](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.5...v1.2.6) (2025-08-26)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **Order:** 重构订单资源以支持经典订单解析 ([f141989](http://124.126.16.154:8888/singularity/hdk-pay/commit/f141989a8d7c6055d0d740619cc0660a1ea0ef7f))
|
||||
|
||||
### [1.2.5](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.4...v1.2.5) (2025-08-26)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **Sdk:** 调整 WechatRpc 类中数组键名的命名风格 ([acc3121](http://124.126.16.154:8888/singularity/hdk-pay/commit/acc3121320d74e2ea3423e3502779afde9675ee8))
|
||||
|
||||
### [1.2.4](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.3...v1.2.4) (2025-08-21)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **transaction:** 修改交易项中的价格字段名称 ([2276885](http://124.126.16.154:8888/singularity/hdk-pay/commit/2276885ac1759a330eb6fb73e1158235edcac941))
|
||||
|
||||
### [1.2.3](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.2...v1.2.3) (2025-08-20)
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **transaction:** 重构交易信息构建方式 ([86939ea](http://124.126.16.154:8888/singularity/hdk-pay/commit/86939ea421d2f14c621da4e3bb86e3ab8d8b7d33))
|
||||
|
||||
### [1.2.2](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.1...v1.2.2) (2025-08-20)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **transaction:** 修复回调服务中的商品价格字段 ([2ea5227](http://124.126.16.154:8888/singularity/hdk-pay/commit/2ea52271852e4e009b044fb9baeb222b3a54c111))
|
||||
|
||||
### [1.2.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.2.0...v1.2.1) (2025-08-20)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **deps:** 更新多个依赖至最新版本 ([c3a256c](http://124.126.16.154:8888/singularity/hdk-pay/commit/c3a256cb3d5e41a29a4969442b5a7f27c9000576))
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **TransactionRecord:** 添加 TransactionRecord 类的 getter 方法 ([9d61106](http://124.126.16.154:8888/singularity/hdk-pay/commit/9d61106e2e8b04559fb34b606fb489a2890c34d5))
|
||||
|
||||
## [1.2.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.1.0...v1.2.0) (2025-08-20)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **transaction:** 添加交易相关实体和回调服务 ([8f71cbe](http://124.126.16.154:8888/singularity/hdk-pay/commit/8f71cbeb653d0722f231c300c2a1fabe79764580))
|
||||
|
||||
|
||||
### ✅ Tests | 测试
|
||||
|
||||
* 更新 LuxPay 回调测试用例 ([fc5cf45](http://124.126.16.154:8888/singularity/hdk-pay/commit/fc5cf453aed133552514e1b60699fe63d2178543))
|
||||
|
||||
## [1.1.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0...v1.1.0) (2025-08-18)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **pay:** 新增消费命令和通用订单 DTO ([c8ee3bb](http://124.126.16.154:8888/singularity/hdk-pay/commit/c8ee3bb23bf41f39a64ca08db4a005d2893c1554))
|
||||
* **pay:** 添加充值功能 ([80dc1a3](http://124.126.16.154:8888/singularity/hdk-pay/commit/80dc1a3706fa973f3360c70f1db34d403eb741df))
|
||||
|
||||
## [1.0.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-beta.5...v1.0.0) (2025-08-18)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **deps:** 更新 Hyperf 和 Symfony 组件 ([7f7fe10](http://124.126.16.154:8888/singularity/hdk-pay/commit/7f7fe100e71e98557de0399702ef2e3cb17d3b42))
|
||||
|
||||
|
||||
### ✅ Tests | 测试
|
||||
|
||||
* **pay:** 添加账户信息查询功能测试 ([336cb3a](http://124.126.16.154:8888/singularity/hdk-pay/commit/336cb3a9b9baa0b9e47ca7cf5bb5a6bc04d48c90))
|
||||
|
||||
|
||||
### ♻️ Code Refactoring | 代码重构
|
||||
|
||||
* **pay:** 调整请求头构建逻辑 ([1bb8666](http://124.126.16.154:8888/singularity/hdk-pay/commit/1bb8666b5e4432d720d9b8256baa06d4f570718a))
|
||||
* **pay:** 重构账户余额查询功能 ([5559f2c](http://124.126.16.154:8888/singularity/hdk-pay/commit/5559f2c2a59326a8aa209ffb00693523d39fc319))
|
||||
* **pay:** 重构账户余额查询接口并添加单元测试 ([4f0d402](http://124.126.16.154:8888/singularity/hdk-pay/commit/4f0d402538410020c89910b48bb418f2d306b1a0))
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **domain:** 新增账户余额和积分相关实体及接口 ([3d91f76](http://124.126.16.154:8888/singularity/hdk-pay/commit/3d91f76dc0657bd24643ee18a3192ad631001530))
|
||||
* **pay:** 添加产品类型枚举和兑换率接口 ([a2fc4ce](http://124.126.16.154:8888/singularity/hdk-pay/commit/a2fc4cecf8105616b440add0bfaab93b91abce09))
|
||||
* **product:** 增加 EMA 产品查询功能 ([1814adc](http://124.126.16.154:8888/singularity/hdk-pay/commit/1814adc30e0c3801c11bfb270a666ebd9348d115))
|
||||
* **product:** 新增充值产品相关数据结构和接口 ([06dc4a2](http://124.126.16.154:8888/singularity/hdk-pay/commit/06dc4a2e6555f92aab09271a3f8cd09fc8960e95))
|
||||
|
||||
## [1.0.0-beta.5](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-beta.4...v1.0.0-beta.5) (2025-07-17)
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
"Singularity\\HDK\\Pay\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Singularity\\HDK\\Test\\Pay\\": "tests/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"hyperf": {
|
||||
"config": "Singularity\\HDK\\Pay\\ConfigProvider"
|
||||
@@ -15,14 +20,16 @@
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"ext-bcmath": "*",
|
||||
"composer/composer": ">=2.7.7",
|
||||
"hyperf/config": "~3.1.0",
|
||||
"hyperf/constants": "3.1.*",
|
||||
"hyperf/contract": "~3.1.0",
|
||||
"hyperf/di": "~3.1.0",
|
||||
"hyperf/guzzle": "3.1.*",
|
||||
"hyperf/http-server": "3.1.*",
|
||||
"hyperf/http-server": "^3.1",
|
||||
"moneyphp/money": "^4.1",
|
||||
"nesbot/carbon": "*",
|
||||
"singularity/hdk-core": "^1.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
@@ -62,5 +69,5 @@
|
||||
"url": "https://mirrors.aliyun.com/composer/"
|
||||
}
|
||||
},
|
||||
"version": "1.0.0-beta.5"
|
||||
"version": "1.11.1"
|
||||
}
|
||||
|
||||
1524
composer.lock
generated
1524
composer.lock
generated
File diff suppressed because it is too large
Load Diff
41
src/Application/Command/ConsumeCmd.php
Normal file
41
src/Application/Command/ConsumeCmd.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ConsumeCmd.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Application\Command;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
use Singularity\HDK\Pay\Enum\PaymentMethod;
|
||||
|
||||
final class ConsumeCmd
|
||||
{
|
||||
public array $items = [];
|
||||
|
||||
public function __construct(
|
||||
public string $uid,
|
||||
public PayType $type,
|
||||
public PaymentMethod|PointType $method,
|
||||
public array $external,
|
||||
public ?string $externalID = null,
|
||||
public ?string $remark = null,
|
||||
) {}
|
||||
|
||||
public function addItem(string $name, float $unitPrice, int $quantity = 1): ConsumeCmd
|
||||
{
|
||||
$this->items[] = [
|
||||
'name' => $name,
|
||||
'quantity' => $quantity,
|
||||
'unit_price' => $unitPrice,
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
31
src/Application/Command/CreateInvoiceCmd.php
Normal file
31
src/Application/Command/CreateInvoiceCmd.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CreateInvoiceCmd.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/29
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Application\Command;
|
||||
|
||||
use Money\Money;
|
||||
|
||||
final readonly class CreateInvoiceCmd
|
||||
{
|
||||
public function __construct(
|
||||
public string $caseId,
|
||||
public bool $setFreqInvAddr,
|
||||
public string $receiver,
|
||||
public string $patientName,
|
||||
public string $address,
|
||||
public string $city,
|
||||
public string $state,
|
||||
public string $country,
|
||||
public string $zipCode,
|
||||
public Money $price,
|
||||
public string $currencySymbol,
|
||||
) {}
|
||||
}
|
||||
40
src/Application/Command/InitialAccountCmd.php
Normal file
40
src/Application/Command/InitialAccountCmd.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* InitialAccountCmd.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/9/17
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Application\Command;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
|
||||
final class InitialAccountCmd
|
||||
{
|
||||
public array $pointsBalances;
|
||||
|
||||
public function __construct(
|
||||
public readonly string $uid,
|
||||
) {}
|
||||
|
||||
public function addPointsBalance(
|
||||
PointType $type,
|
||||
float $basic = 0.0,
|
||||
float $bonus = 0.0,
|
||||
?Carbon $expiredAt = null,
|
||||
?string $version = null,
|
||||
): array {
|
||||
return $this->pointsBalances[] = [
|
||||
'type' => $type->value,
|
||||
'basic' => $basic,
|
||||
'bonus' => $bonus,
|
||||
'expired_at' => $expiredAt->toDateTimeString(),
|
||||
'version' => $version,
|
||||
];
|
||||
}
|
||||
}
|
||||
28
src/Application/Command/RechargeCmd.php
Normal file
28
src/Application/Command/RechargeCmd.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RechargeCmd.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Application\Command;
|
||||
|
||||
final class RechargeCmd {
|
||||
public array $items = [];
|
||||
|
||||
public function __construct(public string $uid) {}
|
||||
|
||||
public function addItem(int $productId, int $quantity = 1): RechargeCmd
|
||||
{
|
||||
$this->items[] = [
|
||||
'product_id' => $productId,
|
||||
'quantity' => $quantity,
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
29
src/Application/Dto/AbstractDto.php
Normal file
29
src/Application/Dto/AbstractDto.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AbstractDto.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Application\Dto;
|
||||
|
||||
use Hyperf\Codec\Json;
|
||||
use Hyperf\Contract\Jsonable;
|
||||
use Swoole\ArrayObject;
|
||||
|
||||
abstract class AbstractDto extends ArrayObject implements Jsonable
|
||||
{
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->toJson();
|
||||
}
|
||||
|
||||
public function toJson(): string
|
||||
{
|
||||
return Json::encode($this->toArray());
|
||||
}
|
||||
}
|
||||
80
src/Application/Dto/Product/RechargeProductsDto.php
Normal file
80
src/Application/Dto/Product/RechargeProductsDto.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RechargeProductsDto.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Application\Dto\Product;
|
||||
|
||||
|
||||
use Singularity\HDK\Pay\Application\Dto\AbstractDto;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\Entities\ProductItem;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\RechargeProduct;
|
||||
|
||||
final class RechargeProductsDto extends AbstractDto
|
||||
{
|
||||
public function __construct(RechargeProduct $product)
|
||||
{
|
||||
parent::__construct(array_filter([
|
||||
'one_time' => $this->parseProductItem($product->getOneTime()),
|
||||
'renew' => $this->parseProductItem($product->getRenew()),
|
||||
'plan' => array_map(
|
||||
fn(ProductItem $item) => $this->parseProductItem($item),
|
||||
$product->getPlans(),
|
||||
),
|
||||
'package' => array_map(
|
||||
fn(ProductItem $item) => $this->parseProductItem($item),
|
||||
$product->getPackages(),
|
||||
),
|
||||
]));
|
||||
}
|
||||
|
||||
private function parseProductItem(?ProductItem $product): array
|
||||
{
|
||||
if (is_null($product)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$effect = $product->effect;
|
||||
$price = $product->unitPrice;
|
||||
|
||||
$result = [
|
||||
'id' => $product->id,
|
||||
'name' => $product->description,
|
||||
'currency' => $price->getCurrency()->getCode(),
|
||||
'price' => (float)bcdiv($price->getAmount(), '100', 2),
|
||||
];
|
||||
|
||||
$is_ftai = empty($effect);
|
||||
if (!$is_ftai) {
|
||||
$result += [
|
||||
'total_points' => $effect->getPointTotal(),
|
||||
'bonus_rate_pct' => round(
|
||||
(float)(bcmul(
|
||||
num1: $effect->getPointTotal() == 0
|
||||
? '0'
|
||||
: bcdiv(
|
||||
(string)$effect->pointBonus,
|
||||
(string)$effect->getPointTotal(),
|
||||
3,
|
||||
),
|
||||
num2: '100',
|
||||
scale: 3,
|
||||
)),
|
||||
),
|
||||
'point' => [
|
||||
'total' => $effect->getPointTotal(),
|
||||
'number' => $effect->pointBasic,
|
||||
'bonus' => $effect->pointBonus,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
46
src/Application/Dto/Transaction/OrderDto.php
Normal file
46
src/Application/Dto/Transaction/OrderDto.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RechargeDto.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Application\Dto\Transaction;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderAction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderStatus;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
|
||||
final readonly class OrderDto
|
||||
{
|
||||
public function __construct(
|
||||
private string $orderNo,
|
||||
private OrderAction $action,
|
||||
private PayType $payType,
|
||||
private OrderStatus $status,
|
||||
) {}
|
||||
|
||||
public function getOrderNo(): string
|
||||
{
|
||||
return $this->orderNo;
|
||||
}
|
||||
|
||||
public function getAction(): OrderAction
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
public function getPayType(): PayType
|
||||
{
|
||||
return $this->payType;
|
||||
}
|
||||
|
||||
public function getStatus(): OrderStatus
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,21 @@ namespace Singularity\HDK\Pay;
|
||||
|
||||
use Hyperf\Contract\StdoutLoggerInterface;
|
||||
use Hyperf\Framework\Logger\StdoutLogger;
|
||||
use Singularity\HDK\Pay\Domain\Account\Repository\AccountRepoInterface;
|
||||
use Singularity\HDK\Pay\Domain\Account\Repository\PointLogRepoInterface;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Repository\FrequentAddressRepoInterface;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceProductRepoInterface;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceRepoInterface;
|
||||
use Singularity\HDK\Pay\Domain\Product\Repository\ExchangeRepoInterface;
|
||||
use Singularity\HDK\Pay\Domain\Product\Repository\RechargeProductRepoInterface;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Repository\OrderRepoInterface;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\AccountBalanceRepo;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\FrequentAddressRepo;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceProductRepo;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceRepo;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\OrderRepo;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\PointLogRepo;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\ProductRepo;
|
||||
|
||||
/**
|
||||
* ConfigProvider.php@HyperfAuth
|
||||
@@ -18,11 +33,27 @@ class ConfigProvider
|
||||
{
|
||||
public function __invoke(): array
|
||||
{
|
||||
/** @noinspection PhpUndefinedConstantInspection */
|
||||
return [
|
||||
// 合并到 config/autoload/dependencies.php 文件
|
||||
'dependencies' => [
|
||||
StdoutLoggerInterface::class => StdoutLogger::class,
|
||||
|
||||
// Repo
|
||||
// account
|
||||
AccountRepoInterface::class => AccountBalanceRepo::class,
|
||||
PointLogRepoInterface::class => PointLogRepo::class,
|
||||
|
||||
// product
|
||||
ExchangeRepoInterface::class => ProductRepo::class,
|
||||
RechargeProductRepoInterface::class => ProductRepo::class,
|
||||
|
||||
// transaction
|
||||
OrderRepoInterface::class => OrderRepo::class,
|
||||
|
||||
// invoice
|
||||
InvoiceProductRepoInterface::class => InvoiceProductRepo::class,
|
||||
InvoiceRepoInterface::class => InvoiceRepo::class,
|
||||
FrequentAddressRepoInterface::class => FrequentAddressRepo::class,
|
||||
],
|
||||
// 合并到 config/autoload/annotations.php 文件
|
||||
'annotations' => [
|
||||
|
||||
44
src/Domain/Account/Aggregate/Account/AccountBalance.php
Normal file
44
src/Domain/Account/Aggregate/Account/AccountBalance.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AccountBalance.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/17
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\Account;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Pay\Domain\Account\Aggregate\AccountBalance@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/17
|
||||
*
|
||||
* @template TPointType of string
|
||||
* @template TPointsBalances of array<TPointType, PointsBalance>
|
||||
*/
|
||||
final readonly class AccountBalance
|
||||
{
|
||||
/**
|
||||
* @param string $uid
|
||||
* @param PointsBalance $pointsBalances
|
||||
*/
|
||||
public function __construct(
|
||||
private string $uid,
|
||||
private array $pointsBalances = [],
|
||||
) {}
|
||||
|
||||
public function getUid(): string
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
public function getPointsBalances(): array
|
||||
{
|
||||
return $this->pointsBalances;
|
||||
}
|
||||
}
|
||||
58
src/Domain/Account/Aggregate/Account/PointsBalance.php
Normal file
58
src/Domain/Account/Aggregate/Account/PointsBalance.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PointsBalance.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\Account;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
|
||||
final readonly class PointsBalance
|
||||
{
|
||||
public function __construct(
|
||||
private PointType $type,
|
||||
private float $total,
|
||||
private float $cost,
|
||||
public float $amount,
|
||||
private string|null $version,
|
||||
private Carbon|null $expiredAt,
|
||||
) {
|
||||
}
|
||||
|
||||
public function getType(): PointType
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getTotal(): float
|
||||
{
|
||||
return $this->total;
|
||||
}
|
||||
|
||||
public function getCost(): float
|
||||
{
|
||||
return $this->cost;
|
||||
}
|
||||
|
||||
public function getVersion(): ?string
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function getExpiredAt(): ?Carbon
|
||||
{
|
||||
return $this->expiredAt;
|
||||
}
|
||||
|
||||
public function getAmount(): float
|
||||
{
|
||||
return $this->amount;
|
||||
}
|
||||
}
|
||||
94
src/Domain/Account/Aggregate/PointLog/PointLog.php
Normal file
94
src/Domain/Account/Aggregate/PointLog/PointLog.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PointLog.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/21
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\ValueObject\InvoiceRecord;
|
||||
use Singularity\HDK\Pay\Domain\AggregateRoot;
|
||||
|
||||
final class PointLog extends AggregateRoot
|
||||
{
|
||||
public function __construct(
|
||||
private readonly int $id,
|
||||
private readonly string $caseId,
|
||||
private readonly string $uid,
|
||||
private readonly float $credits,
|
||||
private readonly string $source,
|
||||
private readonly string $operator,
|
||||
private readonly string $description,
|
||||
private readonly string $patientName,
|
||||
private readonly Carbon $date,
|
||||
private readonly bool $invoiceable,
|
||||
private readonly ?InvoiceRecord $invoiceRecord,
|
||||
) {}
|
||||
|
||||
public function getPatientName(): string
|
||||
{
|
||||
return $this->patientName;
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function getSource(): string
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
public function getDate(): Carbon
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function getUid(): string
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
|
||||
public function getCredits(): float
|
||||
{
|
||||
return $this->credits;
|
||||
}
|
||||
|
||||
public function getOperator(): string
|
||||
{
|
||||
return $this->operator;
|
||||
}
|
||||
|
||||
public function getCaseId(): ?string
|
||||
{
|
||||
return $this->caseId;
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getInvoiceNo(): ?string
|
||||
{
|
||||
return $this->invoiceRecord?->invoiceNo;
|
||||
}
|
||||
|
||||
public function getInvoiceReceiver(): ?string
|
||||
{
|
||||
return $this->invoiceRecord?->receiver;
|
||||
}
|
||||
|
||||
public function getInvoiceable(): bool
|
||||
{
|
||||
return $this->invoiceable;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* InvoiceRecord.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/9/4
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\ValueObject;
|
||||
|
||||
final class InvoiceRecord
|
||||
{
|
||||
public function __construct(
|
||||
public string $invoiceNo,
|
||||
public string $receiver,
|
||||
) {}
|
||||
}
|
||||
35
src/Domain/Account/Enum/PointAction.php
Normal file
35
src/Domain/Account/Enum/PointAction.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* PointAction.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/21
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Account\Enum;
|
||||
|
||||
enum PointAction
|
||||
{
|
||||
case Initial;
|
||||
|
||||
case Deduct;
|
||||
|
||||
case Refund;
|
||||
|
||||
case Increase;
|
||||
|
||||
case Clear;
|
||||
|
||||
public static function tryFrom(string $action): ?PointAction
|
||||
{
|
||||
return match (strtolower($action)) {
|
||||
'initial' => self::Initial,
|
||||
'deduct' => self::Deduct,
|
||||
'refund' => self::Refund,
|
||||
'increase' => self::Increase,
|
||||
'clear' => self::Clear,
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
41
src/Domain/Account/Enum/PointType.php
Normal file
41
src/Domain/Account/Enum/PointType.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* PointType.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Account\Enum;
|
||||
|
||||
enum PointType: string
|
||||
{
|
||||
case LuxPoint = 'lux-point';
|
||||
|
||||
case EMA = 'ema';
|
||||
|
||||
case FtaiAligner = 'aligner';
|
||||
case FtaiRetainer = 'retainer';
|
||||
|
||||
case Aligner4D = 'aligner-4d';
|
||||
case NightguardAi = 'nightguard-ai';
|
||||
|
||||
case ScanToModel = 'scan-to-model';
|
||||
|
||||
case FourDXUnlimitedBonusCredits = 'aligner-4d-u';
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return [
|
||||
self::LuxPoint->value,
|
||||
self::EMA->value,
|
||||
self::FtaiAligner->value,
|
||||
self::FtaiRetainer->value,
|
||||
self::Aligner4D->value,
|
||||
self::NightguardAi->value,
|
||||
self::ScanToModel->value,
|
||||
self::FourDXUnlimitedBonusCredits->value,
|
||||
];
|
||||
}
|
||||
}
|
||||
39
src/Domain/Account/Repository/AccountRepoInterface.php
Normal file
39
src/Domain/Account/Repository/AccountRepoInterface.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AccountBalanceRpc.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/17
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Account\Repository;
|
||||
|
||||
use Singularity\HDK\Pay\Application\Command\InitialAccountCmd;
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\AccountBalance;
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\PointsBalance;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
|
||||
interface AccountRepoInterface
|
||||
{
|
||||
/**
|
||||
* @param string $uid
|
||||
* @return AccountBalance
|
||||
*/
|
||||
public function getAccount(string $uid): AccountBalance;
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @param PointType $pointType
|
||||
* @return PointsBalance
|
||||
*/
|
||||
public function getPointBalance(string $uid, PointType $pointType): PointsBalance;
|
||||
|
||||
/**
|
||||
* @param InitialAccountCmd $cmd
|
||||
* @return void
|
||||
*/
|
||||
public function initial(InitialAccountCmd $cmd): void;
|
||||
}
|
||||
27
src/Domain/Account/Repository/PointLogRepoInterface.php
Normal file
27
src/Domain/Account/Repository/PointLogRepoInterface.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* PointLogRepoInterface.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/27
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Account\Repository;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\PointLog;
|
||||
|
||||
interface PointLogRepoInterface
|
||||
{
|
||||
/**
|
||||
* @param string $uid
|
||||
* @return PointLog[]
|
||||
*/
|
||||
public function getList(string $uid): array;
|
||||
|
||||
/**
|
||||
* @param string $caseId
|
||||
* @return PointLog
|
||||
*/
|
||||
public function getDetail(string $caseId): PointLog;
|
||||
}
|
||||
32
src/Domain/AggregateRoot.php
Normal file
32
src/Domain/AggregateRoot.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AggregateRoot.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/7/31
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain;
|
||||
|
||||
abstract class AggregateRoot implements AggregateRootInterface {
|
||||
/**
|
||||
* @var array{}|DomainEvent[]
|
||||
*/
|
||||
protected array $domainEvents = [];
|
||||
|
||||
public function recordEvent(DomainEvent $event): void
|
||||
{
|
||||
$this->domainEvents[] = $event;
|
||||
}
|
||||
|
||||
public function flushAllEvent(): array
|
||||
{
|
||||
$events = $this->domainEvents;
|
||||
$this->domainEvents = [];
|
||||
|
||||
return $events;
|
||||
}
|
||||
}
|
||||
14
src/Domain/AggregateRootInterface.php
Normal file
14
src/Domain/AggregateRootInterface.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AbstractAggregateRoot.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/7/25
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain;
|
||||
|
||||
interface AggregateRootInterface {}
|
||||
12
src/Domain/DomainEvent.php
Normal file
12
src/Domain/DomainEvent.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
/**
|
||||
* DomainEvent.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/7/31
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain;
|
||||
|
||||
interface DomainEvent {}
|
||||
14
src/Domain/DomainException.php
Normal file
14
src/Domain/DomainException.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* DomainException.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/7/8
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain;
|
||||
|
||||
class DomainException extends \RuntimeException {}
|
||||
56
src/Domain/Invoice/Aggregate/Address/FrequentAddress.php
Normal file
56
src/Domain/Invoice/Aggregate/Address/FrequentAddress.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryFreqAddrDto.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/29
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Address;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\AggregateRoot;
|
||||
|
||||
final class FrequentAddress extends AggregateRoot
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $uid,
|
||||
private readonly string $address,
|
||||
private readonly string $city,
|
||||
private readonly string $state,
|
||||
private readonly string $country,
|
||||
private readonly string $zipCode,
|
||||
) {}
|
||||
|
||||
public function getUid(): string
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
public function getAddress(): string
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function getCity(): string
|
||||
{
|
||||
return $this->city;
|
||||
}
|
||||
|
||||
public function getState(): string
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function getCountry(): string
|
||||
{
|
||||
return $this->country;
|
||||
}
|
||||
|
||||
public function getZipCode(): string
|
||||
{
|
||||
return $this->zipCode;
|
||||
}
|
||||
}
|
||||
53
src/Domain/Invoice/Aggregate/Invoice/Address.php
Normal file
53
src/Domain/Invoice/Aggregate/Invoice/Address.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Address.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/28
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice;
|
||||
|
||||
final readonly class Address {
|
||||
public function __construct(
|
||||
private string $patientName,
|
||||
private string $address,
|
||||
private string $city,
|
||||
private string $state,
|
||||
private string $country,
|
||||
private string $zipCode,
|
||||
) {}
|
||||
|
||||
public function getPatientName(): string
|
||||
{
|
||||
return $this->patientName;
|
||||
}
|
||||
|
||||
public function getAddress(): string
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function getCity(): string
|
||||
{
|
||||
return $this->city;
|
||||
}
|
||||
|
||||
public function getState(): string
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
public function getCountry(): string
|
||||
{
|
||||
return $this->country;
|
||||
}
|
||||
|
||||
public function getZipCode(): string
|
||||
{
|
||||
return $this->zipCode;
|
||||
}
|
||||
}
|
||||
99
src/Domain/Invoice/Aggregate/Invoice/Invoice.php
Normal file
99
src/Domain/Invoice/Aggregate/Invoice/Invoice.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* InvoiceDto.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/28
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice;
|
||||
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Pay\Domain\AggregateRoot;
|
||||
|
||||
final class Invoice extends AggregateRoot
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $invoiceNo,
|
||||
private readonly string $uid,
|
||||
private readonly string $caseId,
|
||||
private readonly Address $address,
|
||||
private readonly bool $setFreqInvAddr,
|
||||
private readonly string $receiver,
|
||||
private readonly Money $price,
|
||||
private readonly string $currencySymbol,
|
||||
) {}
|
||||
|
||||
public function getAmount(): float
|
||||
{
|
||||
return (float)bcdiv($this->price->getAmount(), '100', 2);
|
||||
}
|
||||
|
||||
public function getCurrencyCode(): string
|
||||
{
|
||||
return $this->price->getCurrency()->getCode();
|
||||
}
|
||||
|
||||
public function getCurrencySymbol(): string
|
||||
{
|
||||
return $this->currencySymbol;
|
||||
}
|
||||
|
||||
public function getInvoiceNo(): string
|
||||
{
|
||||
return $this->invoiceNo;
|
||||
}
|
||||
|
||||
public function getUid(): string
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
public function getCaseId(): string
|
||||
{
|
||||
return $this->caseId;
|
||||
}
|
||||
|
||||
public function isSetFreqInvAddr(): bool
|
||||
{
|
||||
return $this->setFreqInvAddr;
|
||||
}
|
||||
|
||||
public function getReceiver(): string
|
||||
{
|
||||
return $this->receiver;
|
||||
}
|
||||
|
||||
public function getPatientName(): string
|
||||
{
|
||||
return $this->address->getPatientName();
|
||||
}
|
||||
|
||||
public function getAddress(): string
|
||||
{
|
||||
return $this->address->getAddress();
|
||||
}
|
||||
|
||||
public function getCity(): string
|
||||
{
|
||||
return $this->address->getCity();
|
||||
}
|
||||
|
||||
public function getState(): string
|
||||
{
|
||||
return $this->address->getState();
|
||||
}
|
||||
|
||||
public function getCountry(): string
|
||||
{
|
||||
return $this->address->getCountry();
|
||||
}
|
||||
|
||||
public function getZipCode(): string
|
||||
{
|
||||
return $this->address->getZipCode();
|
||||
}
|
||||
}
|
||||
81
src/Domain/Invoice/Aggregate/Invoice/InvoiceInfo.php
Normal file
81
src/Domain/Invoice/Aggregate/Invoice/InvoiceInfo.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* InvoiceInfo.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/9/5
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointBalance;
|
||||
|
||||
final readonly class InvoiceInfo
|
||||
{
|
||||
public function __construct(
|
||||
private string $invoiceNo,
|
||||
private string $uid,
|
||||
private string $caseId,
|
||||
private Address $address,
|
||||
private InvoiceProduct $product,
|
||||
private PointBalance $balance,
|
||||
private string $receiver,
|
||||
private Carbon $invoiceAt,
|
||||
private Carbon $designedAt,
|
||||
private string $patientName,
|
||||
) {}
|
||||
|
||||
public function getInvoiceNo(): string
|
||||
{
|
||||
return $this->invoiceNo;
|
||||
}
|
||||
|
||||
public function getUid(): string
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
public function getCaseId(): string
|
||||
{
|
||||
return $this->caseId;
|
||||
}
|
||||
|
||||
public function getAddress(): Address
|
||||
{
|
||||
return $this->address;
|
||||
}
|
||||
|
||||
public function getProduct(): InvoiceProduct
|
||||
{
|
||||
return $this->product;
|
||||
}
|
||||
|
||||
public function getBalance(): PointBalance
|
||||
{
|
||||
return $this->balance;
|
||||
}
|
||||
|
||||
public function getReceiver(): string
|
||||
{
|
||||
return $this->receiver;
|
||||
}
|
||||
|
||||
public function getInvoiceAt(): Carbon
|
||||
{
|
||||
return $this->invoiceAt;
|
||||
}
|
||||
|
||||
public function getDesignedAt(): Carbon
|
||||
{
|
||||
return $this->designedAt;
|
||||
}
|
||||
|
||||
public function getPatientName(): string
|
||||
{
|
||||
return $this->patientName;
|
||||
}
|
||||
}
|
||||
33
src/Domain/Invoice/Aggregate/Invoice/InvoiceProduct.php
Normal file
33
src/Domain/Invoice/Aggregate/Invoice/InvoiceProduct.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* InvoiceProduct.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/28
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointPrice;
|
||||
|
||||
final readonly class InvoiceProduct {
|
||||
/**
|
||||
* @param string $caseId
|
||||
* @param string $uid
|
||||
* @param string $name
|
||||
* @param string $sku
|
||||
* @param string $description
|
||||
* @param PointPrice[] $prices
|
||||
*/
|
||||
public function __construct(
|
||||
public string $caseId,
|
||||
public string $uid,
|
||||
public string $name,
|
||||
public string $sku,
|
||||
public string $description,
|
||||
public array $prices,
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PointBalance.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/9/5
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject;
|
||||
|
||||
final readonly class PointBalance {
|
||||
public function __construct(
|
||||
public float $total,
|
||||
public float $cost,
|
||||
public float $remain,
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PointPrice.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/11/25
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject;
|
||||
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
|
||||
final readonly class PointPrice
|
||||
{
|
||||
public function __construct(
|
||||
public Money $price,
|
||||
public string $currencySymbol,
|
||||
) {}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* FrequentAddressRepoInterface.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/29
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Repository;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Address\FrequentAddress;
|
||||
|
||||
interface FrequentAddressRepoInterface
|
||||
{
|
||||
/**
|
||||
* @param string $uid
|
||||
* @return FrequentAddress
|
||||
*/
|
||||
public function findByUser(string $uid): FrequentAddress;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* InvoiceProductRepoInterface.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/28
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Repository;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
|
||||
|
||||
interface InvoiceProductRepoInterface
|
||||
{
|
||||
/**
|
||||
* @param string $caseId
|
||||
* @return InvoiceProduct
|
||||
*/
|
||||
public function getCaseProduct(string $caseId): InvoiceProduct;
|
||||
}
|
||||
46
src/Domain/Invoice/Repository/InvoiceRepoInterface.php
Normal file
46
src/Domain/Invoice/Repository/InvoiceRepoInterface.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* InvoiceRepoInterface.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/29
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Invoice\Repository;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Singularity\HDK\Pay\Application\Command\CreateInvoiceCmd;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\Invoice;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceInfo;
|
||||
|
||||
interface InvoiceRepoInterface
|
||||
{
|
||||
/**
|
||||
* @param CreateInvoiceCmd $cmd
|
||||
* @return Invoice
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function create(CreateInvoiceCmd $cmd): Invoice;
|
||||
|
||||
/**
|
||||
* @param string $invoiceNo
|
||||
* @return ResponseInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function download(string $invoiceNo): ResponseInterface;
|
||||
|
||||
/**
|
||||
* @param string $invoiceNo
|
||||
* @return void
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function send(string $invoiceNo): void;
|
||||
|
||||
/**
|
||||
* @param string $invoiceNo
|
||||
* @return InvoiceInfo
|
||||
*/
|
||||
public function findOne(string $invoiceNo): InvoiceInfo;
|
||||
}
|
||||
27
src/Domain/Product/Aggregate/Entities/ProductItem.php
Normal file
27
src/Domain/Product/Aggregate/Entities/ProductItem.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RechargeProduct.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Product\Aggregate\Entities;
|
||||
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\ValueObject\RechargeEffect;
|
||||
use Singularity\HDK\Pay\Domain\Product\Enum\ProductType;
|
||||
|
||||
final class ProductItem
|
||||
{
|
||||
public function __construct(
|
||||
public int $id,
|
||||
public string $description,
|
||||
public Money $unitPrice,
|
||||
public ProductType $productType,
|
||||
public ?RechargeEffect $effect = null,
|
||||
) {}
|
||||
}
|
||||
80
src/Domain/Product/Aggregate/RechargeProduct.php
Normal file
80
src/Domain/Product/Aggregate/RechargeProduct.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RechargeProduct.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Product\Aggregate;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\AggregateRoot;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\Entities\ProductItem;
|
||||
|
||||
/**
|
||||
* App\Domain\Product\Aggregate\RechargeProduct@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*
|
||||
* @property-read ProductItem[] $plans
|
||||
* @property-read ProductItem[] $packages
|
||||
* @property-read ProductItem $oneTime
|
||||
*/
|
||||
final class RechargeProduct extends AggregateRoot
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ?ProductItem $oneTime,
|
||||
private readonly ?ProductItem $renew = null,
|
||||
private readonly array $plans = [],
|
||||
private readonly array $packages = [],
|
||||
) {}
|
||||
|
||||
/**
|
||||
* @param array $idList
|
||||
* @return array{'id': int, 'quantity': int, 'detail': ProductItem}
|
||||
*/
|
||||
public function selectItemList(array $idList): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
/** @var ProductItem $item */
|
||||
foreach ([$this->oneTime, $this->renew, ...$this->plans, ...$this->packages] as $item) {
|
||||
if (in_array($item->id, $idList)) {
|
||||
$result[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ProductItem[]
|
||||
*/
|
||||
public function getPlans(): array
|
||||
{
|
||||
return $this->plans;
|
||||
}
|
||||
|
||||
public function getRenew(): ?ProductItem
|
||||
{
|
||||
return $this->renew;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ProductItem[]
|
||||
*/
|
||||
public function getPackages(): array
|
||||
{
|
||||
return $this->packages;
|
||||
}
|
||||
|
||||
public function getOneTime(): ?ProductItem
|
||||
{
|
||||
return $this->oneTime;
|
||||
}
|
||||
}
|
||||
86
src/Domain/Product/Aggregate/ValueObject/RechargeEffect.php
Normal file
86
src/Domain/Product/Aggregate/ValueObject/RechargeEffect.php
Normal file
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* RechargeEffect.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Product\Aggregate\ValueObject;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Hyperf\Framework\Exception\NotImplementedException;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
|
||||
final class RechargeEffect
|
||||
{
|
||||
private float $pointTotal;
|
||||
|
||||
public function __construct(
|
||||
public PointType $pointType,
|
||||
|
||||
public float $pointBasic,
|
||||
public float $pointBonus,
|
||||
|
||||
public ?Carbon $expiredAt = null,
|
||||
|
||||
public ?string $version = null,
|
||||
) {
|
||||
$this->pointTotal = (float)bcadd((string)$pointBasic, (string)$pointBonus, 4);
|
||||
}
|
||||
|
||||
public function getPointTotal(): float
|
||||
{
|
||||
return $this->pointTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template TPoints of array{'total': float, 'basic': float, 'bonus': float}
|
||||
* @return array{'points'?: TPoints, 'version'?: string, 'expired_at'?: Carbon}
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return array_filter([
|
||||
'points' => $this->pointTotal == 0
|
||||
? null
|
||||
: [
|
||||
'total' => $this->pointTotal,
|
||||
'basic' => $this->pointBasic,
|
||||
'bonus' => $this->pointBonus,
|
||||
],
|
||||
'version' => $this->version,
|
||||
'expired_at' => $this->expiredAt,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PointType $pointType
|
||||
* @param string $range
|
||||
* @return Carbon
|
||||
*/
|
||||
private static function parseExpiredAt(PointType $pointType, string $range): Carbon
|
||||
{
|
||||
if ($pointType !== PointType::EMA) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
$now = Carbon::now();
|
||||
|
||||
preg_match('/^(\d+)(\w)$/', $range, $matches);
|
||||
$quantity = $matches[1]; // 数字部分
|
||||
$unit = $matches[2]; // 单位部分
|
||||
|
||||
return match ($unit) {
|
||||
'Y' => $now->addYears($quantity),
|
||||
'm' => $now->addMonths($quantity),
|
||||
'd' => $now->addDays($quantity),
|
||||
'H' => $now->addHours($quantity),
|
||||
'i' => $now->addMinutes($quantity),
|
||||
's' => $now->addSeconds($quantity),
|
||||
default => $now
|
||||
};
|
||||
}
|
||||
}
|
||||
41
src/Domain/Product/Enum/ProductType.php
Normal file
41
src/Domain/Product/Enum/ProductType.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* ProductType.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Product\Enum;
|
||||
|
||||
enum ProductType {
|
||||
case plan;
|
||||
|
||||
case pack;
|
||||
|
||||
case oneTime;
|
||||
|
||||
case renew;
|
||||
|
||||
public static function tryFrom(string $type): ?ProductType
|
||||
{
|
||||
return match ($type) {
|
||||
'plan' => self::plan,
|
||||
'pack' => self::pack,
|
||||
'oneTime' => self::oneTime,
|
||||
'renew' => self::renew,
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
public static function names(): array
|
||||
{
|
||||
$result = [];
|
||||
foreach (self::cases() as $case) {
|
||||
$result[] = $case->name;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
23
src/Domain/Product/Repository/ExchangeRepoInterface.php
Normal file
23
src/Domain/Product/Repository/ExchangeRepoInterface.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* ExchangeRepoInterface.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/7/29
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Product\Repository;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
|
||||
interface ExchangeRepoInterface
|
||||
{
|
||||
/**
|
||||
* @param PointType $source
|
||||
* @param PointType $target
|
||||
* @param string|null $uid
|
||||
* @return float
|
||||
*/
|
||||
public function getRate(PointType $source, PointType $target, ?string $uid = null): float;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* RechargeProductRepoInterface.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/5
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Product\Repository;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\RechargeProduct;
|
||||
|
||||
interface RechargeProductRepoInterface
|
||||
{
|
||||
/**
|
||||
* @return RechargeProduct
|
||||
*/
|
||||
public function findLuxPointProduct(): RechargeProduct;
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @return RechargeProduct
|
||||
*/
|
||||
public function findEmaProduct(string $uid): RechargeProduct;
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @param PointType $pointType
|
||||
* @return RechargeProduct
|
||||
*/
|
||||
public function findFtaiProduct(string $uid, PointType $pointType): RechargeProduct;
|
||||
}
|
||||
127
src/Domain/Transaction/Aggregate/TransactionRecord.php
Normal file
127
src/Domain/Transaction/Aggregate/TransactionRecord.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* TransactionRecord.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Aggregate;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Singularity\HDK\Pay\Domain\AggregateRoot;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Item;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction\CardTransaction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction\PointTransaction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderAction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderStatus;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
|
||||
final class TransactionRecord extends AggregateRoot
|
||||
{
|
||||
/**
|
||||
* @param string $orderNo
|
||||
* @param string $uid
|
||||
* @param PayType $payType
|
||||
* @param OrderAction $action
|
||||
* @param OrderStatus $status
|
||||
* @param string $source
|
||||
* @param Item[] $items
|
||||
* @param array<PointTransaction|CardTransaction> $transactions
|
||||
* @param array $refunds
|
||||
* @param array|null $external
|
||||
* @param string|null $externalId
|
||||
* @param Carbon|null $createdAt
|
||||
* @param Carbon|null $occurredAt
|
||||
* @param Carbon|null $lastRefundedAt
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly string $orderNo,
|
||||
private readonly string $uid,
|
||||
private readonly PayType $payType,
|
||||
private readonly OrderAction $action,
|
||||
private readonly OrderStatus $status,
|
||||
private readonly string $source,
|
||||
private readonly array $items,
|
||||
private readonly array $transactions,
|
||||
private readonly array $refunds,
|
||||
private readonly ?array $external,
|
||||
private readonly ?string $externalId,
|
||||
private readonly ?Carbon $createdAt,
|
||||
private readonly ?Carbon $occurredAt,
|
||||
private readonly ?Carbon $lastRefundedAt,
|
||||
) {}
|
||||
|
||||
public function getOrderNo(): string
|
||||
{
|
||||
return $this->orderNo;
|
||||
}
|
||||
|
||||
public function getUid(): string
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
public function getPayType(): PayType
|
||||
{
|
||||
return $this->payType;
|
||||
}
|
||||
|
||||
public function getAction(): OrderAction
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
public function getStatus(): OrderStatus
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
public function getSource(): string
|
||||
{
|
||||
return $this->source;
|
||||
}
|
||||
|
||||
public function getItems(): array
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
public function getTransactions(): array
|
||||
{
|
||||
return $this->transactions;
|
||||
}
|
||||
|
||||
public function getRefunds(): array
|
||||
{
|
||||
return $this->refunds;
|
||||
}
|
||||
|
||||
public function getExternal(): ?array
|
||||
{
|
||||
return $this->external;
|
||||
}
|
||||
|
||||
public function getExternalId(): ?string
|
||||
{
|
||||
return $this->externalId;
|
||||
}
|
||||
|
||||
public function getCreatedAt(): ?Carbon
|
||||
{
|
||||
return $this->createdAt;
|
||||
}
|
||||
|
||||
public function getOccurredAt(): ?Carbon
|
||||
{
|
||||
return $this->occurredAt;
|
||||
}
|
||||
|
||||
public function getLastRefundedAt(): ?Carbon
|
||||
{
|
||||
return $this->lastRefundedAt;
|
||||
}
|
||||
}
|
||||
44
src/Domain/Transaction/Aggregate/ValueObject/Item.php
Normal file
44
src/Domain/Transaction/Aggregate/ValueObject/Item.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Item.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject;
|
||||
|
||||
use Swoole\ArrayObject;
|
||||
|
||||
final class Item extends ArrayObject
|
||||
{
|
||||
public function __construct(
|
||||
private readonly string $name,
|
||||
private readonly int $quantity,
|
||||
private readonly float $price,
|
||||
) {
|
||||
parent::__construct([
|
||||
'name' => $name,
|
||||
'quantity' => $quantity,
|
||||
'unit_price' => $price,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function getQuantity(): int
|
||||
{
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
public function getPrice(): float
|
||||
{
|
||||
return $this->price;
|
||||
}
|
||||
}
|
||||
44
src/Domain/Transaction/Aggregate/ValueObject/Transaction.php
Normal file
44
src/Domain/Transaction/Aggregate/ValueObject/Transaction.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Transaction.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderStatus;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
use Singularity\HDK\Pay\Enum\PaymentMethod;
|
||||
use Swoole\ArrayObject;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
abstract class Transaction extends ArrayObject
|
||||
{
|
||||
public function __construct(
|
||||
private PayType $payType,
|
||||
private PaymentMethod|PointType $type,
|
||||
private float $amount,
|
||||
private OrderStatus $status,
|
||||
) {
|
||||
parent::__construct(
|
||||
[
|
||||
'pay_type' => $payType->value,
|
||||
'type' => $type->value,
|
||||
'amount' => $amount,
|
||||
'status' => $status->name,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CardTransaction.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderStatus;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
use Singularity\HDK\Pay\Enum\PaymentMethod;
|
||||
|
||||
final class CardTransaction extends Transaction
|
||||
{
|
||||
public function __construct(
|
||||
PaymentMethod $method,
|
||||
float $amount,
|
||||
OrderStatus $status,
|
||||
) {
|
||||
parent::__construct(
|
||||
payType: PayType::Card,
|
||||
type: $method,
|
||||
amount: $amount,
|
||||
status: $status,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PointTransaction.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction;
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderStatus;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
|
||||
final class PointTransaction extends Transaction
|
||||
{
|
||||
public function __construct(PointType $type, float $amount, OrderStatus $status)
|
||||
{
|
||||
parent::__construct(
|
||||
payType: PayType::Point,
|
||||
type: $type,
|
||||
amount: $amount,
|
||||
status: $status,
|
||||
);
|
||||
}
|
||||
}
|
||||
18
src/Domain/Transaction/Enum/OrderAction.php
Normal file
18
src/Domain/Transaction/Enum/OrderAction.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* OrderAction.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/7/30
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Enum;
|
||||
|
||||
enum OrderAction: string {
|
||||
case Recharge = 'recharge';
|
||||
|
||||
case Consumption = 'consumption';
|
||||
|
||||
case Refund = 'refund';
|
||||
}
|
||||
58
src/Domain/Transaction/Enum/OrderStatus.php
Normal file
58
src/Domain/Transaction/Enum/OrderStatus.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* OrderStatus.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2024/11/26
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Enum;
|
||||
|
||||
enum OrderStatus
|
||||
{
|
||||
case created;
|
||||
|
||||
case paid;
|
||||
|
||||
case completed;
|
||||
|
||||
case refunded;
|
||||
|
||||
case cancelled;
|
||||
|
||||
case failed;
|
||||
|
||||
case closed;
|
||||
|
||||
public static function tryFrom(mixed $status): OrderStatus
|
||||
{
|
||||
$status = strtolower($status);
|
||||
return match ($status) {
|
||||
'paid' => self::paid,
|
||||
'refunded' => self::refunded,
|
||||
'cancelled' => self::cancelled,
|
||||
'completed' => self::completed,
|
||||
'failed' => self::failed,
|
||||
'closed' => self::closed,
|
||||
default => self::created,
|
||||
};
|
||||
}
|
||||
|
||||
public static function all(): array
|
||||
{
|
||||
return [
|
||||
self::created,
|
||||
self::paid,
|
||||
self::completed,
|
||||
self::refunded,
|
||||
self::cancelled,
|
||||
self::closed,
|
||||
];
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::all(), 'value');
|
||||
}
|
||||
}
|
||||
18
src/Domain/Transaction/Enum/PayType.php
Normal file
18
src/Domain/Transaction/Enum/PayType.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
* PayType.php@LuxDesign
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/7/25
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Enum;
|
||||
|
||||
Enum PayType: string {
|
||||
case Point = 'point';
|
||||
|
||||
case Card = 'card';
|
||||
|
||||
case Hybrid = 'hybrid';
|
||||
}
|
||||
21
src/Domain/Transaction/Repository/OrderRepoInterface.php
Normal file
21
src/Domain/Transaction/Repository/OrderRepoInterface.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* OrderRepoInterface.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Repository;
|
||||
|
||||
use Singularity\HDK\Pay\Application\Command\ConsumeCmd;
|
||||
use Singularity\HDK\Pay\Application\Command\RechargeCmd;
|
||||
use Singularity\HDK\Pay\Application\Dto\Transaction\OrderDto;
|
||||
|
||||
interface OrderRepoInterface
|
||||
{
|
||||
public function recharge(RechargeCmd $cmd): OrderDto;
|
||||
|
||||
public function consume(ConsumeCmd $cmd): OrderDto;
|
||||
}
|
||||
80
src/Domain/Transaction/Service/CallbackDomainSvc.php
Normal file
80
src/Domain/Transaction/Service/CallbackDomainSvc.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CallbackDomainSvc.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain\Transaction\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\TransactionRecord;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Item;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction\CardTransaction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\ValueObject\Transaction\PointTransaction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderAction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderStatus;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
use Singularity\HDK\Pay\Enum\PaymentMethod;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Pay\Domain\Transaction\Service\CallbackDomainSvc@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
final class CallbackDomainSvc
|
||||
{
|
||||
/**
|
||||
* @param array $order
|
||||
* @return TransactionRecord
|
||||
*/
|
||||
public function callback(array $order): TransactionRecord
|
||||
{
|
||||
$payType = PayType::tryFrom($order['pay_type']);
|
||||
|
||||
return new TransactionRecord(
|
||||
orderNo: $order['order_no'],
|
||||
uid: $order['uid'],
|
||||
payType: $payType,
|
||||
action: OrderAction::tryFrom($order['action']),
|
||||
status: OrderStatus::tryFrom($order['status']),
|
||||
source: $order['source'],
|
||||
items: array_map(
|
||||
callback: fn(array $item) => new Item(
|
||||
name: $item['name'],
|
||||
quantity: $item['quantity'],
|
||||
price: $item['unit_price'],
|
||||
),
|
||||
array: $order['items'],
|
||||
),
|
||||
transactions: array_map(
|
||||
callback: fn(array $transaction)
|
||||
=> $transaction['pay_type'] === PayType::Card->value
|
||||
? new CardTransaction(
|
||||
method: PaymentMethod::tryFrom($transaction['type']),
|
||||
amount: $transaction['amount'],
|
||||
status: OrderStatus::tryFrom($transaction['status']),
|
||||
)
|
||||
: new PointTransaction(
|
||||
type: PointType::tryFrom($transaction['type']),
|
||||
amount: $transaction['amount'],
|
||||
status: OrderStatus::tryFrom($transaction['status']),
|
||||
),
|
||||
array: $order['transactions'],
|
||||
),
|
||||
refunds: $order['refunds'],
|
||||
external: $order['external'],
|
||||
externalId: $order['external_id'],
|
||||
createdAt: isset($order['created_at']) ? new Carbon($order['created_at']) : null,
|
||||
occurredAt: isset($order['occurred_at']) ? new Carbon($order['occurred_at']) : null,
|
||||
lastRefundedAt: isset($order['last_refunded_at']) ? new Carbon($order['last_refunded_at']) : null,
|
||||
);
|
||||
}
|
||||
}
|
||||
16
src/Domain/ValueObject.php
Normal file
16
src/Domain/ValueObject.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ValueObject.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/12
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Domain;
|
||||
|
||||
use Swoole\ArrayObject;
|
||||
|
||||
abstract class ValueObject extends ArrayObject {}
|
||||
17
src/Enum/Environment.php
Normal file
17
src/Enum/Environment.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Environment.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/8
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Enum;
|
||||
|
||||
enum Environment: string
|
||||
{
|
||||
case Dev = 'development';
|
||||
|
||||
case Prod = 'production';
|
||||
}
|
||||
17
src/Enum/Site.php
Normal file
17
src/Enum/Site.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Site.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/8
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Enum;
|
||||
|
||||
enum Site: string
|
||||
{
|
||||
case ChinaMainland = 'CN';
|
||||
|
||||
case NorthAmerica = 'NA';
|
||||
}
|
||||
36
src/Infrastructure/Repository/AbstractRepo.php
Normal file
36
src/Infrastructure/Repository/AbstractRepo.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AbstractRepo.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Infrastructure\Repository;
|
||||
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use Singularity\HDK\Core\Http\RequestService;
|
||||
use Singularity\HDK\Core\Http\RequestServiceFactory;
|
||||
|
||||
use Singularity\HDK\Pay\Trait\RequestHeaderBuilder;
|
||||
|
||||
use function Hyperf\Config\config;
|
||||
|
||||
abstract class AbstractRepo
|
||||
{
|
||||
use RequestHeaderBuilder;
|
||||
|
||||
protected RequestService $requestService;
|
||||
|
||||
public function __construct(?string $baseUrl = null)
|
||||
{
|
||||
$this->requestService = RequestServiceFactory::make([
|
||||
'base_uri' => $baseUrl ?? config('payment.base_uri'),
|
||||
RequestOptions::ALLOW_REDIRECTS => true,
|
||||
'headers' => $this->headerBuilder(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
84
src/Infrastructure/Repository/AccountBalanceRepo.php
Normal file
84
src/Infrastructure/Repository/AccountBalanceRepo.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AccountBalanceRpc.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/17
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Infrastructure\Repository;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Hyperf\Codec\Json;
|
||||
use Singularity\HDK\Pay\Application\Command\InitialAccountCmd;
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\AccountBalance;
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\PointsBalance;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Account\Repository\AccountRepoInterface;
|
||||
|
||||
final class AccountBalanceRepo extends AbstractRepo implements AccountRepoInterface
|
||||
{
|
||||
public function getAccount(string $uid): AccountBalance
|
||||
{
|
||||
$response = $this->requestService->requestGet(
|
||||
url: "/rpc/v2/account/$uid/balance",
|
||||
params: [
|
||||
'type' => join(',', PointType::values()),
|
||||
],
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new AccountBalance(
|
||||
uid: $result['uid'],
|
||||
pointsBalances: array_map(
|
||||
callback: fn($pointBalance)
|
||||
=> new PointsBalance(
|
||||
type: PointType::from($pointBalance['name']),
|
||||
total: $pointBalance['total'],
|
||||
cost: $pointBalance['cost'],
|
||||
amount: $pointBalance['amount'],
|
||||
version: $pointBalance['version'],
|
||||
expiredAt: isset($pointBalance['expired_at']) ? new Carbon($pointBalance['expired_at']): null,
|
||||
),
|
||||
array: $result['point_balance'],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function getPointBalance(string $uid, PointType $pointType): PointsBalance
|
||||
{
|
||||
$response = $this->requestService->requestGet(
|
||||
url: "/rpc/v2/account/$uid/balance/$pointType->value",
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new PointsBalance(
|
||||
type: PointType::from($result['name']),
|
||||
total: $result['total'],
|
||||
cost: $result['cost'],
|
||||
amount: $result['amount'],
|
||||
version: $result['version'],
|
||||
expiredAt: isset($result['expired_at']) ? new Carbon($result['expired_at']): null,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function initial(InitialAccountCmd $cmd): void
|
||||
{
|
||||
$uid = $cmd->uid;
|
||||
|
||||
$this->requestService->requestPost(
|
||||
url: "/rpc/v2/account/$uid/balance",
|
||||
data: $cmd->pointsBalances
|
||||
);
|
||||
}
|
||||
}
|
||||
41
src/Infrastructure/Repository/FrequentAddressRepo.php
Normal file
41
src/Infrastructure/Repository/FrequentAddressRepo.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* FrequentAddressRepo.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/29
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Infrastructure\Repository;
|
||||
|
||||
use Hyperf\Codec\Json;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Address\FrequentAddress;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Repository\FrequentAddressRepoInterface;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\AbstractRepo;
|
||||
|
||||
final class FrequentAddressRepo extends AbstractRepo implements FrequentAddressRepoInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function findByUser(string $uid): FrequentAddress
|
||||
{
|
||||
$response = $this->requestService->requestGet("/rpc/v2/account/$uid/inv-addr");
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new FrequentAddress(
|
||||
uid: $result['uid'],
|
||||
address: $result['address'],
|
||||
city: $result['city'],
|
||||
state: $result['state'],
|
||||
country: $result['country'],
|
||||
zipCode: $result['zip']
|
||||
);
|
||||
}
|
||||
}
|
||||
51
src/Infrastructure/Repository/InvoiceProductRepo.php
Normal file
51
src/Infrastructure/Repository/InvoiceProductRepo.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* InvoiceProductRepo.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/28
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Infrastructure\Repository;
|
||||
|
||||
use Hyperf\Codec\Json;
|
||||
use Money\Currency;
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointPrice;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceProductRepoInterface;
|
||||
|
||||
final class InvoiceProductRepo extends AbstractRepo implements InvoiceProductRepoInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getCaseProduct(string $caseId): InvoiceProduct
|
||||
{
|
||||
$response = $this->requestService->requestGet("/rpc/v2/invoice/$caseId/product");
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new InvoiceProduct(
|
||||
caseId: $result['case_id'],
|
||||
uid: $result['uid'],
|
||||
name: $result['name'],
|
||||
sku: $result['sku'],
|
||||
description: $result['description'],
|
||||
prices: array_map(
|
||||
callback: fn(array $price) => new PointPrice(
|
||||
price: new Money(
|
||||
amount: bcmul((string)$price['amount'], '100', 2),
|
||||
currency: new Currency($price['currency']),
|
||||
),
|
||||
currencySymbol: $price['symbol'],
|
||||
),
|
||||
array: $result['prices'],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
149
src/Infrastructure/Repository/InvoiceRepo.php
Normal file
149
src/Infrastructure/Repository/InvoiceRepo.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* InvoiceRepo.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/29
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Infrastructure\Repository;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Hyperf\Codec\Json;
|
||||
use Money\Currency;
|
||||
use Money\Money;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Singularity\HDK\Core\Exceptions\ValidateException;
|
||||
use Singularity\HDK\Pay\Application\Command\CreateInvoiceCmd;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\Address;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\Invoice;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceInfo;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointBalance;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Repository\InvoiceRepoInterface;
|
||||
|
||||
final class InvoiceRepo extends AbstractRepo implements InvoiceRepoInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function create(CreateInvoiceCmd $cmd): Invoice
|
||||
{
|
||||
$money = $cmd->price;
|
||||
$response = $this->requestService->requestPost(
|
||||
url: "/rpc/v2/account/logs/points/$cmd->caseId/invoices",
|
||||
data: [
|
||||
'set_freq_addr' => $cmd->setFreqInvAddr,
|
||||
'receiver' => $cmd->receiver,
|
||||
'patient_name' => $cmd->patientName,
|
||||
'address' => $cmd->address,
|
||||
'city' => $cmd->city,
|
||||
'state' => $cmd->state,
|
||||
'country' => $cmd->country,
|
||||
'zip' => $cmd->zipCode,
|
||||
'price' => [
|
||||
'amount' => (float)bcmul($money->getAmount(), '100', 2),
|
||||
'currency' => [
|
||||
'code' => $money->getCurrency()->getCode(),
|
||||
'symbol' => $cmd->currencySymbol,
|
||||
],
|
||||
],
|
||||
],
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
$price = $result['price'];
|
||||
return new Invoice(
|
||||
invoiceNo: $result['invoice_no'],
|
||||
uid: $result['uid'],
|
||||
caseId: $result['case_id'],
|
||||
address: new Address(
|
||||
patientName: $result['patient_name'],
|
||||
address: $result['address'],
|
||||
city: $result['city'],
|
||||
state: $result['state'],
|
||||
country: $result['country'],
|
||||
zipCode: $result['zip'],
|
||||
),
|
||||
setFreqInvAddr: $result['set_freq_addr'],
|
||||
receiver: $result['receiver'],
|
||||
price: new Money(
|
||||
bcmul((string)$price['amount'], '100', 2),
|
||||
new Currency($price['code']),
|
||||
),
|
||||
currencySymbol: $price['symbol'],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function send(string $invoiceNo): void
|
||||
{
|
||||
if (empty($invoiceNo)) {
|
||||
throw new ValidateException(message: 'invoice no is required.');
|
||||
}
|
||||
$this->requestService->requestGet(url: "/rpc/v2/invoice/invoices/$invoiceNo/email");
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function download(string $invoiceNo): ResponseInterface
|
||||
{
|
||||
if (empty($invoiceNo)) {
|
||||
throw new ValidateException(message: 'invoice no is required.');
|
||||
}
|
||||
|
||||
return $this->requestService->requestGet(url: "/rpc/v2/invoice/invoices/$invoiceNo/pdf");
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function findOne(string $invoiceNo): InvoiceInfo
|
||||
{
|
||||
if (empty($invoiceNo)) {
|
||||
throw new ValidateException(message: 'invoice no is required.');
|
||||
}
|
||||
|
||||
$response = $this->requestService->requestGet(url: "/rpc/v2/invoice/invoices/$invoiceNo");
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new InvoiceInfo(
|
||||
invoiceNo: $result['invoice_no'],
|
||||
uid: $result['uid'],
|
||||
caseId: $result['case_id'],
|
||||
address: new Address(
|
||||
patientName: $result['patient_name'],
|
||||
address: $result['address']['address'],
|
||||
city: $result['address']['city'],
|
||||
state: $result['address']['state'],
|
||||
country: $result['address']['country'],
|
||||
zipCode: $result['address']['zip_code'],
|
||||
),
|
||||
product: new InvoiceProduct(
|
||||
caseId: $result['case_id'],
|
||||
uid: $result['uid'],
|
||||
name: $result['product']['name'],
|
||||
sku: $result['product']['sku'],
|
||||
description: $result['product']['description'],
|
||||
),
|
||||
balance: new PointBalance(
|
||||
total: $result['balance']['total'],
|
||||
cost: $result['balance']['cost'],
|
||||
remain: $result['balance']['remain'],
|
||||
),
|
||||
receiver: $result['receiver'],
|
||||
invoiceAt: new Carbon($result['invoice_at']),
|
||||
designedAt: new Carbon($result['designed_at']),
|
||||
patientName: $result['patient_name'],
|
||||
);
|
||||
}
|
||||
}
|
||||
77
src/Infrastructure/Repository/OrderRepo.php
Normal file
77
src/Infrastructure/Repository/OrderRepo.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* OrderRepo.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Infrastructure\Repository;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Hyperf\Codec\Json;
|
||||
use Singularity\HDK\Pay\Application\Command\ConsumeCmd;
|
||||
use Singularity\HDK\Pay\Application\Command\RechargeCmd;
|
||||
use Singularity\HDK\Pay\Application\Dto\Transaction\OrderDto;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderAction;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\OrderStatus;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Repository\OrderRepoInterface;
|
||||
|
||||
final class OrderRepo extends AbstractRepo implements OrderRepoInterface
|
||||
{
|
||||
/**
|
||||
* @param RechargeCmd $cmd
|
||||
* @return OrderDto
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function recharge(RechargeCmd $cmd): OrderDto
|
||||
{
|
||||
$response = $this->requestService->requestPost(
|
||||
url: '/rpc/v2/transaction/orders/recharge',
|
||||
data: [
|
||||
'uid' => $cmd->uid,
|
||||
'items' => $cmd->items,
|
||||
],
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new OrderDto(
|
||||
orderNo: $result['order_no'],
|
||||
action: OrderAction::tryFrom($result['action']),
|
||||
payType: PayType::tryFrom($result['pay_type']),
|
||||
status: OrderStatus::tryFrom($result['status']),
|
||||
);
|
||||
}
|
||||
|
||||
public function consume(ConsumeCmd $cmd): OrderDto
|
||||
{
|
||||
$response = $this->requestService->requestPost(
|
||||
url: '/rpc/v2/transaction/orders/consumption',
|
||||
data: [
|
||||
'uid' => $cmd->uid,
|
||||
'type' => $cmd->type->value,
|
||||
'method' => $cmd->method->value,
|
||||
'items' => $cmd->items,
|
||||
'external' => $cmd->external,
|
||||
'external_id' => $cmd->externalID ?? '',
|
||||
'remark' => $cmd->remark,
|
||||
],
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new OrderDto(
|
||||
orderNo: $result['order_no'],
|
||||
action: OrderAction::tryFrom($result['action']),
|
||||
payType: PayType::tryFrom($result['pay_type']),
|
||||
status: OrderStatus::tryFrom($result['status']),
|
||||
);
|
||||
}
|
||||
}
|
||||
89
src/Infrastructure/Repository/PointLogRepo.php
Normal file
89
src/Infrastructure/Repository/PointLogRepo.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PointLogRepo.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/27
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Infrastructure\Repository;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Hyperf\Codec\Json;
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\PointLog;
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\ValueObject\InvoiceRecord;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Account\Repository\PointLogRepoInterface;
|
||||
|
||||
final class PointLogRepo extends AbstractRepo implements PointLogRepoInterface
|
||||
{
|
||||
/**
|
||||
* @param string $uid
|
||||
* @param PointType|null $type
|
||||
* @return array{}|PointLog[]
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function getList(string $uid, ?PointType $type = null): array
|
||||
{
|
||||
$type = isset($type) ? $type->value : 'all';
|
||||
$response = $this->requestService->requestGet(url: "/rpc/v2/account/$uid/balance/$type/logs");
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return array_map(function ($item) {
|
||||
return new PointLog(
|
||||
id: $item['id'],
|
||||
caseId: $item['case_id'],
|
||||
uid: $item['uid'],
|
||||
credits: $item['credits'],
|
||||
source: $item['source'],
|
||||
operator: $item['operator'],
|
||||
description: $item['description'],
|
||||
patientName: $item['patient_name'],
|
||||
date: new Carbon($item['date']),
|
||||
invoiceable: $item['invoiceable'],
|
||||
invoiceRecord: isset($item['invoice_record'])
|
||||
? new InvoiceRecord(
|
||||
invoiceNo: $item['invoice_record']['invoice_no'],
|
||||
receiver: $item['invoice_record']['receiver'],
|
||||
)
|
||||
: null,
|
||||
);
|
||||
}, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getDetail(string $caseId): PointLog
|
||||
{
|
||||
$response = $this->requestService->requestGet(url: "/rpc/v2/account/logs/points/$caseId");
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new PointLog(
|
||||
id: $result['id'],
|
||||
caseId: $result['case_id'],
|
||||
uid: $result['uid'],
|
||||
credits: $result['credits'],
|
||||
source: $result['source'],
|
||||
operator: $result['operator'],
|
||||
description: $result['description'],
|
||||
patientName: $result['patient_name'],
|
||||
date: new Carbon($result['date']),
|
||||
invoiceable: $result['invoiceable'],
|
||||
invoiceRecord: isset($result['invoice_record'])
|
||||
? new InvoiceRecord(
|
||||
$result['invoice_record']['invoice_no'],
|
||||
$result['invoice_record']['receiver'],
|
||||
)
|
||||
: null,
|
||||
);
|
||||
}
|
||||
}
|
||||
221
src/Infrastructure/Repository/ProductRepo.php
Normal file
221
src/Infrastructure/Repository/ProductRepo.php
Normal file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ProductRepo.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Infrastructure\Repository;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Hyperf\Codec\Json;
|
||||
use Money\Currency;
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\Entities\ProductItem;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\RechargeProduct;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\ValueObject\RechargeEffect;
|
||||
use Singularity\HDK\Pay\Domain\Product\Enum\ProductType;
|
||||
use Singularity\HDK\Pay\Domain\Product\Repository\ExchangeRepoInterface;
|
||||
use Singularity\HDK\Pay\Domain\Product\Repository\RechargeProductRepoInterface;
|
||||
|
||||
final class ProductRepo extends AbstractRepo implements RechargeProductRepoInterface, ExchangeRepoInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function findLuxPointProduct(): RechargeProduct
|
||||
{
|
||||
$response = $this->requestService->requestGet(
|
||||
url: '/rpc/v2/products/lux-point',
|
||||
options: [
|
||||
'headers' => $this->headerBuilder(),
|
||||
],
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new RechargeProduct(
|
||||
oneTime: new ProductItem(
|
||||
id: $result['one_time']['id'],
|
||||
description: $result['one_time']['name'],
|
||||
unitPrice: new Money(
|
||||
amount: bcmul((string)$result['one_time']['price'], '100'),
|
||||
currency: new Currency($result['one_time']['currency']),
|
||||
),
|
||||
productType: ProductType::oneTime,
|
||||
effect: new RechargeEffect(
|
||||
pointType: PointType::LuxPoint,
|
||||
pointBasic: $result['one_time']['point']['number'],
|
||||
pointBonus: $result['one_time']['point']['bonus'],
|
||||
),
|
||||
),
|
||||
packages: array_map(
|
||||
fn(array $item) => new ProductItem(
|
||||
id: $item['id'],
|
||||
description: $item['name'],
|
||||
unitPrice: new Money(
|
||||
amount: bcmul((string)$item['price'], '100'),
|
||||
currency: new Currency($item['currency']),
|
||||
),
|
||||
productType: ProductType::pack,
|
||||
effect: new RechargeEffect(
|
||||
pointType: PointType::LuxPoint,
|
||||
pointBasic: $item['point']['number'],
|
||||
pointBonus: $item['point']['bonus'],
|
||||
),
|
||||
),
|
||||
$result['package'] ?? [],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function findFtaiProduct(string $uid, PointType $pointType): RechargeProduct
|
||||
{
|
||||
$response = $this->requestService->requestGet(
|
||||
url: '/rpc/v2/products/ftai',
|
||||
params: ['uid' => $uid, 'type' => $pointType->value],
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new RechargeProduct(
|
||||
oneTime: isset($result['one_time'])
|
||||
? new ProductItem(
|
||||
id: $result['one_time']['id'],
|
||||
description: $result['one_time']['name'],
|
||||
unitPrice: new Money(
|
||||
amount: bcmul((string)$result['one_time']['price'], '100'),
|
||||
currency: new Currency($result['one_time']['currency']),
|
||||
),
|
||||
productType: ProductType::oneTime,
|
||||
effect: new RechargeEffect(
|
||||
pointType: $pointType,
|
||||
pointBasic: $result['one_time']['point']['number'],
|
||||
pointBonus: $result['one_time']['point']['bonus'],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
plans: array_map(
|
||||
fn(array $item) => new ProductItem(
|
||||
id: $item['id'],
|
||||
description: $item['name'],
|
||||
unitPrice: new Money(
|
||||
amount: bcmul((string)$item['price'], '100'),
|
||||
currency: new Currency($item['currency']),
|
||||
),
|
||||
productType: ProductType::plan,
|
||||
),
|
||||
$result['plan'] ?? [],
|
||||
),
|
||||
packages: array_map(
|
||||
fn(array $item) => new ProductItem(
|
||||
id: $item['id'],
|
||||
description: $item['name'],
|
||||
unitPrice: new Money(
|
||||
amount: bcmul((string)$item['price'], '100'),
|
||||
currency: new Currency($item['currency']),
|
||||
),
|
||||
productType: ProductType::plan,
|
||||
effect: new RechargeEffect(
|
||||
pointType: $pointType,
|
||||
pointBasic: $item['point']['number'],
|
||||
pointBonus: $item['point']['bonus'],
|
||||
),
|
||||
),
|
||||
$result['package'] ?? [],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function findEmaProduct(string $uid): RechargeProduct
|
||||
{
|
||||
$response = $this->requestService->requestGet(
|
||||
url: '/rpc/v2/products/ema',
|
||||
params: ['uid' => $uid],
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return new RechargeProduct(
|
||||
oneTime: isset($result['one_time'])
|
||||
? new ProductItem(
|
||||
id: $result['one_time']['id'],
|
||||
description: $result['one_time']['name'],
|
||||
unitPrice: new Money(
|
||||
amount: bcmul((string)$result['one_time']['price'], '100'),
|
||||
currency: new Currency($result['one_time']['currency']),
|
||||
),
|
||||
productType: ProductType::oneTime,
|
||||
effect: new RechargeEffect(
|
||||
pointType: PointType::EMA,
|
||||
pointBasic: $result['one_time']['point']['number'],
|
||||
pointBonus: $result['one_time']['point']['bonus'],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
renew: isset($result['renew'])
|
||||
? new ProductItem(
|
||||
id: $result['renew']['id'],
|
||||
description: $result['renew']['name'],
|
||||
unitPrice: new Money(
|
||||
amount: bcmul((string)$result['renew']['price'], '100'),
|
||||
currency: new Currency($result['renew']['currency']),
|
||||
),
|
||||
productType: ProductType::renew,
|
||||
effect: new RechargeEffect(
|
||||
pointType: PointType::EMA,
|
||||
pointBasic: $result['renew']['point']['number'],
|
||||
pointBonus: $result['renew']['point']['bonus'],
|
||||
),
|
||||
)
|
||||
: null,
|
||||
plans: array_map(
|
||||
fn(array $item) => new ProductItem(
|
||||
id: $item['id'],
|
||||
description: $item['name'],
|
||||
unitPrice: new Money(
|
||||
amount: bcmul((string)$item['price'], '100'),
|
||||
currency: new Currency($item['currency']),
|
||||
),
|
||||
productType: ProductType::plan,
|
||||
effect: new RechargeEffect(
|
||||
pointType: PointType::EMA,
|
||||
pointBasic: $item['point']['number'],
|
||||
pointBonus: $item['point']['bonus'],
|
||||
),
|
||||
),
|
||||
$result['plan'] ?? [],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PointType $source
|
||||
* @param PointType $target
|
||||
* @return float
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function getRate(PointType $source, PointType $target, ?string $uid = null): float
|
||||
{
|
||||
$response = $this->requestService->requestGet(
|
||||
url: "/rpc/v2/products/$target->value/exchange-rate/$source->value",
|
||||
params: array_filter(['uid' => $uid]),
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$result = Json::decode($content);
|
||||
|
||||
return $result['rate'];
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace Singularity\HDK\Pay\Resource\V2;
|
||||
|
||||
use App\Model\ServiceProvider;
|
||||
use Carbon\Carbon;
|
||||
use Hyperf\Resource\Json\JsonResource;
|
||||
use Money\Currency;
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Pay\Enum\OrderStatus;
|
||||
use stdClass;
|
||||
|
||||
@@ -48,6 +48,9 @@ class Order extends JsonResource
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
if (empty($this->resource['order_no'])) {
|
||||
return $this->parseClassicOrder();
|
||||
}
|
||||
return [
|
||||
'order_no' => $this->order_no,
|
||||
'state' => $this->state,
|
||||
@@ -65,6 +68,25 @@ class Order extends JsonResource
|
||||
];
|
||||
}
|
||||
|
||||
private function parseClassicOrder(): array
|
||||
{
|
||||
return [
|
||||
'order_no' => $this->orderNo,
|
||||
'state' => $this->state,
|
||||
'transaction_id' => $this->transactionId,
|
||||
'uid' => $this->uid,
|
||||
'method' => $this->payment,
|
||||
'description' => $this->goodsName,
|
||||
'total_amount' => new Money($this->amount['amount'], new Currency($this->amount['currency'])),
|
||||
'currency' => $this->amount['currency'],
|
||||
'items' => [],
|
||||
'external' => [],
|
||||
'remark' => $this->remark,
|
||||
'notification' => $this->notification ?? [],
|
||||
'more_details' => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->resource->{$key} ?? $this->resource[$key];
|
||||
|
||||
@@ -76,8 +76,8 @@ final class WechatRpc
|
||||
'amount' => (int)$money->getAmount(),
|
||||
'fileType' => $type,
|
||||
'uid' => $uid,
|
||||
'goods_detail' => [
|
||||
'goods_name' => $goodsName,
|
||||
'goodsDetail' => [
|
||||
'goodsName' => $goodsName,
|
||||
],
|
||||
'number' => $number,
|
||||
],
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* WechatService.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/7/17
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Service;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Pay\Service\WechatService@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/7/17
|
||||
*/
|
||||
final class WechatService
|
||||
{
|
||||
|
||||
}
|
||||
36
src/Trait/RequestHeaderBuilder.php
Normal file
36
src/Trait/RequestHeaderBuilder.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* RequestHeaderBuilder.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Trait;
|
||||
|
||||
use Lmc\HttpConstants\Header;
|
||||
use Singularity\HDK\Core\I18n\Enum\Languages;
|
||||
use Singularity\HDK\Pay\Enum\Environment;
|
||||
use Singularity\HDK\Pay\Enum\Site;
|
||||
|
||||
use function Hyperf\Config\config;
|
||||
|
||||
trait RequestHeaderBuilder {
|
||||
public function headerBuilder(): array
|
||||
{
|
||||
return [
|
||||
Header::CONTENT_TYPE => 'application/json',
|
||||
Header::ACCEPT_LANGUAGE => $locale?->value ?? config('translation.locale', Languages::EN->value),
|
||||
'X-SP-ID' => config('app_name'),
|
||||
'X-SITE' => (match (strtoupper(config('site', Site::NorthAmerica->value))) {
|
||||
'CN' => Site::ChinaMainland,
|
||||
default => Site::NorthAmerica,
|
||||
})->value,
|
||||
'X-ENV' => (match (strtolower(config('app_env', Environment::Dev->value))) {
|
||||
'prod', 'production' => Environment::Prod,
|
||||
default => Environment::Dev,
|
||||
})->value,
|
||||
];
|
||||
}
|
||||
}
|
||||
53
tests/Feature/Account/InitialAccountBalanceTest.php
Normal file
53
tests/Feature/Account/InitialAccountBalanceTest.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* InitialAccountBalanceTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/9/17
|
||||
*/
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Singularity\HDK\Pay\Application\Command\InitialAccountCmd;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\AccountBalanceRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should initial account balance', function () {
|
||||
$uid = uniqid('TDD');
|
||||
$data = [
|
||||
[
|
||||
'type' => 'aligner',
|
||||
'basic' => 0,
|
||||
'bonus' => 40,
|
||||
'expired_at' => Carbon::now()->addYear(),
|
||||
'version' => 'trial',
|
||||
],
|
||||
[
|
||||
'type' => 'ema',
|
||||
'basic' => 0,
|
||||
'bonus' => 1,
|
||||
'expired_at' => Carbon::now()->addYear(),
|
||||
'version' => 'Trial',
|
||||
],
|
||||
];
|
||||
|
||||
$cmd = new InitialAccountCmd($uid);
|
||||
foreach ($data as $point_balance) {
|
||||
$cmd->addPointsBalance(
|
||||
type: PointType::from($point_balance['type']),
|
||||
basic: $point_balance['basic'],
|
||||
bonus: $point_balance['bonus'],
|
||||
expiredAt:$point_balance['expired_at'],
|
||||
version: $point_balance['version'],
|
||||
);
|
||||
}
|
||||
|
||||
$repo = make(AccountBalanceRepo::class);
|
||||
$repo->initial($cmd);
|
||||
|
||||
expect(true)->toBeTrue();
|
||||
});
|
||||
23
tests/Feature/Account/QueryAccountInformationTest.php
Normal file
23
tests/Feature/Account/QueryAccountInformationTest.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryAccountInformationTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\AccountBalance;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\AccountBalanceRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should be able to query account information', function () {
|
||||
$uid = '123456';
|
||||
$repo = make(AccountBalanceRepo::class);
|
||||
$result = $repo->getAccount($uid);
|
||||
expect($result)
|
||||
->toBeInstanceOf(AccountBalance::class)
|
||||
->and($result->getUid())->tobe($uid);
|
||||
});
|
||||
24
tests/Feature/Account/QueryPointBalanceTest.php
Normal file
24
tests/Feature/Account/QueryPointBalanceTest.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryPointBalanceTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\Account\PointsBalance;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\AccountBalanceRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should query point balance', function () {
|
||||
$uid = 'cn3221';
|
||||
$repo = make(AccountBalanceRepo::class);
|
||||
$point_balance = $repo->getPointBalance($uid, PointType::EMA);
|
||||
expect($point_balance)
|
||||
->toBeInstanceOf(PointsBalance::class)
|
||||
->and($point_balance->getType())->toBe(PointType::EMA);
|
||||
});
|
||||
34
tests/Feature/Account/QueryPointLogTest.php
Normal file
34
tests/Feature/Account/QueryPointLogTest.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryPointLogTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/27
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Aggregate\PointLog\PointLog;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\PointLogRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should can query point log list', function () {
|
||||
$uid = '61a74db54f387';
|
||||
|
||||
$repo = make(PointLogRepo::class);
|
||||
$list = $repo->getList($uid);
|
||||
expect($list)
|
||||
->not->toBeEmpty()
|
||||
->each
|
||||
->toBeInstanceOf(PointLog::class);
|
||||
});
|
||||
|
||||
it('should can query a point log', function () {
|
||||
$case_id = '68b6ac37a6440';
|
||||
|
||||
$repo = make(PointLogRepo::class);
|
||||
$log = $repo->getDetail($case_id);
|
||||
expect($log)
|
||||
->toBeInstanceOf(PointLog::class);
|
||||
});
|
||||
61
tests/Feature/Invoice/CreateInvoiceTest.php
Normal file
61
tests/Feature/Invoice/CreateInvoiceTest.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CreateInvoiceTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/29
|
||||
*/
|
||||
|
||||
use Money\Money;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Singularity\HDK\Pay\Application\Command\CreateInvoiceCmd;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\Invoice;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should can create invoice', function () {
|
||||
$repo = make(InvoiceRepo::class);
|
||||
|
||||
$invoice = $repo->create(
|
||||
new CreateInvoiceCmd(
|
||||
caseId: '68affb136c01d',
|
||||
setFreqInvAddr: true,
|
||||
receiver: "dongyun.li@luxcreo.ai",
|
||||
patientName: "Ms. Jennifer Durgan",
|
||||
address: "12345 Magnolia Boulevard Northeast,Apartment 5678, Suite 910",
|
||||
city: "Springfield",
|
||||
state: "Illinois",
|
||||
country: "United States",
|
||||
zipCode: "67890-1234",
|
||||
price: Money::EUR('19900'),
|
||||
currencySymbol: '€'
|
||||
),
|
||||
);
|
||||
|
||||
expect($invoice)
|
||||
->toBeInstanceOf(Invoice::class);
|
||||
});
|
||||
|
||||
it('should can send invoice email to receiver', function () {
|
||||
$repo = make(InvoiceRepo::class);
|
||||
|
||||
expect(
|
||||
(function () use ($repo) {
|
||||
$invoice_no = '517268';
|
||||
$repo->send($invoice_no);
|
||||
|
||||
return true;
|
||||
})(),
|
||||
)->not->toThrow(Throwable::class);
|
||||
});
|
||||
|
||||
it('should can download invoice pdf', function () {
|
||||
$repo = make(InvoiceRepo::class);
|
||||
|
||||
$invoice_no = '517268';
|
||||
$response = $repo->download($invoice_no);
|
||||
expect($response)->toBeInstanceOf(ResponseInterface::class);
|
||||
});
|
||||
29
tests/Feature/Invoice/QueryCaseInvoiceProductTest.php
Normal file
29
tests/Feature/Invoice/QueryCaseInvoiceProductTest.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryCaseInvoiceProductTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/28
|
||||
*/
|
||||
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceProduct;
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\ValueObject\PointPrice;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceProductRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should can query case invoice product', function () {
|
||||
/** @var InvoiceProductRepo $invoiceProductRepo */
|
||||
$invoiceProductRepo = make(InvoiceProductRepo::class);
|
||||
|
||||
$caseId = '68affb136c01d';
|
||||
|
||||
$result = $invoiceProductRepo->getCaseProduct(caseId: $caseId);
|
||||
|
||||
expect($result)->toBeInstanceOf(InvoiceProduct::class)
|
||||
->prices->toBeArray()
|
||||
->each->toBeInstanceOf(PointPrice::class);
|
||||
});
|
||||
23
tests/Feature/Invoice/QueryFreqAddrTest.php
Normal file
23
tests/Feature/Invoice/QueryFreqAddrTest.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryFreqAddrTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/29
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Address\FrequentAddress;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\FrequentAddressRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should can query frequent invoice address', function () {
|
||||
$uid = '61dbe752d4caa';
|
||||
|
||||
$addrRepo = make(FrequentAddressRepo::class);
|
||||
$freq_addr = $addrRepo->findByUser($uid);
|
||||
|
||||
expect($freq_addr)->toBeInstanceOf(FrequentAddress::class);
|
||||
});
|
||||
23
tests/Feature/Invoice/QueryInvoiceDetailTest.php
Normal file
23
tests/Feature/Invoice/QueryInvoiceDetailTest.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryInvoiceDetailTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/9/5
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Invoice\Aggregate\Invoice\InvoiceInfo;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\InvoiceRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should can query invoice detail', function () {
|
||||
$repo = make(InvoiceRepo::class);
|
||||
|
||||
$invoiceNo = '517268';
|
||||
$result = $repo->findOne($invoiceNo);
|
||||
expect($result)
|
||||
->toBeInstanceOf(InvoiceInfo::class);
|
||||
});
|
||||
38
tests/Feature/Product/QueryPointRateTest.php
Normal file
38
tests/Feature/Product/QueryPointRateTest.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryPointRateTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\ProductRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('can query point rate', function () {
|
||||
$repo = make(ProductRepo::class);
|
||||
|
||||
$from = PointType::FtaiAligner;
|
||||
$to = PointType::LuxPoint;
|
||||
|
||||
$uid = 'cn3321';
|
||||
|
||||
$rate = $repo->getRate($from, $to, $uid);
|
||||
expect($rate)->toBeFloat();
|
||||
});
|
||||
|
||||
it('can query point rate with uid', function () {
|
||||
$repo = make(ProductRepo::class);
|
||||
|
||||
$from = PointType::FtaiAligner;
|
||||
$to = PointType::LuxPoint;
|
||||
|
||||
$uid = 'cn3321';
|
||||
|
||||
$rate = $repo->getRate($from, $to, $uid);
|
||||
expect($rate)->toBeFloat();
|
||||
});
|
||||
63
tests/Feature/Product/QueryProductsTest.php
Normal file
63
tests/Feature/Product/QueryProductsTest.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* QueryProductsTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
|
||||
use Pest\Expectation;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\Entities\ProductItem;
|
||||
use Singularity\HDK\Pay\Domain\Product\Aggregate\RechargeProduct;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\ProductRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should can query LuxPoint products', function () {
|
||||
$repo = make(ProductRepo::class);
|
||||
|
||||
$products = $repo->findLuxPointProduct();
|
||||
expect($products)
|
||||
->toBeInstanceOf(RechargeProduct::class)
|
||||
->and($products->getOneTime())->toBeInstanceOf(ProductItem::class)
|
||||
->and($products->getPackages())->each->toBeInstanceOf(ProductItem::class);
|
||||
});
|
||||
|
||||
it('should can query EMA products', function () {
|
||||
$repo = make(ProductRepo::class);
|
||||
|
||||
$uid = 'cn3321';
|
||||
$products = $repo->findEmaProduct($uid);
|
||||
expect($products)
|
||||
->toBeInstanceOf(RechargeProduct::class)
|
||||
->when(
|
||||
$products->getOneTime() !== null,
|
||||
fn(Expectation $expectation) => $expectation
|
||||
->and($products->getOneTime())->toBeInstanceOf(ProductItem::class),
|
||||
)
|
||||
->when(
|
||||
$products->getRenew() !== null,
|
||||
fn(Expectation $expectation) => $expectation
|
||||
->and($products->getRenew())->toBeInstanceOf(ProductItem::class),
|
||||
)
|
||||
->and($products->getPlans())->each->toBeInstanceOf(ProductItem::class);
|
||||
});
|
||||
|
||||
it('should can query FTAI products', function () {
|
||||
$repo = make(ProductRepo::class);
|
||||
|
||||
$uid = '61efabc21e5a2';
|
||||
$products = $repo->findFtaiProduct($uid, PointType::FtaiAligner);
|
||||
expect($products)
|
||||
->toBeInstanceOf(RechargeProduct::class)
|
||||
->when(
|
||||
$products->getOneTime() !== null,
|
||||
fn(Expectation $expectation) => $expectation
|
||||
->and($products->getOneTime())->toBeInstanceOf(ProductItem::class),
|
||||
)
|
||||
->and($products->getPackages())->each->toBeInstanceOf(ProductItem::class)
|
||||
->and($products->getPlans())->each->toBeInstanceOf(ProductItem::class);
|
||||
});
|
||||
34
tests/Feature/Transaction/CreateConsumptionOrderTest.php
Normal file
34
tests/Feature/Transaction/CreateConsumptionOrderTest.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CreateConsumptionOrderTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Pay\Application\Command\ConsumeCmd;
|
||||
use Singularity\HDK\Pay\Application\Dto\Transaction\OrderDto;
|
||||
use Singularity\HDK\Pay\Domain\Account\Enum\PointType;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Enum\PayType;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\OrderRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should can create consumption order', function () {
|
||||
$uid = 'cn3321';
|
||||
|
||||
$cmd = (new ConsumeCmd(
|
||||
uid: $uid,
|
||||
type: PayType::Point,
|
||||
method: PointType::FtaiAligner,
|
||||
external: [],
|
||||
externalID: null,
|
||||
remark: '',
|
||||
))->addItem('Design FTAI Aligner', 1, 5);
|
||||
|
||||
$repo = make(OrderRepo::class);
|
||||
$result = $repo->consume($cmd);
|
||||
expect($result)->toBeInstanceOf(OrderDto::class);
|
||||
});
|
||||
23
tests/Feature/Transaction/CreateRechargeOrderTest.php
Normal file
23
tests/Feature/Transaction/CreateRechargeOrderTest.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* CreateRechargeOrderTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/18
|
||||
*/
|
||||
|
||||
use Singularity\HDK\Pay\Application\Command\RechargeCmd;
|
||||
use Singularity\HDK\Pay\Application\Dto\Transaction\OrderDto;
|
||||
use Singularity\HDK\Pay\Infrastructure\Repository\OrderRepo;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
it('should can create recharge order', function () {
|
||||
$cmd = (new RechargeCmd('cn3321'))->addItem(1, 2);
|
||||
|
||||
$repo = make(OrderRepo::class);
|
||||
$result = $repo->recharge($cmd);
|
||||
expect($result)->toBeInstanceOf(OrderDto::class);
|
||||
});
|
||||
99
tests/Feature/Transaction/LuxPayCallbackTest.php
Normal file
99
tests/Feature/Transaction/LuxPayCallbackTest.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* LuxPayCallbackTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2025/8/20
|
||||
*/
|
||||
|
||||
use Hyperf\Codec\Json;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Aggregate\TransactionRecord;
|
||||
use Singularity\HDK\Pay\Domain\Transaction\Service\CallbackDomainSvc;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
dataset('cases', [
|
||||
'recharge' => [
|
||||
<<<JSON
|
||||
{
|
||||
"order_no": "202508191929138659DTB",
|
||||
"uid": "cn3321",
|
||||
"pay_type": "card",
|
||||
"action": "recharge",
|
||||
"status": "created",
|
||||
"source": "LuxDesign",
|
||||
"items": [
|
||||
{
|
||||
"name": "Starter Pack",
|
||||
"unit_price": 399,
|
||||
"quantity": 1
|
||||
}
|
||||
],
|
||||
"transactions": [
|
||||
{
|
||||
"pay_type": "card",
|
||||
"type": "stripe.checkout",
|
||||
"amount": 399,
|
||||
"status": "created"
|
||||
}
|
||||
],
|
||||
"refunds": [],
|
||||
"external": [],
|
||||
"external_id": "",
|
||||
"created_at": "2025-08-20 10:44:46",
|
||||
"occurred_at": null,
|
||||
"last_refunded_at": null
|
||||
}
|
||||
JSON,
|
||||
],
|
||||
'consumption' => [
|
||||
<<<JSON
|
||||
{
|
||||
"order_no": "202508190441101116DTB",
|
||||
"uid": "cn3321",
|
||||
"pay_type": "hybrid",
|
||||
"action": "consumption",
|
||||
"status": "created",
|
||||
"source": "LuxDesign",
|
||||
"items": [
|
||||
{
|
||||
"name": "Design - retainer",
|
||||
"quantity": 1,
|
||||
"unit_price": 3
|
||||
}
|
||||
],
|
||||
"transactions": [
|
||||
{
|
||||
"pay_type": "card",
|
||||
"type": "stripe.checkout",
|
||||
"amount": 3,
|
||||
"status": "created"
|
||||
},
|
||||
{
|
||||
"pay_type": "point",
|
||||
"type": "lux-point",
|
||||
"amount": 3.05,
|
||||
"status": "created"
|
||||
}
|
||||
],
|
||||
"refunds": [],
|
||||
"external": [],
|
||||
"external_id": "",
|
||||
"created_at": "2025-08-20 10:44:46",
|
||||
"occurred_at": null,
|
||||
"last_refunded_at": null
|
||||
}
|
||||
JSON,
|
||||
]
|
||||
]);
|
||||
|
||||
it(
|
||||
'should parse request recharge body to TransactionRecord Entity',
|
||||
function ($data) {
|
||||
$data = Json::decode($data);
|
||||
$entity = make(CallbackDomainSvc::class)->callback($data);
|
||||
expect($entity)->toBeInstanceOf(TransactionRecord::class);
|
||||
},
|
||||
)->with('cases');
|
||||
53
tests/HttpTestCase.php
Normal file
53
tests/HttpTestCase.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Test\Pay;
|
||||
|
||||
use Hyperf\Testing\Client;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
/**
|
||||
* Class HttpTestCase.
|
||||
* @method get($uri, $data = [], $headers = [])
|
||||
* @method post($uri, $data = [], $headers = [])
|
||||
* @method json($uri, $data = [], $headers = [])
|
||||
* @method file($uri, $data = [], $headers = [])
|
||||
* @method request($method, $path, $options = [])
|
||||
*/
|
||||
abstract class HttpTestCase extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Client
|
||||
*/
|
||||
protected Client $client;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct(?string $name = null)
|
||||
{
|
||||
parent::__construct($name);
|
||||
$this->client = make(Client::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array<string, mixed> $arguments
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function __call(string $name, array $arguments): array
|
||||
{
|
||||
return $this->client->{$name}(...$arguments);
|
||||
}
|
||||
}
|
||||
32
tests/Pest.php
Normal file
32
tests/Pest.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Singularity\HDK\Test\Pay\HttpTestCase;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Test Case
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The closure you provide to your tests functions is always bound to a specific PHPUnit tests
|
||||
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
|
||||
| need to change it using the "uses()" function to bind a different classes or traits.
|
||||
|
|
||||
*/
|
||||
|
||||
// uses(HttpTestCase::class)->in('Feature');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Functions
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
|
||||
| project that you don't want to repeat in every file. Here you can also expose helpers as
|
||||
| global functions to help you to reduce the number of lines of code in your tests files.
|
||||
|
|
||||
*/
|
||||
|
||||
/*function something()
|
||||
{
|
||||
// ..
|
||||
}*/
|
||||
@@ -32,4 +32,4 @@ test(
|
||||
);
|
||||
expect($goods)->toBeInstanceOf(Goods::class);
|
||||
}
|
||||
);
|
||||
)->skip();
|
||||
|
||||
@@ -29,7 +29,7 @@ test('能够正常创建 Stripe 订单', function () {
|
||||
service: 1
|
||||
);
|
||||
expect($order)->toBeInstanceOf(Order::class);
|
||||
});
|
||||
})->skip();
|
||||
|
||||
test('能够正常获取 Stripe 配置信息', function () {
|
||||
/** @var StripeRpc $service */
|
||||
@@ -40,4 +40,4 @@ test('能够正常获取 Stripe 配置信息', function () {
|
||||
->toBeInstanceOf(StripeConfiguration::class)
|
||||
->toHaveKeys(['id', 'pk'])
|
||||
->and($configures->resolve())->toBeArray();
|
||||
});
|
||||
})->skip();
|
||||
|
||||
@@ -2,19 +2,16 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://hyperf.wiki
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
use Hyperf\Config\Config;
|
||||
use Hyperf\Context\ApplicationContext;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Di\ClassLoader;
|
||||
use Hyperf\Di\Container;
|
||||
use Hyperf\Di\Definition\DefinitionSource;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Swoole\Runtime;
|
||||
|
||||
use function Hyperf\Support\env;
|
||||
use function Hyperf\Support\make;
|
||||
|
||||
ini_set('display_errors', 'on');
|
||||
ini_set('display_startup_errors', 'on');
|
||||
@@ -22,16 +19,26 @@ ini_set('display_startup_errors', 'on');
|
||||
error_reporting(E_ALL);
|
||||
date_default_timezone_set('Asia/Shanghai');
|
||||
|
||||
|
||||
!defined('BASE_PATH') && define('BASE_PATH', dirname(__DIR__, 1));
|
||||
!defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL);
|
||||
|
||||
Swoole\Runtime::enableCoroutine(true);
|
||||
Runtime::enableCoroutine(SWOOLE_HOOK_FLAGS);
|
||||
|
||||
require BASE_PATH . '/vendor/autoload.php';
|
||||
Hyperf\Di\ClassLoader::init();
|
||||
ClassLoader::init();
|
||||
|
||||
$container = new Container(new DefinitionSource([]));
|
||||
if (!$container instanceof ContainerInterface) {
|
||||
throw new RuntimeException('The dependency injection container is invalid.');
|
||||
}
|
||||
$container = ApplicationContext::setContainer($container);
|
||||
$container = ApplicationContext::setContainer($container);
|
||||
|
||||
/** @var Config $config */
|
||||
$config = make(Config::class, [
|
||||
[
|
||||
'app_name' => 'LuxDesign',
|
||||
'dependencies' => [],
|
||||
'payment' => [
|
||||
'base_uri' => env('LUX_PAY_BASE_URI', 'http://test-pay.luxcreo.com'),
|
||||
],
|
||||
],
|
||||
]);
|
||||
ApplicationContext::getContainer()->set(ConfigInterface::class, $config);
|
||||
|
||||
Reference in New Issue
Block a user