feat(users): normalize center routes and withdrawal limits

This commit is contained in:
2026-08-12 19:44:47 +08:00
parent 9004f7093f
commit dacd0095bf
24 changed files with 326 additions and 174 deletions
+18 -31
View File
@@ -398,50 +398,37 @@ trait BalanceServiceRest {
if (class_exists('\AKSRT\Settings\Capabilities') && !\AKSRT\Settings\Capabilities::user_can('balance_withdraw', $user_id)) {
return new \WP_Error('aksrt_withdraw_forbidden', __('当前账号无权提现', 'aksrt'), ['status' => 403]);
}
$amount = round((float) ($params['amount'] ?? 0), 2);
$raw_amount = $params['amount'] ?? 0;
if (filter_var($raw_amount, FILTER_VALIDATE_INT) === false || (int) $raw_amount <= 0) {
return new \WP_Error('aksrt_withdraw_amount', __('提现金额必须为正整数', 'aksrt'), ['status' => 400]);
}
$amount = (int) $raw_amount;
$method = sanitize_key((string) ($params['method'] ?? 'alipay'));
$account = sanitize_textarea_field((string) ($params['account_info'] ?? $params['account'] ?? ''));
$lowest = max(1, (float) ($settings['pay_balance_withdraw_lowest_money'] ?? $settings['pay_rebate_withdraw_lowest_money'] ?? 50));
$withdraw_settings = class_exists('\\AKSRT\\Settings\\Settings')
? \AKSRT\Settings\Settings::get_withdrawal_settings()
: ['min_amount' => 50, 'service_charge_rate' => 5, 'daily_count' => 3, 'daily_limit' => 50, 'reset_time' => '00:00'];
$lowest = (float) $withdraw_settings['min_amount'];
if ($amount < $lowest) {
return new \WP_Error('aksrt_withdraw_min', sprintf(__('最低提现 %s 元', 'aksrt'), (string) $lowest), ['status' => 400]);
return new \WP_Error('withdraw_min_amount', sprintf(__('提现金额低于最低提现门槛(%s 元)', 'aksrt'), (string) $lowest), ['status' => 400]);
}
if ($account === '') {
return new \WP_Error('aksrt_withdraw_account', __('请填写收款账号信息', 'aksrt'), ['status' => 400]);
}
// One open balance withdrawal at a time (Zibll parity).
if (\AKSRT\Payment\Withdrawal::get_instance()->has_open_withdrawal($user_id)) {
return new \WP_Error('aksrt_withdraw_pending', __('您有处理中的提现申请,请等待完成后再申请', 'aksrt'), ['status' => 409]);
}
$wallet = Balance::balance($user_id);
if ($wallet < $amount) {
return new \WP_Error('aksrt_balance_insufficient', __('余额不足', 'aksrt'), ['status' => 402]);
}
$deduct = Balance::deduct($user_id, $amount, 'withdraw_hold', ['type' => 'withdraw'], __('余额提现申请冻结', 'aksrt'));
if (is_wp_error($deduct)) {
return $deduct;
}
$fee_rate = max(0, min(50, (int) ($settings['withdraw_service_charge'] ?? 0)));
$net = $fee_rate > 0 ? round($amount * (100 - $fee_rate) / 100, 2) : $amount;
$account_payload = wp_json_encode([
'account' => $account,
'gross_amount' => $amount,
'fee_rate' => $fee_rate,
'source' => 'balance',
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?: $account;
$wid = \AKSRT\Payment\Withdrawal::get_instance()->create($user_id, $net, $method !== '' ? $method : 'alipay', $account_payload);
if ($wid <= 0) {
Balance::add($user_id, $amount, 'withdraw_refund', [], __('提现申请失败退回', 'aksrt'));
return new \WP_Error('aksrt_withdraw_failed', __('提现申请失败', 'aksrt'), ['status' => 500]);
$result = \AKSRT\Payment\Withdrawal::get_instance()->create_balance_request($user_id, $amount, $method !== '' ? $method : 'alipay', $account, $withdraw_settings);
if (is_wp_error($result)) {
return $result;
}
return rest_ensure_response([
'success' => true,
'data' => [
'message' => __('提现申请已提交,请等待处理', 'aksrt'),
'withdrawal_id' => $wid,
'withdrawal_id' => $result['withdrawal_id'],
'amount' => $amount,
'net_amount' => $net,
'wallet_balance' => Balance::balance($user_id),
'reload' => true,
'net_amount' => $result['net_amount'],
'wallet_balance' => $result['wallet_balance'],
'remaining_count' => $result['usage']['remaining_count'],
'remaining_amount' => $result['usage']['remaining_amount'],
],
]);
}