Merge pull request 'fix(payment): wire balance wallet end-to-end when pay_balance_s is on' (#287) from worktree-fix-balance-chain into main
Reviewed-on: CYL/wordpress-theme-aksrt#287
This commit is contained in:
@@ -12,7 +12,7 @@ export const gatewaySchema = {
|
||||
payment_wechat_enabled: false,
|
||||
payment_alipay_enabled: false,
|
||||
payment_paypal_enabled: false,
|
||||
payment_balance_enabled: false,
|
||||
payment_balance_enabled: true,
|
||||
payment_card_pass_enabled: false,
|
||||
payment_xunhupay_enabled: false,
|
||||
payment_xhpay_enabled: false,
|
||||
@@ -73,7 +73,7 @@ export const gatewaySchema = {
|
||||
{ key: 'payment_alipay_enabled', label: '支付宝', type: 'switch', default: false },
|
||||
{ key: 'payment_paypal_enabled', label: 'PayPal', type: 'switch', default: false },
|
||||
{ key: 'payment_stripe_enabled', label: 'Stripe', type: 'switch', default: false },
|
||||
{ key: 'payment_balance_enabled', label: '余额支付', type: 'switch', default: false },
|
||||
{ key: 'payment_balance_enabled', label: '余额支付', type: 'switch', default: true, help: '需同时在「余额充值」启用余额功能。关闭后用户中心仍可有钱包,但结账不可用余额支付。' },
|
||||
{ key: 'payment_card_pass_enabled', label: '卡密充值', type: 'switch', default: false },
|
||||
{ key: 'payment_xunhupay_enabled', label: '虎皮椒', type: 'switch', default: false },
|
||||
{ key: 'payment_xhpay_enabled', label: '小火付', type: 'switch', default: false },
|
||||
|
||||
@@ -32,9 +32,9 @@ export const rechargeSchema = {
|
||||
title: '充值开关',
|
||||
icon: 'fas fa-wallet',
|
||||
fields: [
|
||||
{ key: 'pay_balance_s', label: '启用余额功能', type: 'switch', default: true },
|
||||
{ key: 'pay_balance_s', label: '启用余额功能', type: 'switch', default: true, help: '开启后用户中心显示现金钱包,并默认允许余额支付(可在收款接口单独关闭)。充值需另配支付宝/微信等外部网关。' },
|
||||
{ key: 'pay_balance_desc', label: '充值说明', type: 'textarea', default: '', dependsOn: { key: 'pay_balance_s', value: true } },
|
||||
{ key: 'pay_auto_to_balance', label: '自动到账到余额', type: 'switch', default: true, dependsOn: { key: 'pay_balance_s', value: true } },
|
||||
{ key: 'pay_auto_to_balance', label: '自动到账到余额', type: 'switch', default: true, dependsOn: { key: 'pay_balance_s', value: true }, help: '充值订单支付成功后自动入账钱包(卡密/管理员调整不受此开关限制)。' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
+29
-12
@@ -548,18 +548,35 @@
|
||||
}
|
||||
body += '</div>';
|
||||
}
|
||||
let methodHtml = '';
|
||||
methods.forEach(function (m, idx) {
|
||||
const id = escapeAttr(m.id || '');
|
||||
const name = escapeHtml(m.name || id);
|
||||
methodHtml += '<label class="aksrt-cashier__method"><input type="radio" name="aksrt_pay_method" value="' + id + '"' + (idx === 0 ? ' checked' : '') + '> <span>' + name + '</span></label>';
|
||||
});
|
||||
if (methodHtml) {
|
||||
body += '<div class="aksrt-cashier__methods"><div class="aksrt-cashier__methods-title">' + tt('pay_method', '支付方式') + '</div>' + methodHtml + '</div>';
|
||||
}
|
||||
body += '<div class="aksrt-dl-modal__actions">';
|
||||
body += '<button type="button" class="btn-primary aksrt-dl-modal__download" data-aksrt-pay-submit data-mode="cash" data-price-type="' + escapeAttr(priceType) + '">' + tt('pay_now', '立即支付') + ' ' + amountLabel + '</button>';
|
||||
body += '</div>';
|
||||
const walletBal = typeof preview.wallet_balance === 'number'
|
||||
? preview.wallet_balance
|
||||
: (typeof preview.balance === 'number' ? preview.balance : 0);
|
||||
const hasBalanceMethod = methods.some(function (m) { return (m && m.id) === 'balance'; });
|
||||
if (hasBalanceMethod) {
|
||||
body += '<div class="aksrt-cashier__box"><div class="aksrt-cashier__row"><span>' + tt('my_wallet', '我的余额') + '</span><b class="is-ok">¥' + Number(walletBal).toFixed(2) + '</b></div></div>';
|
||||
if (preview.balance_enough === false) {
|
||||
body += '<div class="aksrt-cashier__warn">' + tt('wallet_short', '余额不足,请先充值或选择其他支付方式') + '</div>';
|
||||
if (preview.credits_url) {
|
||||
body += '<div class="aksrt-dl-modal__actions"><a class="btn-sm" href="' + escapeAttr(preview.credits_url) + '">' + tt('go_recharge', '去充值') + '</a></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
let methodHtml = '';
|
||||
methods.forEach(function (m, idx) {
|
||||
const id = escapeAttr(m.id || '');
|
||||
const name = escapeHtml(m.name || id);
|
||||
methodHtml += '<label class="aksrt-cashier__method"><input type="radio" name="aksrt_pay_method" value="' + id + '"' + (idx === 0 ? ' checked' : '') + '> <span>' + name + '</span></label>';
|
||||
});
|
||||
if (methodHtml) {
|
||||
body += '<div class="aksrt-cashier__methods"><div class="aksrt-cashier__methods-title">' + tt('pay_method', '支付方式') + '</div>' + methodHtml + '</div>';
|
||||
} else {
|
||||
body += '<div class="aksrt-cashier__warn">' + tt('no_pay_method', '暂无可用支付方式,请联系站长配置收款接口') + '</div>';
|
||||
}
|
||||
body += '<div class="aksrt-dl-modal__actions">';
|
||||
if (methodHtml) {
|
||||
body += '<button type="button" class="btn-primary aksrt-dl-modal__download" data-aksrt-pay-submit data-mode="cash" data-price-type="' + escapeAttr(priceType) + '">' + tt('pay_now', '立即支付') + ' ' + amountLabel + '</button>';
|
||||
}
|
||||
body += '</div>';
|
||||
}
|
||||
|
||||
open('<h3 class="aksrt-dl-modal__title">' + tt('confirm_buy', '确认购买') + '</h3>' + body, returnFocusEl);
|
||||
|
||||
@@ -107,12 +107,8 @@ if (!function_exists('aksrt_list_cash_payment_methods')) {
|
||||
];
|
||||
}
|
||||
|
||||
if ($methods === []) {
|
||||
$methods[] = $logged_in
|
||||
? ['id' => 'balance', 'name' => __('站内余额', 'aksrt')]
|
||||
: ['id' => 'alipay', 'name' => __('支付宝', 'aksrt')];
|
||||
}
|
||||
|
||||
// Do not inject a fake balance/alipay option when nothing is configured —
|
||||
// callers should surface “暂无可用支付方式” instead of a dead method.
|
||||
return $methods;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,10 @@ class SchemaPayment {
|
||||
['key' => 'pay_balance_exchange_rate', 'label' => '兑换比例', 'type' => 'number', 'default' => 100, 'min' => 1, 'max' => 10000, 'dependsOn' => ['key' => 'pay_balance_exchange_s', 'value' => true]],
|
||||
['key' => 'pay_balance_exchange_desc', 'label' => '兑换说明', 'type' => 'textarea', 'default' => '', 'dependsOn' => ['key' => 'pay_balance_exchange_s', 'value' => true]],
|
||||
]],
|
||||
['key' => 'withdraw', 'title' => '余额提现', 'fields' => [
|
||||
['key' => 'pay_balance_withdraw_s', 'label' => '启用余额提现', 'type' => 'switch', 'default' => false, 'dependsOn' => ['key' => 'pay_balance_s', 'value' => true]],
|
||||
['key' => 'pay_balance_withdraw_lowest_money', 'label' => '最低提现金额', 'type' => 'number', 'default' => 50, 'min' => 1, 'max' => 99999, 'dependsOn' => ['key' => 'pay_balance_withdraw_s', 'value' => true]],
|
||||
]],
|
||||
],
|
||||
],
|
||||
'vip' => [
|
||||
@@ -229,7 +233,7 @@ class SchemaPayment {
|
||||
['key' => 'payment_wechat_enabled', 'label' => '微信支付', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'payment_alipay_enabled', 'label' => '支付宝', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'payment_paypal_enabled', 'label' => 'PayPal', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'payment_balance_enabled', 'label' => '余额支付', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'payment_balance_enabled', 'label' => '余额支付', 'type' => 'switch', 'default' => true],
|
||||
['key' => 'payment_card_pass_enabled', 'label' => '卡密充值', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'payment_xunhupay_enabled', 'label' => '虎皮椒', 'type' => 'switch', 'default' => false],
|
||||
['key' => 'payment_xhpay_enabled', 'label' => '小火付', 'type' => 'switch', 'default' => false],
|
||||
|
||||
@@ -120,7 +120,14 @@ trait PayHelpers {
|
||||
? (class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_currency_name() : __('积分', 'aksrt'))
|
||||
: '¥'));
|
||||
|
||||
$balance = ($uid > 0 && class_exists('\AKSRT\Credits\Credits')) ? \AKSRT\Credits\Credits::balance($uid) : 0;
|
||||
// Points cashier uses Credits; cash cashier uses wallet (元). Keep both for UI.
|
||||
$points_balance = ($uid > 0 && class_exists('\AKSRT\Credits\Credits'))
|
||||
? (int) \AKSRT\Credits\Credits::balance($uid)
|
||||
: 0;
|
||||
$wallet_balance = ($uid > 0 && class_exists('\AKSRT\Credits\Balance') && \AKSRT\Credits\Balance::enabled())
|
||||
? (float) \AKSRT\Credits\Balance::balance($uid)
|
||||
: 0.0;
|
||||
$balance = $pay_modo === 'points' ? $points_balance : $wallet_balance;
|
||||
$methods = $this->available_payment_methods($pay_modo, $uid > 0);
|
||||
|
||||
$amount_label = $this->format_amount_label($amount, $pay_modo, $currency);
|
||||
@@ -140,6 +147,11 @@ trait PayHelpers {
|
||||
? aksrt_get_user_free_downloaded_number($uid) : 0;
|
||||
$quota_over = $free_limit > 0 && $free_used >= $free_limit;
|
||||
|
||||
$payable_amount = $pay_modo === 'points' ? (int) ceil($payable) : round($payable, 2);
|
||||
$balance_enough = $pay_modo === 'points'
|
||||
? ($points_balance >= (int) ceil($amount))
|
||||
: ($wallet_balance + 0.0001 >= (float) $payable_amount);
|
||||
|
||||
return [
|
||||
'post_id' => $post_id,
|
||||
'title' => get_the_title($post),
|
||||
@@ -153,7 +165,7 @@ trait PayHelpers {
|
||||
'base' => $pay_modo === 'points' ? (int) ceil($base) : round($base, 2),
|
||||
'list_amount' => $pay_modo === 'points' ? (int) ceil($list_amount) : round($list_amount, 2),
|
||||
'list_amount_label' => $list_label,
|
||||
'payable' => $pay_modo === 'points' ? (int) ceil($payable) : round($payable, 2),
|
||||
'payable' => $payable_amount,
|
||||
'original' => (float) ($priced['original'] ?? 0),
|
||||
'vip1' => (float) ($priced['vip1'] ?? 0),
|
||||
'vip2' => (float) ($priced['vip2'] ?? 0),
|
||||
@@ -181,7 +193,9 @@ trait PayHelpers {
|
||||
'need_purchase' => !$has_paid && !$need_vip && $amount > 0,
|
||||
'logged_in' => $uid > 0,
|
||||
'balance' => $balance,
|
||||
'balance_enough' => $pay_modo !== 'points' || $balance >= (int) ceil($amount),
|
||||
'wallet_balance' => $wallet_balance,
|
||||
'points_balance' => $points_balance,
|
||||
'balance_enough' => $balance_enough,
|
||||
'payment_methods' => $methods,
|
||||
'login_url' => wp_login_url(get_permalink($post)),
|
||||
'vip_url' => $vip_page,
|
||||
|
||||
@@ -506,9 +506,12 @@ trait VipServicePackages {
|
||||
* @return array<int, array{id:string,name:string}>
|
||||
*/
|
||||
private function available_payment_methods(): array {
|
||||
if (function_exists('aksrt_list_cash_payment_methods')) {
|
||||
return aksrt_list_cash_payment_methods(true);
|
||||
}
|
||||
$methods = [];
|
||||
if (!class_exists('\AKSRT\Payment\Gateway')) {
|
||||
return [['id' => 'balance', 'name' => __('站内余额', 'aksrt')]];
|
||||
return $methods;
|
||||
}
|
||||
$gw = \AKSRT\Payment\Gateway::get_instance();
|
||||
foreach (['balance', 'alipay', 'wechatpay', 'paypal', 'stripe'] as $id) {
|
||||
@@ -524,9 +527,6 @@ trait VipServicePackages {
|
||||
'name' => method_exists($g, 'get_name') ? (string) $g->get_name() : $id,
|
||||
];
|
||||
}
|
||||
if ($methods === []) {
|
||||
$methods[] = ['id' => 'balance', 'name' => __('站内余额', 'aksrt')];
|
||||
}
|
||||
return $methods;
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,12 @@ trait VipServicePurchase {
|
||||
$points_packages = $this->get_points_exchange_packages($vip, $levels);
|
||||
}
|
||||
|
||||
$balance = ($user_id > 0 && class_exists('\AKSRT\Credits\Credits')) ? \AKSRT\Credits\Credits::balance($user_id) : 0;
|
||||
$points_balance = ($user_id > 0 && class_exists('\AKSRT\Credits\Credits'))
|
||||
? (int) \AKSRT\Credits\Credits::balance($user_id)
|
||||
: 0;
|
||||
$wallet_balance = ($user_id > 0 && class_exists('\AKSRT\Credits\Balance') && \AKSRT\Credits\Balance::enabled())
|
||||
? (float) \AKSRT\Credits\Balance::balance($user_id)
|
||||
: 0.0;
|
||||
$methods = $this->available_payment_methods();
|
||||
$currency_name = class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::get_currency_name() : __('积分', 'aksrt');
|
||||
|
||||
@@ -144,7 +149,8 @@ trait VipServicePurchase {
|
||||
'user_expires' => $expires,
|
||||
'user_is_permanent' => $is_permanent,
|
||||
'user_expires_label' => $this->format_expires_label($expires, $level),
|
||||
'user_points' => $balance,
|
||||
'user_points' => $points_balance,
|
||||
'wallet_balance' => $wallet_balance,
|
||||
'currency_name' => $currency_name,
|
||||
'renew_enabled' => $renew_enabled,
|
||||
'upgrade_enabled' => $upgrade_enabled,
|
||||
|
||||
@@ -81,6 +81,13 @@ trait BalanceServiceCharge {
|
||||
if (!class_exists('AKSRT\\Credits\\Balance')) {
|
||||
return;
|
||||
}
|
||||
// Honor pay_auto_to_balance (default on). When off, leave order paid without wallet credit.
|
||||
if (class_exists('\AKSRT\Settings\Settings') && method_exists('\AKSRT\Settings\Settings', 'get_payment_recharge_settings')) {
|
||||
$recharge_cfg = \AKSRT\Settings\Settings::get_payment_recharge_settings();
|
||||
if (isset($recharge_cfg['auto_to_balance']) && empty($recharge_cfg['auto_to_balance'])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$note = json_decode((string) ($order['note'] ?? ''), true);
|
||||
if (!is_array($note)) {
|
||||
$note = [];
|
||||
|
||||
@@ -189,16 +189,14 @@ class TopicPay {
|
||||
}
|
||||
$has_paid = $this->user_has_paid($uid, $topic_id);
|
||||
|
||||
$balance = 0;
|
||||
if ($uid > 0 && class_exists('\AKSRT\Credits\Credits')) {
|
||||
$balance = (int) \AKSRT\Credits\Credits::balance($uid);
|
||||
$wallet_balance = 0.0;
|
||||
if ($uid > 0 && class_exists('\AKSRT\Credits\Balance') && \AKSRT\Credits\Balance::enabled()) {
|
||||
$wallet_balance = (float) \AKSRT\Credits\Balance::balance($uid);
|
||||
}
|
||||
|
||||
$methods = function_exists('aksrt_list_cash_payment_methods')
|
||||
? aksrt_list_cash_payment_methods($uid > 0)
|
||||
: ($uid > 0
|
||||
? [['id' => 'balance', 'name' => __('站内余额', 'aksrt')]]
|
||||
: [['id' => 'alipay', 'name' => __('支付宝', 'aksrt')]]);
|
||||
: [];
|
||||
|
||||
$coupon_allowed = $this->is_coupon_allowed($topic_id);
|
||||
$coupon_error = '';
|
||||
@@ -259,8 +257,9 @@ class TopicPay {
|
||||
'need_vip' => false,
|
||||
'need_purchase' => !$has_paid && !$is_free,
|
||||
'logged_in' => $uid > 0,
|
||||
'balance' => $balance,
|
||||
'balance_enough' => true,
|
||||
'balance' => $wallet_balance,
|
||||
'wallet_balance' => $wallet_balance,
|
||||
'balance_enough' => $is_free || ($wallet_balance + 0.0001 >= (float) $payable),
|
||||
'payment_methods' => $methods,
|
||||
'login_url' => wp_login_url(get_permalink($post)),
|
||||
'vip_url' => home_url('/'),
|
||||
|
||||
@@ -10,7 +10,7 @@ defined('ABSPATH') || exit;
|
||||
/**
|
||||
* 站内余额支付网关(内置实现)。
|
||||
*
|
||||
* 优先扣现金钱包(\AKSRT\Credits\Balance / pay_balance);未启用时回退到积分。
|
||||
* 仅扣现金钱包(\AKSRT\Credits\Balance / pay_balance_s),不再回退到积分。
|
||||
*/
|
||||
|
||||
class BalanceGateway implements GatewayInterface {
|
||||
@@ -24,9 +24,8 @@ class BalanceGateway implements GatewayInterface {
|
||||
}
|
||||
|
||||
public function is_configured(): bool {
|
||||
$wallet_on = class_exists('\AKSRT\Credits\Balance') && \AKSRT\Credits\Balance::enabled();
|
||||
$credits_on = class_exists('\AKSRT\Credits\Credits');
|
||||
if (!$wallet_on && !$credits_on) {
|
||||
// Cash wallet only — do not treat points as 余额.
|
||||
if (!class_exists('\AKSRT\Credits\Balance') || !\AKSRT\Credits\Balance::enabled()) {
|
||||
return false;
|
||||
}
|
||||
if (class_exists('\AKSRT\Settings\PaymentRuntime')) {
|
||||
@@ -40,55 +39,26 @@ class BalanceGateway implements GatewayInterface {
|
||||
$amount = round((float) ($order['amount'] ?? 0), 2);
|
||||
$order_number = (string) ($order['order_number'] ?? '');
|
||||
|
||||
// Prefer cash wallet when pay_balance_s is on.
|
||||
if (class_exists('\AKSRT\Credits\Balance') && \AKSRT\Credits\Balance::enabled()) {
|
||||
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'),
|
||||
];
|
||||
if (!class_exists('\AKSRT\Credits\Balance') || !\AKSRT\Credits\Balance::enabled()) {
|
||||
return ['success' => false, 'message' => __('余额功能未启用', 'aksrt')];
|
||||
}
|
||||
|
||||
// Fallback: legacy points-as-balance (1 元 = 100 积分).
|
||||
if (!class_exists('\AKSRT\Credits\Credits')) {
|
||||
return ['success' => false, 'message' => __('积分系统未启用', 'aksrt')];
|
||||
if ($user_id <= 0) {
|
||||
return ['success' => false, 'message' => __('请先登录', 'aksrt')];
|
||||
}
|
||||
|
||||
$credits_cost = (int) ceil($amount * 100);
|
||||
$balance = \AKSRT\Credits\Credits::balance($user_id);
|
||||
if ($balance < $credits_cost) {
|
||||
$balance = \AKSRT\Credits\Balance::balance($user_id);
|
||||
if ($balance < $amount) {
|
||||
return ['success' => false, 'message' => __('余额不足', 'aksrt')];
|
||||
}
|
||||
|
||||
$result = \AKSRT\Credits\Credits::deduct(
|
||||
$result = \AKSRT\Credits\Balance::deduct(
|
||||
$user_id,
|
||||
$credits_cost,
|
||||
$amount,
|
||||
'order_payment',
|
||||
['order' => $order_number],
|
||||
['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()),
|
||||
@@ -127,37 +97,20 @@ class BalanceGateway implements GatewayInterface {
|
||||
$user_id = (int) $order['user_id'];
|
||||
$amount = round((float) $amount, 2);
|
||||
|
||||
if (class_exists('\AKSRT\Credits\Balance') && \AKSRT\Credits\Balance::enabled()) {
|
||||
$result = \AKSRT\Credits\Balance::add(
|
||||
$user_id,
|
||||
$amount,
|
||||
'order_refund',
|
||||
['type' => 'order', '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, 'refund_id' => 'BAL_REF_' . $order_number, 'message' => __('退款成功', 'aksrt')];
|
||||
if (!class_exists('\AKSRT\Credits\Balance') || !\AKSRT\Credits\Balance::enabled()) {
|
||||
return ['success' => false, 'message' => __('余额功能未启用', 'aksrt')];
|
||||
}
|
||||
|
||||
if (!class_exists('\AKSRT\Credits\Credits')) {
|
||||
return ['success' => false, 'message' => __('积分系统未启用', 'aksrt')];
|
||||
}
|
||||
|
||||
$credits_refund = (int) ceil($amount * 100);
|
||||
$result = \AKSRT\Credits\Credits::add(
|
||||
$result = \AKSRT\Credits\Balance::add(
|
||||
$user_id,
|
||||
$credits_refund,
|
||||
$amount,
|
||||
'order_refund',
|
||||
['order' => $order_number],
|
||||
['type' => 'order', '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, 'refund_id' => 'BAL_REF_' . $order_number, 'message' => __('退款成功', 'aksrt')];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +467,15 @@ class PaymentRuntime {
|
||||
return false;
|
||||
}
|
||||
if ($gateway_id === 'balance') {
|
||||
return !empty($settings['payment_balance_enabled']) && !empty($settings['pay_balance_s']);
|
||||
// Master: 余额充值 → 启用余额功能. Optional kill-switch: payment_balance_enabled=false.
|
||||
// Missing key (legacy sites) follows pay_balance_s so "open wallet" alone enables pay.
|
||||
if (empty($settings['pay_balance_s'])) {
|
||||
return false;
|
||||
}
|
||||
if (array_key_exists('payment_balance_enabled', $settings) && empty($settings['payment_balance_enabled'])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return !empty($settings[$key]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user