feat(pay): 卡密兑换入口收敛到三个购买弹窗并对齐参考主题
- 移除余额卡片独立「卡密兑换」通用弹窗,兑换入口分布到充值/积分/会员三个弹窗的支付方式中 - 充值弹窗补齐卡密 logo 与仅卡密时的金额选择隐藏逻辑 - 积分购买弹窗 1:1 复刻参考主题 points-pay modal(商品档位/自定义/支付方式/立即支付),REST 改为 product+custom 契约 - 会员弹窗注入卡密渠道:视图模型透传 card_pass,前端渲染卡密盒并直兑 /pay/card-pass/redeem type=vip - 后台卡密兑换拆分为余额/积分/会员三个独立开关,VIP 段旧会员卡密组清理 - REST type 改为必填(balance/vip/credits),三类型独立闸门 - 测试重写为 card-pass-modal-redeem 契约,321 项全部通过
This commit is contained in:
@@ -110,9 +110,22 @@ class PaymentRuntime {
|
||||
'desc' => sanitize_textarea_field((string) ($settings['pay_balance_transfer_desc'] ?? '')),
|
||||
],
|
||||
'pass_charge' => [
|
||||
'enabled' => !empty($settings['pay_balance_pass_charge_s']),
|
||||
'desc' => sanitize_textarea_field((string) ($settings['pay_balance_pass_charge_desc'] ?? '')),
|
||||
'only_password' => !empty($settings['pay_balance_pass_charge_only_password']),
|
||||
// 三个独立开关:各类型卡密只进入各自的购买弹窗(收款接口同款拆分)。
|
||||
'balance' => [
|
||||
'enabled' => !empty($settings['pay_balance_pass_charge_s']),
|
||||
'desc' => sanitize_textarea_field((string) ($settings['pay_balance_pass_charge_desc'] ?? '')),
|
||||
'only_password' => !empty($settings['pay_balance_pass_charge_only_password']),
|
||||
],
|
||||
'credits' => [
|
||||
'enabled' => !empty($settings['points_pass_exchange_s']),
|
||||
'desc' => sanitize_textarea_field((string) ($settings['points_pass_exchange_desc'] ?? '')),
|
||||
'only_password' => !empty($settings['points_pass_exchange_only_password']),
|
||||
],
|
||||
'vip' => [
|
||||
'enabled' => !empty($settings['pay_vip_pass_charge_s']),
|
||||
'desc' => sanitize_textarea_field((string) ($settings['pay_vip_pass_charge_desc'] ?? '')),
|
||||
'only_password' => !isset($settings['pay_vip_pass_charge_only_password']) || !empty($settings['pay_vip_pass_charge_only_password']),
|
||||
],
|
||||
],
|
||||
'points_exchange' => [
|
||||
'enabled' => !empty($settings['pay_balance_points_exchange_s']),
|
||||
@@ -120,6 +133,9 @@ class PaymentRuntime {
|
||||
'min_points' => max(1, min(10000000, (int) ($settings['pay_balance_points_exchange_min_points'] ?? 100))),
|
||||
'daily_max_points' => max(1, min(10000000, (int) ($settings['pay_balance_points_exchange_daily_max_points'] ?? 100000))),
|
||||
'desc' => sanitize_textarea_field((string) ($settings['pay_balance_points_exchange_desc'] ?? '')),
|
||||
'products_raw' => is_array($settings['pay_points_product'] ?? null)
|
||||
? self::format_points_product_lines($settings['pay_points_product'])
|
||||
: (string) ($settings['pay_points_product'] ?? ''),
|
||||
],
|
||||
];
|
||||
}
|
||||
@@ -229,8 +245,6 @@ class PaymentRuntime {
|
||||
],
|
||||
'benefit' => [
|
||||
'download_limit' => max(0, min(9999, (int) ($settings['pay_download_limit'] ?? 0))),
|
||||
// 会员卡密无独立开关(随「启用卡密兑换功能」总开关),仅保留单密码模式。
|
||||
'pass_charge_only_password' => !isset($settings['pay_vip_pass_charge_only_password']) || !empty($settings['pay_vip_pass_charge_only_password']),
|
||||
],
|
||||
'renew' => [
|
||||
'enabled' => !isset($settings['vip_renew']) || !empty($settings['vip_renew']),
|
||||
@@ -377,7 +391,10 @@ class PaymentRuntime {
|
||||
$paypal_enabled = !empty($settings['pay_paypal_sdk_s']);
|
||||
$stripe_enabled = !empty($settings['pay_stripe_sdk_s']);
|
||||
$balance_enabled = !empty($settings['pay_balance_s']);
|
||||
$card_pass_enabled = !empty($settings['pay_balance_pass_charge_s']);
|
||||
// 卡密收款接口随三个兑换开关任一生效(余额 / 积分 / 会员)。
|
||||
$card_pass_enabled = !empty($settings['pay_balance_pass_charge_s'])
|
||||
|| !empty($settings['points_pass_exchange_s'])
|
||||
|| !empty($settings['pay_vip_pass_charge_s']);
|
||||
|
||||
return [
|
||||
'help_text' => __('微信 / 支付宝可在官方与易支付之间选择;PayPal、Stripe 独立开关。异步回调由各网关验签。', 'aksrt'),
|
||||
@@ -553,7 +570,10 @@ class PaymentRuntime {
|
||||
case 'balance':
|
||||
return !empty($settings['pay_balance_s']);
|
||||
case 'card_pass':
|
||||
return !empty($settings['pay_balance_pass_charge_s']);
|
||||
// 收款接口随三个兑换开关任一生效(余额 / 积分 / 会员)。
|
||||
return !empty($settings['pay_balance_pass_charge_s'])
|
||||
|| !empty($settings['points_pass_exchange_s'])
|
||||
|| !empty($settings['pay_vip_pass_charge_s']);
|
||||
case 'epay':
|
||||
return $wechat === 'epay' || $alipay === 'epay';
|
||||
case 'epay_alipay':
|
||||
@@ -607,4 +627,24 @@ class PaymentRuntime {
|
||||
}
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format points product rows (reference-theme group shape:
|
||||
* points 积分 / pay_price 销售金额 / tag 小标签) into "积分|支付|标签" lines.
|
||||
*
|
||||
* @param array<int,mixed> $products
|
||||
*/
|
||||
private static function format_points_product_lines(array $products): string {
|
||||
$lines = [];
|
||||
foreach ($products as $row) {
|
||||
if (!is_array($row)) {
|
||||
continue;
|
||||
}
|
||||
$points = max(0, (int) ($row['points'] ?? 0));
|
||||
$pay_price = max(0, (float) ($row['pay_price'] ?? 0));
|
||||
$title = trim((string) ($row['tag'] ?? ''));
|
||||
$lines[] = $points . '|' . $pay_price . '|' . $title;
|
||||
}
|
||||
return implode("\n", $lines);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user