积分与余额账务系统硬切重构
This commit is contained in:
1 parent
ca12226b39
commit
5cae5b5c93
159 files changed
+7275
-4718
No files matched your search
@@ -95,10 +95,17 @@ class PaymentOrchestrator {
|
||||
}
|
||||
}
|
||||
|
||||
$order['_ledger_paid_note'] = (string) ($opts['paid_note'] ?? __('用户完成支付。', 'aksrt'));
|
||||
$result = $gateway->create_payment($order);
|
||||
if (empty($result['success'])) {
|
||||
$message = (string) ($result['message'] ?? __('支付失败。', 'aksrt'));
|
||||
return self::fail(self::failure_code($method, $message), $message);
|
||||
$code = sanitize_key((string) ($result['code'] ?? ''));
|
||||
$status = (int) ($result['status'] ?? 0);
|
||||
return self::fail(
|
||||
$code !== '' ? $code : self::failure_code($method, $message),
|
||||
$message,
|
||||
$status >= 400 && $status <= 599 ? $status : 400
|
||||
);
|
||||
}
|
||||
|
||||
$payment_url = (string) ($result['payment_url'] ?? '');
|
||||
@@ -116,8 +123,18 @@ class PaymentOrchestrator {
|
||||
];
|
||||
}
|
||||
|
||||
// Synchronous gateway (balance): funds already moved inside create_payment().
|
||||
// Synchronous asset gateways commit the debit and paid transition together.
|
||||
$transaction_id = sanitize_text_field((string) ($result['transaction_id'] ?? ''));
|
||||
if (!empty($result['order_committed'])) {
|
||||
return [
|
||||
'success' => true,
|
||||
'redirect' => false,
|
||||
'transaction_id' => $transaction_id,
|
||||
'ledger_transaction_id' => (int) ($result['ledger_transaction_id'] ?? 0),
|
||||
'replayed' => !empty($result['replayed']),
|
||||
'message' => (string) ($result['message'] ?? __('支付成功。', 'aksrt')),
|
||||
];
|
||||
}
|
||||
$paid = $repo->update_status($order_number, Order::STATUS_PAID, [
|
||||
'payment_method' => $method,
|
||||
'payment_transaction_id' => $transaction_id,
|
||||
@@ -128,13 +145,7 @@ class PaymentOrchestrator {
|
||||
'require_transition' => true,
|
||||
]);
|
||||
if (!$paid) {
|
||||
$rolled_back = self::rollback($gateway, $order_number, (float) ($order['amount'] ?? 0), $method);
|
||||
return self::fail(
|
||||
'aksrt_order_confirm_failed',
|
||||
$rolled_back
|
||||
? __('订单状态已变化,扣款已退回。', 'aksrt')
|
||||
: __('订单状态已变化,扣款补偿失败,请联系管理员处理。', 'aksrt')
|
||||
);
|
||||
return self::fail('aksrt_order_confirm_failed', __('订单状态确认失败。', 'aksrt'));
|
||||
}
|
||||
|
||||
return [
|
||||
@@ -167,31 +178,6 @@ class PaymentOrchestrator {
|
||||
return ['gateway' => $gateway];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compensate a synchronous deduction that could not be committed.
|
||||
*/
|
||||
private static function rollback(GatewayInterface $gateway, string $order_number, float $amount, string $method): bool {
|
||||
if ($amount <= 0) {
|
||||
return true;
|
||||
}
|
||||
$request_id = 'PAY_ROLLBACK_' . substr(hash('sha256', $order_number), 0, 24);
|
||||
try {
|
||||
$compensation = $gateway->refund($order_number, $amount, $request_id);
|
||||
} catch (\Throwable $e) {
|
||||
$compensation = ['success' => false, 'message' => $e->getMessage()];
|
||||
}
|
||||
if (!empty($compensation['success'])) {
|
||||
return true;
|
||||
}
|
||||
error_log(sprintf(
|
||||
'[AKSRT Payment] rollback failed order=%s gateway=%s: %s',
|
||||
$order_number,
|
||||
$method,
|
||||
(string) ($compensation['message'] ?? 'unknown error')
|
||||
));
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function failure_code(string $method, string $message): string {
|
||||
if ($method === 'balance' && (str_contains($message, '余额') || str_contains($message, '不足'))) {
|
||||
return 'aksrt_balance_insufficient';
|
||||
@@ -202,7 +188,7 @@ class PaymentOrchestrator {
|
||||
/**
|
||||
* @return array{success:false,code:string,message:string}
|
||||
*/
|
||||
private static function fail(string $code, string $message): array {
|
||||
return ['success' => false, 'code' => $code, 'message' => $message];
|
||||
private static function fail(string $code, string $message, int $status = 400): array {
|
||||
return ['success' => false, 'code' => $code, 'status' => $status, 'message' => $message];
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user