false, 'message' => __('余额功能未启用', 'aksrt')]; } if ($user_id <= 0) { return ['success' => false, 'message' => __('请先登录', 'aksrt')]; } $balance = \AKSRT\Credits\Balance::balance($user_id); if ($balance < $amount) { return ['success' => false, 'message' => __('余额不足', 'aksrt')]; } $result = \AKSRT\Credits\Balance::deduct( $user_id, $amount, 'order_payment', ['type' => 'order', 'id' => 0, 'order' => $order_number], sprintf(__('订单 %s 支付', 'aksrt'), $order_number) ); if (is_wp_error($result)) { return ['success' => false, 'message' => $result->get_error_message() ?: __('扣款失败', 'aksrt')]; } return [ 'success' => true, 'transaction_id' => 'BAL_' . ($order_number !== '' ? $order_number : (string) time()), 'message' => __('余额支付成功', 'aksrt'), ]; } public function verify_callback(\WP_REST_Request $request): array { // Balance payment is synchronous — no callback needed return ['success' => false, 'message' => __('余额支付无需回调验证', 'aksrt')]; } public function query_status(string $order_number): array { $order_repo = OrderRepository::get_instance(); $order = $order_repo->get($order_number); if (!$order) { return ['success' => false, 'message' => __('订单不存在', 'aksrt')]; } return [ 'success' => true, 'status' => $order['status'], 'transaction_id' => $order['payment_transaction_id'] ?? '', ]; } public function refund(string $order_number, float $amount, string $request_id = ''): array { $order_repo = OrderRepository::get_instance(); $order = $order_repo->get($order_number); if (!$order) { return ['success' => false, 'message' => __('订单不存在', 'aksrt')]; } $user_id = (int) $order['user_id']; $amount = round((float) $amount, 2); if (!class_exists('\AKSRT\Credits\Balance') || !\AKSRT\Credits\Balance::enabled()) { return ['success' => false, 'message' => __('余额功能未启用', 'aksrt')]; } $request_id = sanitize_text_field($request_id); $refund_key = $request_id !== '' ? $request_id : 'order:' . $order_number; $lock_key = 'aksrt_balance_refund_' . hash('sha256', $refund_key); $existing = get_option($lock_key, []); if (is_array($existing) && ($existing['status'] ?? '') === 'succeeded') { return [ 'success' => true, 'refund_id' => 'BAL_REF_' . $order_number, 'message' => __('退款已处理(幂等)', 'aksrt'), ]; } if (is_array($existing) && ($existing['status'] ?? '') === 'pending') { return ['success' => false, 'status' => 'pending', 'message' => __('退款正在处理中,请稍后查询', 'aksrt')]; } $marker = ['status' => 'pending', 'token' => wp_generate_uuid4(), 'created_at' => time()]; if (!add_option($lock_key, $marker, '', false)) { return ['success' => false, 'status' => 'pending', 'message' => __('退款正在处理中,请稍后查询', 'aksrt')]; } try { $result = \AKSRT\Credits\Balance::add( $user_id, $amount, 'order_refund', ['type' => 'order', 'order' => $order_number, 'request_id' => $request_id], sprintf(__('订单 %s 退款', 'aksrt'), $order_number) ); if (is_wp_error($result)) { delete_option($lock_key); return ['success' => false, 'message' => $result->get_error_message() ?: __('退款失败', 'aksrt')]; } update_option($lock_key, [ 'status' => 'succeeded', 'refund_id' => 'BAL_REF_' . $order_number, 'completed_at' => time(), ], false); return ['success' => true, 'refund_id' => 'BAL_REF_' . $order_number, 'message' => __('退款成功', 'aksrt')]; } catch (\Throwable $e) { delete_option($lock_key); return ['success' => false, 'message' => $e->getMessage()]; } } }