mirror of
http://124.126.16.154:8888/singularity/hdk-pay.git
synced 2026-01-15 07:35:09 +08:00
Compare commits
31 Commits
v1.0.0-alp
...
v1.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
271cdb3c0a | ||
|
|
816649784d | ||
|
|
d12858dda8 | ||
|
|
4d1b5d2ab7 | ||
|
|
8cb8f7eb9e | ||
|
|
c13fc7e800 | ||
|
|
8d6c0189a0 | ||
|
|
dd690e228e | ||
|
|
46ecc8117c | ||
|
|
456294c1a4 | ||
|
|
a6898bb1a0 | ||
|
|
999f3633a5 | ||
|
|
6431fc010f | ||
|
|
cb0b3a3548 | ||
|
|
b8ebebde3c | ||
|
|
1dba3b84a4 | ||
|
|
6cecc96c5f | ||
|
|
448569583c | ||
|
|
99af043376 | ||
|
|
90dde97bc9 | ||
|
|
f7e1386c78 | ||
|
|
a6b33ed0ab | ||
|
|
a532e21f02 | ||
|
|
64dd159f9c | ||
|
|
a50216f2fc | ||
|
|
ff86edf89b | ||
|
|
eb9c9557c5 | ||
|
|
4b5e1740bc | ||
|
|
7401c97860 | ||
|
|
22bb6a4ed2 | ||
|
|
98dbe19a5a |
28
.gitea/workflows/publish_on_tagged.yml
Normal file
28
.gitea/workflows/publish_on_tagged.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Release development version to registry
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '**.**'
|
||||
|
||||
jobs:
|
||||
Publish on Tagged:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v4
|
||||
- run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
|
||||
- name: List files in the repository
|
||||
run: |
|
||||
ls ${{ gitea.workspace }}
|
||||
- name: Zip files in the repository
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install zip
|
||||
zip -r dist.zip *
|
||||
- name: Publish to registry
|
||||
run: |
|
||||
curl --user ch4o5:4fd300672472e666014314c1c94c604c634165a9 \
|
||||
--upload-file ./dist.zip \
|
||||
https://nest.doylee.cn/api/packages/HDK/composer?version=${{ gitea.ref_name }}
|
||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
composer.phar
|
||||
vendor/
|
||||
.idea/
|
||||
.phpunit.result.cache
|
||||
.phpunit.result.cache
|
||||
runtime/
|
||||
103
CHANGELOG.md
103
CHANGELOG.md
@@ -1,4 +1,107 @@
|
||||
# 版本更新日志
|
||||
## [1.0.0-beta.0](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.12...v1.0.0-beta.0) (2024-02-27)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **hyperf:** 迁移到 hyperf3.1 ([d12858d](http://124.126.16.154:8888/singularity/hdk-pay/commit/d12858dda85fd2ce66ca1daff7e27eb381450d2f))
|
||||
* **release:** 发布 beta ([8166497](http://124.126.16.154:8888/singularity/hdk-pay/commit/816649784d5a85b7bd2d61e5415258c0b514dcc1))
|
||||
|
||||
## [1.0.0-alpha.12](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.11...v1.0.0-alpha.12) (2023-10-23)
|
||||
|
||||
|
||||
### 👷 Continuous Integration | CI 配置
|
||||
|
||||
* 修复内容为空的问题 ([8cb8f7e](http://124.126.16.154:8888/singularity/hdk-pay/commit/8cb8f7eb9e8d97408a3a71fec75699579b058c09))
|
||||
|
||||
## [1.0.0-alpha.11](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.10...v1.0.0-alpha.11) (2023-10-23)
|
||||
|
||||
|
||||
### 👷 Continuous Integration | CI 配置
|
||||
|
||||
* 迁移到 Gitea Actions ([8d6c018](http://124.126.16.154:8888/singularity/hdk-pay/commit/8d6c0189a0198d5d6e11e90cd8293107f414273c))
|
||||
|
||||
## [1.0.0-alpha.10](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.9...v1.0.0-alpha.10) (2023-09-26)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **composer:** 更新依赖 ([46ecc81](http://124.126.16.154:8888/singularity/hdk-pay/commit/46ecc8117ccb463ed498fa82e84bf41d9ebb752b))
|
||||
|
||||
## [1.0.0-alpha.9](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.8...v1.0.0-alpha.9) (2023-09-26)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **stripe:** 创建 session 接口增加了语言选项 ([a6898bb](http://124.126.16.154:8888/singularity/hdk-pay/commit/a6898bb1a097f3c66d3ef14f375725fdeaed4df5))
|
||||
|
||||
## [1.0.0-alpha.8](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.7...v1.0.0-alpha.8) (2023-09-22)
|
||||
|
||||
|
||||
### 🐛 Bug Fixes | Bug 修复
|
||||
|
||||
* **order:** 修复类型错误的问题 ([6431fc0](http://124.126.16.154:8888/singularity/hdk-pay/commit/6431fc010fe3e989773b84506df62d3c8f7ffc81))
|
||||
|
||||
## [1.0.0-alpha.7](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.6...v1.0.0-alpha.7) (2023-09-22)
|
||||
|
||||
|
||||
### ⚡ Performance Improvements | 性能优化
|
||||
|
||||
* **callback:** 增加了共用的通知业务系统的方法 ([b8ebebd](http://124.126.16.154:8888/singularity/hdk-pay/commit/b8ebebde3c5835bb0abc6e5078517c82341db95f))
|
||||
|
||||
## [1.0.0-alpha.6](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.5...v1.0.0-alpha.6) (2023-09-22)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **composer:** 兼容 hyperf 的 RequestInterface ([6cecc96](http://124.126.16.154:8888/singularity/hdk-pay/commit/6cecc96c5ffc223a1a72df6abd1f07d54cb7953d))
|
||||
|
||||
## [1.0.0-alpha.5](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.4...v1.0.0-alpha.5) (2023-09-22)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **composer:** 增加 hyperf/contract 包,更新依赖 ([90dde97](http://124.126.16.154:8888/singularity/hdk-pay/commit/90dde97bc90d33917eb2c1a4d09779dd45776d30))
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **stripe:** 增加 callback 对请求的转化 ([99af043](http://124.126.16.154:8888/singularity/hdk-pay/commit/99af043376c4b44412a275d1b778e3e3584f5f96))
|
||||
|
||||
## [1.0.0-alpha.4](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.3...v1.0.0-alpha.4) (2023-09-20)
|
||||
|
||||
|
||||
### ✏️ Documentation | 文档
|
||||
|
||||
* **resource:** 更新了资源的字段注释 ([a6b33ed](http://124.126.16.154:8888/singularity/hdk-pay/commit/a6b33ed0abed2d23b041407c0a6a58e8405e075c))
|
||||
|
||||
## [1.0.0-alpha.3](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.2...v1.0.0-alpha.3) (2023-09-20)
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **stripe:** 实现了 stripe 获取配置信息的服务方法 ([64dd159](http://124.126.16.154:8888/singularity/hdk-pay/commit/64dd159f9c153183d22e51390a8d670e5bfd7385))
|
||||
|
||||
## [1.0.0-alpha.2](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.1...v1.0.0-alpha.2) (2023-09-19)
|
||||
|
||||
|
||||
### 📦 Build System | 打包构建
|
||||
|
||||
* **composer:** 更新依赖 ([22bb6a4](http://124.126.16.154:8888/singularity/hdk-pay/commit/22bb6a4ed2f8f76ed7960cd3dc116cdbf3370abb))
|
||||
* **script:** 版本最低为 8.1 ([7401c97](http://124.126.16.154:8888/singularity/hdk-pay/commit/7401c9786011a27e658075036301aef9e9cb9eed))
|
||||
|
||||
|
||||
### ⚡ Performance Improvements | 性能优化
|
||||
|
||||
* 使用更先进的 hdk 方法创建 http 请求 ([4b5e174](http://124.126.16.154:8888/singularity/hdk-pay/commit/4b5e1740bca1e83820de207d4d0c8bea0e94a42f))
|
||||
|
||||
|
||||
### ✨ Features | 新功能
|
||||
|
||||
* **enum:** 增加订单相关的枚举类型 ([98dbe19](http://124.126.16.154:8888/singularity/hdk-pay/commit/98dbe19a5a5091ae6549c32d91b58f6c94a507c2))
|
||||
* **pest:** 支持了依赖注入 ([eb9c955](http://124.126.16.154:8888/singularity/hdk-pay/commit/eb9c9557c51cb80531886f1929cfeb0c949054b5))
|
||||
* **stripe:** 实现了 stripe 创建订单的服务方法 ([ff86edf](http://124.126.16.154:8888/singularity/hdk-pay/commit/ff86edf89b1a7ed459349f4101251bc654cda69c))
|
||||
|
||||
## [1.0.0-alpha.1](http://124.126.16.154:8888/singularity/hdk-pay/compare/v1.0.0-alpha.0...v1.0.0-alpha.1) (2023-07-25)
|
||||
|
||||
|
||||
|
||||
@@ -14,26 +14,28 @@
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"php": ">=8.2",
|
||||
"composer/composer": ">=2.5.8",
|
||||
"hyperf/guzzle": "~3.0.0",
|
||||
"moneyphp/money": "^4.1",
|
||||
"singularity/hdk-core": "^1.0.0",
|
||||
"hyperf/contract": "~3.0.0",
|
||||
"hyperf/config": "~3.0.0",
|
||||
"hyperf/di": "~3.0.0"
|
||||
"hyperf/contract": "~3.1.0",
|
||||
"hyperf/constants": "3.1.*",
|
||||
"hyperf/config": "~3.1.0",
|
||||
"hyperf/di": "~3.1.0",
|
||||
"hyperf/http-server": "3.1.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"cooper/hyperf-pest": "^1.1",
|
||||
"firebase/php-jwt": "^6.8.0",
|
||||
"phpunit/phpunit": "^9.6.9"
|
||||
"hyperf/testing": "^3.1",
|
||||
"friendsofhyperf/pest-plugin-hyperf": "3.1.*",
|
||||
"swoole/ide-helper": "^4.8.13"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"minimum-stability": "beta",
|
||||
"prefer-stable": true,
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true,
|
||||
"secure-http": false,
|
||||
"allow-plugins": {
|
||||
"pestphp/pest-plugin": true
|
||||
}
|
||||
@@ -45,20 +47,20 @@
|
||||
"test": [
|
||||
"rm -rf runtime",
|
||||
"Composer\\Config::disableProcessTimeout",
|
||||
"co-pest --prepend tests/bootstrap.php -c phpunit.xml --colors=always"
|
||||
"APP_STATUS=false pest --coroutine --prepend=tests/bootstrap.php --colors=always $1"
|
||||
],
|
||||
"cs-fix": "php-cs-fixer fix $1",
|
||||
"analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config"
|
||||
},
|
||||
"repositories": {
|
||||
"lux-map": {
|
||||
"nest": {
|
||||
"type": "composer",
|
||||
"url": "https://satis.luxcreo.cn/"
|
||||
"url": "https://nest.doylee.cn/api/packages/HDK/composer"
|
||||
},
|
||||
"packagist": {
|
||||
"type": "composer",
|
||||
"url": "https://mirrors.cloud.tencent.com/composer/"
|
||||
"url": "https://mirrors.aliyun.com/composer/"
|
||||
}
|
||||
},
|
||||
"version": "1.0.0-alpha.1"
|
||||
"version": "1.0.0-beta.0"
|
||||
}
|
||||
|
||||
6870
composer.lock
generated
6870
composer.lock
generated
File diff suppressed because it is too large
Load Diff
10
phpunit.xml
10
phpunit.xml
@@ -1,10 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="vendor/autoload.php"
|
||||
colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd">
|
||||
<coverage/>
|
||||
<phpunit
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Pest">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<source/>
|
||||
</phpunit>
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
|
||||
docker run \
|
||||
--pull always \
|
||||
-ti --rm --name "hdk-pay" \
|
||||
-w "/srv/www" \
|
||||
-v "$(pwd)":/srv/www \
|
||||
-v ~/.ssh:/root/.ssh \
|
||||
harbor.luxcreo.cn/library/hyperf:8.0-swoole /bin/ash
|
||||
harbor.luxcreo.cn/library/hyperf:8.2-swoole /bin/ash
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
docker run --rm -it \
|
||||
-v $(pwd):/app -e "GIT_AUTHOR_NAME=ch4o5" -e "EMAIL=dongyun.li@luxcreo.ai" \
|
||||
detouched/standard-version:latest -p=alpha $1
|
||||
detouched/standard-version:latest -p=beta $1
|
||||
|
||||
23
src/Enum/CurrencyEnum.php
Normal file
23
src/Enum/CurrencyEnum.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Currencies.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/5/17
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Enum;
|
||||
|
||||
use Money\Currency;
|
||||
|
||||
enum CurrencyEnum
|
||||
{
|
||||
case CNY;
|
||||
case USD;
|
||||
|
||||
public function getInstance(): Currency
|
||||
{
|
||||
return new Currency($this->name);
|
||||
}
|
||||
}
|
||||
54
src/Enum/OrderStatus.php
Normal file
54
src/Enum/OrderStatus.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* OrderStatus.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/5/19
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Singularity\HDK\Pay\Enum;
|
||||
|
||||
/**
|
||||
* App\Enum\OrderStatus@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/5/19
|
||||
*/
|
||||
enum OrderStatus: string
|
||||
{
|
||||
case Created = "Created";
|
||||
|
||||
case Paid = 'Paid';
|
||||
|
||||
case Cancelled = 'Cancelled';
|
||||
|
||||
case Closed = 'Closed';
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
$list = [];
|
||||
foreach (self::cases() as $key) {
|
||||
$list[] = $key->name;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
// public static function from(string $value): ?OrderStatus
|
||||
// {
|
||||
// var_dump($value, __METHOD__);
|
||||
// return match ($value) {
|
||||
// 'Created' => OrderStatus::Created,
|
||||
// 'Paid' => OrderStatus::Paid,
|
||||
// 'Cancelled' => OrderStatus::Cancelled,
|
||||
// 'Closed' => OrderStatus::Closed,
|
||||
// default => null
|
||||
// };
|
||||
// }
|
||||
}
|
||||
53
src/Enum/PaymentMethod.php
Normal file
53
src/Enum/PaymentMethod.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* PaymentMethod.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/9/19
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Enum;
|
||||
|
||||
enum PaymentMethod: string
|
||||
{
|
||||
case Stripe = 'stripe';
|
||||
|
||||
case WechatPay = 'wechat';
|
||||
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
$list = [];
|
||||
foreach (self::cases() as $key) {
|
||||
$list[$key->name] = $key->value;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function values(): array
|
||||
{
|
||||
$list = [];
|
||||
foreach (self::cases() as $key) {
|
||||
$list[] = $key->value;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function keys(): array
|
||||
{
|
||||
$list = [];
|
||||
foreach (self::cases() as $key) {
|
||||
$list[] = $key->name;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
26
src/Resource/GoodsCollection.php
Normal file
26
src/Resource/GoodsCollection.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* GoodsCollection.php@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/7/20
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Resource;
|
||||
|
||||
use Hyperf\Resource\Json\ResourceCollection;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Pay\Resource\ GoodsCollection@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/9/20
|
||||
*/
|
||||
final class GoodsCollection extends ResourceCollection
|
||||
{
|
||||
public ?string $wrap = null;
|
||||
}
|
||||
69
src/Resource/Order.php
Normal file
69
src/Resource/Order.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Singularity\HDK\Pay\Resource;
|
||||
|
||||
use Hyperf\Resource\Json\JsonResource;
|
||||
use Money\Currency;
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Pay\Enum\OrderStatus;
|
||||
|
||||
/**
|
||||
* App\Resource\ Order@LuxPay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/9/19
|
||||
*
|
||||
* @property-read string $orderNo
|
||||
* @property-read string transactionId
|
||||
* @property-read Money amount
|
||||
* @property-read OrderStatus state
|
||||
* @property-read string uid
|
||||
* @property-read string payment
|
||||
* @property-read string remark
|
||||
*/
|
||||
class Order extends JsonResource
|
||||
{
|
||||
public ?string $wrap = null;
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array{
|
||||
* orderNo: string,
|
||||
* transactionId: string,
|
||||
* amount: Money,
|
||||
* state: OrderStatus,
|
||||
* uid: string,
|
||||
* payment: string,
|
||||
* remark: string
|
||||
* }
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
// 'id ' => $this->id,
|
||||
'orderNo' => $this->resource['orderNo'],
|
||||
'transactionId' => $this->resource['transactionId'],
|
||||
'goodsName' => $this->resource['goodsName'],
|
||||
'amount' => new Money(
|
||||
$this->resource['amount']['amount'],
|
||||
new Currency($this->resource['amount']['currency'])
|
||||
),
|
||||
'state' => OrderStatus::from($this->resource['state']),
|
||||
'uid' => $this->resource['uid'],
|
||||
'payment' => $this->resource['payment'],
|
||||
'remark' => $this->resource['remark'],
|
||||
// extends
|
||||
// 'spId' => $this->spId,
|
||||
// 'goodsDetail' => GoodsCollection::make([$this->goodsDetail])->resolve(),
|
||||
// 'goodsDetail' => $this->goodsDetail,
|
||||
// 'notification' => $this->notification,
|
||||
];
|
||||
}
|
||||
|
||||
public function __get($key)
|
||||
{
|
||||
return $this->resource->{$key} ?? $this->resource[$key];
|
||||
}
|
||||
}
|
||||
45
src/Resource/StripeConfiguration.php
Normal file
45
src/Resource/StripeConfiguration.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* StripeConfiguration.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/9/20
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Resource;
|
||||
|
||||
use Hyperf\Resource\Json\JsonResource;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Pay\Resource\StripeConfiguration@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/9/20
|
||||
*
|
||||
* @property-read string $id The unique identifier for this stripe account
|
||||
* @property-read string $pk The publishable key for this stripe account
|
||||
*/
|
||||
final class StripeConfiguration extends JsonResource
|
||||
{
|
||||
public ?string $wrap = null;
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->resource['id'],
|
||||
'pk' => $this->resource['pk'],
|
||||
'sk' => $this->when(isset($this->resource['sk']), fn() => $this->resource['sk']),
|
||||
'webhookSecret' => $this->when(isset($this->webhookSecret), fn() =>$this->resource['webhookSecret']),
|
||||
'notifyUrl' => $this->when(!empty($this->resource['notifyUrl']), fn() => $this->resource['notifyUrl'])
|
||||
];
|
||||
}
|
||||
|
||||
public function __get($key): ?string
|
||||
{
|
||||
return $this->resource[$key] ?? null;
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,22 @@ namespace Singularity\HDK\Pay\Sdk;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use Hyperf\Codec\Json;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Singularity\HDK\Core\Service\HttpRequestService;
|
||||
use Singularity\HDK\Core\Http\RequestService;
|
||||
use Singularity\HDK\Core\Http\RequestServiceFactory;
|
||||
use Singularity\HDK\Pay\Resource\Goods;
|
||||
|
||||
use function Hyperf\Config\config;
|
||||
|
||||
final class GoodsRpc
|
||||
{
|
||||
public function __construct(private HttpRequestService $requestService, private ?string $baseUri = null)
|
||||
private RequestService $requestService;
|
||||
|
||||
public function __construct(?string $baseUri = null)
|
||||
{
|
||||
$this->baseUri ??= config('payment.base_uri');
|
||||
if (empty($this->baseUri)) {
|
||||
throw new \InvalidArgumentException('payment.base_uri is required');
|
||||
}
|
||||
$this->requestService->setOptions(
|
||||
[
|
||||
'base_uri' => $this->baseUri,
|
||||
RequestOptions::ALLOW_REDIRECTS => true,
|
||||
]
|
||||
);
|
||||
$this->requestService = RequestServiceFactory::make([
|
||||
'base_uri' => $baseUri ?? config('payment.base_uri'),
|
||||
RequestOptions::ALLOW_REDIRECTS => true,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,8 +41,6 @@ final class GoodsRpc
|
||||
*/
|
||||
public function find(int $goodsId, array $specifies): Goods
|
||||
{
|
||||
$url = $this->baseUri . '/rpc/v1/wechat/qrcode';
|
||||
|
||||
$response = $this->requestService->requestGet("/rpc/v1/goods/$goodsId/search", $specifies);
|
||||
$content = $response->getBody()->getContents();
|
||||
return Goods::make(Json::decode($content));
|
||||
|
||||
105
src/Sdk/StripeRpc.php
Normal file
105
src/Sdk/StripeRpc.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* WechatRpc.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/7/17
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Sdk;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use Hyperf\Codec\Json;
|
||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||
use Lmc\HttpConstants\Header;
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Core\Http\RequestService;
|
||||
use Singularity\HDK\Core\Http\RequestServiceFactory;
|
||||
use Singularity\HDK\Core\I18n\Enum\Languages;
|
||||
use Singularity\HDK\Pay\Resource\Order;
|
||||
use Singularity\HDK\Pay\Resource\StripeConfiguration;
|
||||
|
||||
use Singularity\HDK\Pay\Trait\WebhooksNotificationHandler;
|
||||
|
||||
use function Hyperf\Config\config;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Pay\Sdk\WechatRpc@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/7/17
|
||||
*/
|
||||
final class StripeRpc
|
||||
{
|
||||
use WebhooksNotificationHandler;
|
||||
|
||||
private RequestService $requestService;
|
||||
|
||||
public function __construct(?string $baseUrl = null)
|
||||
{
|
||||
$this->requestService = RequestServiceFactory::make([
|
||||
'base_uri' => $baseUrl ?? config('payment.base_uri'),
|
||||
RequestOptions::ALLOW_REDIRECTS => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getConfigurations(): StripeConfiguration
|
||||
{
|
||||
$resp = $this->requestService->requestGet('/rpc/v1/stripe/configurations');
|
||||
|
||||
$content = $resp->getBody()->getContents();
|
||||
$order = Json::decode($content);
|
||||
return StripeConfiguration::make($order);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Money $money
|
||||
* @param string $uid
|
||||
* @param int $goodsId
|
||||
* @param string $goodsName
|
||||
* @param array $goodsDetail
|
||||
* @return Order
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function createSession(
|
||||
Money $money,
|
||||
string $uid,
|
||||
int $goodsId,
|
||||
string $goodsName,
|
||||
array $goodsDetail,
|
||||
?Languages $locale = null,
|
||||
?int $service = null,
|
||||
): Order {
|
||||
$response = $this->requestService->requestPost(
|
||||
url: '/rpc/v1/stripe/order',
|
||||
data: [
|
||||
'service' => $service ?? config('payment.sp_id'),
|
||||
'amount' => $money->getAmount(),
|
||||
'currency' => (string)$money->getCurrency(),
|
||||
'uid' => $uid,
|
||||
'goodsDetail' => array_replace(
|
||||
$goodsDetail,
|
||||
[
|
||||
'id' => $goodsId,
|
||||
'goodsName' => $goodsName,
|
||||
]
|
||||
),
|
||||
],
|
||||
options: [
|
||||
'headers' => [
|
||||
Header::CONTENT_TYPE => 'application/json',
|
||||
Header::ACCEPT_LANGUAGE => $locale?->value ?? config('translation.locale')
|
||||
]
|
||||
]
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
$order = Json::decode($content);
|
||||
return Order::make($order);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* WechatRpc.php@Pay
|
||||
@@ -11,12 +12,14 @@ declare(strict_types=1);
|
||||
namespace Singularity\HDK\Pay\Sdk;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\RequestOptions;
|
||||
use Hyperf\Codec\Json;
|
||||
use Hyperf\Di\Annotation\Inject;
|
||||
use Lmc\HttpConstants\Header;
|
||||
use Money\Money;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Singularity\HDK\Core\Service\HttpRequestService;
|
||||
use Singularity\HDK\Core\Http\RequestService;
|
||||
use Singularity\HDK\Core\Http\RequestServiceFactory;
|
||||
use Singularity\HDK\Pay\Trait\WebhooksNotificationHandler;
|
||||
|
||||
use function Hyperf\Config\config;
|
||||
|
||||
@@ -29,9 +32,17 @@ use function Hyperf\Config\config;
|
||||
*/
|
||||
final class WechatRpc
|
||||
{
|
||||
#[Inject]
|
||||
private HttpRequestService $requestService;
|
||||
use WebhooksNotificationHandler;
|
||||
|
||||
private RequestService $requestService;
|
||||
|
||||
public function __construct(?string $baseUrl = null)
|
||||
{
|
||||
$this->requestService = RequestServiceFactory::make([
|
||||
'base_uri' => $baseUrl ?? config('payment.base_uri'),
|
||||
RequestOptions::ALLOW_REDIRECTS => true,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestInterface $request
|
||||
@@ -49,23 +60,24 @@ final class WechatRpc
|
||||
Money $money,
|
||||
string $uid
|
||||
): array {
|
||||
$url = config('payment.base_uri') . '/rpc/v1/wechat/qrcode';
|
||||
$data = [
|
||||
'service' => config('payment.sp_id'),
|
||||
'amount' => (int)$money->getAmount(),
|
||||
'fileType' => $type,
|
||||
'uid' => $uid,
|
||||
'goods_detail' => [
|
||||
'goods_name' => $goodsName,
|
||||
],
|
||||
];
|
||||
$response = $this->requestService
|
||||
->setOptions([
|
||||
'headers' => [
|
||||
Header::ACCEPT => $request->getHeader(Header::ACCEPT),
|
||||
],
|
||||
])
|
||||
->requestPost($url, $data);
|
||||
->requestPost(
|
||||
url: '/rpc/v1/wechat/qrcode',
|
||||
data: [
|
||||
'service' => config('payment.sp_id'),
|
||||
'amount' => (int)$money->getAmount(),
|
||||
'fileType' => $type,
|
||||
'uid' => $uid,
|
||||
'goods_detail' => [
|
||||
'goods_name' => $goodsName,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$content = $response->getBody()->getContents();
|
||||
return Json::decode($content);
|
||||
|
||||
28
src/Trait/WebhooksNotificationHandler.php
Normal file
28
src/Trait/WebhooksNotificationHandler.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Webhooks.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/9/22
|
||||
*/
|
||||
|
||||
namespace Singularity\HDK\Pay\Trait;
|
||||
|
||||
use Hyperf\HttpServer\Contract\RequestInterface;
|
||||
use Singularity\HDK\Pay\Resource\Order;
|
||||
|
||||
/**
|
||||
* Singularity\HDK\Pay\Trait\Webhooks@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/9/22
|
||||
*/
|
||||
trait WebhooksNotificationHandler
|
||||
{
|
||||
public function callback(RequestInterface $request): Order
|
||||
{
|
||||
return Order::make($request->post());
|
||||
}
|
||||
}
|
||||
@@ -11,26 +11,25 @@ declare(strict_types=1);
|
||||
*/
|
||||
|
||||
|
||||
use Singularity\HDK\Core\Service\HttpRequestService;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use Singularity\HDK\Pay\Resource\Goods;
|
||||
use Singularity\HDK\Pay\Sdk\GoodsRpc;
|
||||
|
||||
/** @var GoodsRpc $service */
|
||||
$service = \Hyperf\Support\make(
|
||||
GoodsRpc::class,
|
||||
[
|
||||
'requestService' => \Hyperf\Support\make(HttpRequestService::class),
|
||||
'baseUri' => 'http://localhost:9611'
|
||||
]);
|
||||
|
||||
test('根据分类和商品名称获取到对应的 SKU', function () use ($service) {
|
||||
$goods = $service->find(
|
||||
1,
|
||||
[
|
||||
'lattice' => 'TYPE-0',
|
||||
'precision' => 'high',
|
||||
'mode' => 'gradient',
|
||||
],
|
||||
);
|
||||
expect($goods)->toBeInstanceOf(Goods::class);
|
||||
})->only();
|
||||
test(
|
||||
'根据分类和商品名称获取到对应的 SKU',
|
||||
/**
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
function () {
|
||||
$service = new GoodsRpc('http://192.168.2.246:9611');
|
||||
$goods = $service->find(
|
||||
1,
|
||||
[
|
||||
'lattice' => 'TYPE-0',
|
||||
'precision' => 'high',
|
||||
'mode' => 'gradient',
|
||||
],
|
||||
);
|
||||
expect($goods)->toBeInstanceOf(Goods::class);
|
||||
}
|
||||
);
|
||||
|
||||
43
tests/Unit/StripeTest.php
Normal file
43
tests/Unit/StripeTest.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* StripeTest.php@Pay
|
||||
*
|
||||
* @author 李东云 <Dongyun.Li@LuxCreo.Ai>
|
||||
* Powered by PhpStorm
|
||||
* Created on 2023/9/19
|
||||
*/
|
||||
|
||||
/** @var StripeRpc $service */
|
||||
|
||||
use Money\Money;
|
||||
use Singularity\HDK\Core\I18n\Enum\Languages;
|
||||
use Singularity\HDK\Pay\Resource\Order;
|
||||
use Singularity\HDK\Pay\Resource\StripeConfiguration;
|
||||
use Singularity\HDK\Pay\Sdk\StripeRpc;
|
||||
|
||||
test('能够正常创建 Stripe 订单', function () {
|
||||
/** @var StripeRpc $service */
|
||||
$service = \Hyperf\Support\make(StripeRpc::class, ['baseUrl' => 'http://192.168.2.246:9611']);
|
||||
$order = $service->createSession(
|
||||
money: Money::USD(51),
|
||||
uid: uniqid('NAT_'),
|
||||
goodsId: 1,
|
||||
goodsName: 'HDK-Pay Test',
|
||||
goodsDetail: [],
|
||||
locale: Languages::EN,
|
||||
service: 1
|
||||
);
|
||||
expect($order)->toBeInstanceOf(Order::class);
|
||||
});
|
||||
|
||||
test('能够正常获取 Stripe 配置信息', function () {
|
||||
/** @var StripeRpc $service */
|
||||
$service = \Hyperf\Support\make(StripeRpc::class, ['baseUrl' => 'http://192.168.2.246:9611']);
|
||||
$configures = $service->getConfigurations();
|
||||
|
||||
expect($configures)
|
||||
->toBeInstanceOf(StripeConfiguration::class)
|
||||
->toHaveKeys(['id', 'pk'])
|
||||
->and($configures->resolve())->toBeArray();
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
@@ -9,8 +10,28 @@ declare(strict_types=1);
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
use Hyperf\Context\ApplicationContext;
|
||||
use Hyperf\Di\Container;
|
||||
use Hyperf\Di\Definition\DefinitionSource;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
ini_set('display_errors', 'on');
|
||||
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);
|
||||
|
||||
require BASE_PATH . '/vendor/autoload.php';
|
||||
Hyperf\Di\ClassLoader::init();
|
||||
|
||||
$container = new Container(new DefinitionSource([]));
|
||||
if (!$container instanceof ContainerInterface) {
|
||||
throw new RuntimeException('The dependency injection container is invalid.');
|
||||
}
|
||||
$container = ApplicationContext::setContainer($container);
|
||||
Reference in New Issue
Block a user