- 移除「余额充值」设置中的充值卡(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 死代码,数据层零迁移
114 lines
4.4 KiB
PHP
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'));
|
|
}
|
|
|
|
}
|