积分与余额账务系统硬切重构
This commit is contained in:
1 parent
ca12226b39
commit
5cae5b5c93
159 files changed
+7275
-4718
No files matched your search
@@ -42,13 +42,17 @@ class StripeGateway implements \AKSRT\Payment\GatewayInterface {
|
||||
? \AKSRT\Payment\OrderRepository::provider_out_trade_no($order)
|
||||
: $order_number;
|
||||
}
|
||||
$amount = (float) ($order['amount'] ?? 0);
|
||||
$amount = is_string($order['amount'] ?? null) ? trim($order['amount']) : '';
|
||||
$subject = $order['subject'] ?? __('订单支付', 'aksrt');
|
||||
$order_currency = strtoupper((string) ($order['currency'] ?? ''));
|
||||
$currency = strtolower($config['currency'] ?? 'usd');
|
||||
if ($order_currency === '' || !hash_equals($order_currency, strtoupper($currency))) {
|
||||
return ['success' => false, 'message' => __('Stripe 币种与订单币种不一致', 'aksrt')];
|
||||
}
|
||||
$smallest_amount = $this->to_smallest_unit($amount, $currency);
|
||||
if ($order_number === '' || $out_trade_no === '' || $smallest_amount === null || $smallest_amount <= 0) {
|
||||
return ['success' => false, 'message' => __('订单金额无效', 'aksrt')];
|
||||
}
|
||||
|
||||
try {
|
||||
$stripe = $this->create_client($config);
|
||||
@@ -62,7 +66,7 @@ class StripeGateway implements \AKSRT\Payment\GatewayInterface {
|
||||
'product_data' => [
|
||||
'name' => $subject,
|
||||
],
|
||||
'unit_amount' => $this->to_smallest_unit($amount, $currency),
|
||||
'unit_amount' => $smallest_amount,
|
||||
],
|
||||
'quantity' => 1,
|
||||
]],
|
||||
@@ -204,7 +208,15 @@ class StripeGateway implements \AKSRT\Payment\GatewayInterface {
|
||||
}
|
||||
}
|
||||
|
||||
public function refund(string $order_number, float $amount, string $request_id = ''): array {
|
||||
public function refund(string $order_number, string $amount, string $request_id = ''): array {
|
||||
try {
|
||||
$refund_amount = \AKSRT\Ledger\AssetAmount::balance($amount);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return ['success' => false, 'message' => __('退款金额无效', 'aksrt')];
|
||||
}
|
||||
if ($refund_amount->minor() <= 0) {
|
||||
return ['success' => false, 'message' => __('退款金额无效', 'aksrt')];
|
||||
}
|
||||
if (!$this->is_configured()) {
|
||||
return ['success' => false, 'message' => __('Stripe 未配置', 'aksrt')];
|
||||
}
|
||||
@@ -228,6 +240,10 @@ class StripeGateway implements \AKSRT\Payment\GatewayInterface {
|
||||
}
|
||||
|
||||
$currency = strtolower((string) ($found->currency ?? $config['currency'] ?? 'usd'));
|
||||
$refund_smallest = $this->to_smallest_unit($refund_amount->decimal(), $currency);
|
||||
if ($refund_smallest === null || $refund_smallest <= 0) {
|
||||
return ['success' => false, 'message' => __('退款金额与币种精度不匹配', 'aksrt')];
|
||||
}
|
||||
|
||||
$options = ['api_key' => $config['secret_key']];
|
||||
if ($request_id !== '') {
|
||||
@@ -235,7 +251,7 @@ class StripeGateway implements \AKSRT\Payment\GatewayInterface {
|
||||
}
|
||||
$refund = \Stripe\Refund::create([
|
||||
'payment_intent' => $paymentIntentId,
|
||||
'amount' => $this->to_smallest_unit($amount, $currency),
|
||||
'amount' => $refund_smallest,
|
||||
'reason' => 'requested_by_customer',
|
||||
'metadata' => [
|
||||
'aksrt_request_id' => $request_id,
|
||||
@@ -390,26 +406,37 @@ class StripeGateway implements \AKSRT\Payment\GatewayInterface {
|
||||
return array_values(array_intersect($methods, $valid)) ?: ['card'];
|
||||
}
|
||||
|
||||
private function from_smallest_unit(int $amount, string $currency): float {
|
||||
private function from_smallest_unit(int $amount, string $currency): string {
|
||||
if ($amount < 0) {
|
||||
return '0.00';
|
||||
}
|
||||
$zero_decimal = ['bif', 'clp', 'djf', 'gnf', 'jpy', 'kmf', 'krw', 'mga', 'pyg', 'rwf', 'ugx', 'vnd', 'vuv', 'xaf', 'xof', 'xpf'];
|
||||
if (in_array(strtolower($currency), $zero_decimal, true)) {
|
||||
return (float) $amount;
|
||||
if ($amount > intdiv(PHP_INT_MAX, 100)) {
|
||||
return '0.00';
|
||||
}
|
||||
return \AKSRT\Ledger\AssetAmount::from_minor(\AKSRT\Ledger\AssetType::BALANCE, $amount * 100)->decimal();
|
||||
}
|
||||
|
||||
return $amount / 100;
|
||||
return \AKSRT\Ledger\AssetAmount::from_minor(\AKSRT\Ledger\AssetType::BALANCE, $amount)->decimal();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将金额转换为最小单位(分/cent)。
|
||||
*/
|
||||
private function to_smallest_unit(float $amount, string $currency): int {
|
||||
private function to_smallest_unit(string $amount, string $currency): ?int {
|
||||
try {
|
||||
$parsed = \AKSRT\Ledger\AssetAmount::balance($amount);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return null;
|
||||
}
|
||||
// 零小数货币(日元、韩元等)
|
||||
$zeroDecimal = ['bif', 'clp', 'djf', 'gnf', 'jpy', 'kmf', 'krw', 'mga', 'pyg', 'rwf', 'ugx', 'vnd', 'vuv', 'xaf', 'xof', 'xpf'];
|
||||
|
||||
if (in_array(strtolower($currency), $zeroDecimal, true)) {
|
||||
return (int) $amount;
|
||||
return $parsed->minor() % 100 === 0 ? intdiv($parsed->minor(), 100) : null;
|
||||
}
|
||||
|
||||
return (int) round($amount * 100);
|
||||
return $parsed->minor();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user