Files
wordpress-theme-aksrt/src/Admin/PaymentController.php
T
kate522 678143e7b9 feat(payment): 卡密管理改为独立页面并对齐参考主题
- 移除「余额充值」设置中的充值卡(card_pass_*)配置组,PHP schema 与 SPA mirror 双轨同步
- 重写后台卡密管理页:列表过滤/排序/搜索/批量删除/同款分页/点击复制、自动生成与导入、text/xls 导出
- ChargeCard 服务新增 generate_cards/rand_number/rand_password/delete_by_ids/get_export_rows,get_list 支持参考主题排序别名与标识过滤
- 删除无消费方的 /payment/charge-cards REST 路由及 batch_create/disable 死代码,数据层零迁移
2026-09-16 22:05:37 +08:00

114 lines
4.4 KiB
PHP

<?php
/**
* @package AKSRT
*/
namespace AKSRT\Admin;
defined('ABSPATH') || exit;
class PaymentController extends ControllerBase {
private static $instance = null;
public static function get_instance(): self {
if (null === self::$instance) self::$instance = new self();
return self::$instance;
}
public function register_routes(): void {
$this->register_section_routes('payment', 'payment');
register_rest_route(self::API_NAMESPACE, '/payment/withdrawals', [
'methods' => 'GET',
'callback' => [$this, 'get_withdrawals'],
'permission_callback' => [$this, 'check_permission'],
'args' => [
'page' => ['type' => 'integer', 'minimum' => 1, 'default' => 1],
'per_page' => ['type' => 'integer', 'minimum' => 1, 'maximum' => 50, 'default' => 20],
'status' => ['type' => 'string', 'enum' => ['', 'pending', 'processing', 'completed', 'rejected']],
],
]);
// Withdrawal status update
register_rest_route(self::API_NAMESPACE, '/payment/withdrawals/(?P<id>\d+)', [
'methods' => 'POST',
'callback' => [$this, 'update_withdrawal_status'],
'permission_callback' => [$this, 'check_permission'],
'args' => [
'id' => ['type' => 'integer', 'minimum' => 1, 'required' => true],
'status' => ['type' => 'string', 'required' => true, 'enum' => ['processing', 'completed', 'rejected']],
'note' => ['type' => 'string', 'default' => '', 'maxLength' => 1000, 'sanitize_callback' => 'sanitize_textarea_field'],
],
]);
}
public function get_withdrawals(\WP_REST_Request $request): \WP_REST_Response {
if (!class_exists('\AKSRT\Payment\Withdrawal')) {
return $this->success(['data' => ['items' => [], 'total' => 0, 'page' => 1, 'total_pages' => 1, 'stats' => []]]);
}
$status = sanitize_key((string) $request->get_param('status'));
$page = max(1, (int) $request->get_param('page'));
$per_page = max(1, min(50, (int) $request->get_param('per_page'))) ?: 20;
$items = \AKSRT\Payment\Withdrawal::get_instance()->get_all([
'status' => $status,
'limit' => $per_page,
'offset' => ($page - 1) * $per_page,
]);
$total = \AKSRT\Payment\Withdrawal::get_instance()->get_count(['status' => $status]);
$stats = \AKSRT\Payment\Withdrawal::get_instance()->get_stats();
return $this->success([
'data' => [
'items' => $items,
'total' => $total,
'page' => $page,
'total_pages' => max(1, (int) ceil($total / $per_page)),
'stats' => $stats,
],
]);
}
/**
* POST /payment/withdrawals/{id} — 更新提现状态
*/
public function update_withdrawal_status(\WP_REST_Request $request): \WP_REST_Response {
if (!class_exists('\AKSRT\Payment\Withdrawal')) {
return $this->error('提现模块未初始化', 500);
}
$id = (int) $request->get_param('id');
$params = $this->get_json_params($request);
$new_status = sanitize_key((string) ($params['status'] ?? ''));
$note = sanitize_textarea_field((string) ($params['note'] ?? ''));
$valid_statuses = ['processing', 'completed', 'rejected'];
if (!in_array($new_status, $valid_statuses, true)) {
return $this->error('无效的提现状态');
}
if ($id <= 0) {
return $this->error('无效的提现 ID');
}
$operation_key = \AKSRT\Ledger\OperationKey::from_request($request, 'admin-withdraw-transition', get_current_user_id());
if (is_wp_error($operation_key)) {
return $this->error($operation_key->get_error_message(), (int) ($operation_key->get_error_data()['status'] ?? 400));
}
$result = \AKSRT\Payment\Withdrawal::get_instance()->process_status_change($id, $new_status, $note, $operation_key);
if (is_wp_error($result)) {
$data = $result->get_error_data();
return $this->error($result->get_error_message(), is_array($data) ? (int) ($data['status'] ?? 400) : 400);
}
if (is_array($result)) {
return $this->success(array_merge(['message' => __('提现状态已更新', 'aksrt')], $result));
}
return $this->error(__('更新失败', 'aksrt'));
}
}