积分与余额账务系统硬切重构

This commit is contained in:
kate522 committed 2026-08-24 15:59:11 +08:00
1 parent ca12226b39
commit 5cae5b5c93
159 files changed
+7275 -4718

No files matched your search

+22 -36
View File
@@ -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];
}
}