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:
@@ -146,6 +146,21 @@ trait BalanceServiceCharge {
|
||||
$methods[] = is_array($m) ? $m : ['id' => $id, 'name' => $id];
|
||||
}
|
||||
}
|
||||
// 卡密支付渠道:受「启用卡密兑换余额功能」开关控制(开关内部已含收款接口主开关)。
|
||||
$pass_charge = is_array($cfg['pass_charge'] ?? null) ? $cfg['pass_charge'] : [];
|
||||
$card_pass_on = false;
|
||||
if (class_exists('\AKSRT\Payment\ChargeCard')) {
|
||||
$card_opts = \AKSRT\Payment\ChargeCard::get_instance()->get_public_options();
|
||||
$card_pass_on = !empty($card_opts['balance']['enabled']);
|
||||
$pass_charge = [
|
||||
'balance' => is_array($card_opts['balance'] ?? null) ? $card_opts['balance'] : $pass_charge,
|
||||
'credits' => is_array($card_opts['credits'] ?? null) ? $card_opts['credits'] : [],
|
||||
'vip' => is_array($card_opts['vip'] ?? null) ? $card_opts['vip'] : [],
|
||||
];
|
||||
}
|
||||
if ($card_pass_on) {
|
||||
$methods[] = ['id' => 'card_pass', 'name' => __('卡密', 'aksrt')];
|
||||
}
|
||||
return [
|
||||
'enabled' => !empty($cfg['enabled']),
|
||||
'desc' => (string) ($cfg['desc'] ?? ''),
|
||||
@@ -160,7 +175,7 @@ trait BalanceServiceCharge {
|
||||
'service_charge' => (int) ($cfg['transfer']['service_charge'] ?? 0),
|
||||
'desc' => (string) ($cfg['transfer']['desc'] ?? ''),
|
||||
],
|
||||
'pass_charge' => is_array($cfg['pass_charge'] ?? null) ? $cfg['pass_charge'] : [],
|
||||
'pass_charge' => $pass_charge,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -206,6 +221,48 @@ trait BalanceServiceCharge {
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 积分商品行解析("积分|支付|标签",参考主题 pay_points_product 同款结构)。
|
||||
*
|
||||
* @return array<int,array{key:string,points:int,pay_price:string,title:string,tag:string}>
|
||||
*/
|
||||
public function parse_points_packages(string $raw): array {
|
||||
$out = [];
|
||||
$lines = preg_split('/\r\n|\r|\n/', $raw) ?: [];
|
||||
$i = 0;
|
||||
foreach ($lines as $line) {
|
||||
$line = trim((string) $line);
|
||||
if ($line === '') {
|
||||
continue;
|
||||
}
|
||||
$parts = array_map('trim', explode('|', $line));
|
||||
if (count($parts) < 2) {
|
||||
continue;
|
||||
}
|
||||
$points = (int) $parts[0];
|
||||
try {
|
||||
$pay = \AKSRT\Ledger\AssetAmount::balance((string) $parts[1]);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
continue;
|
||||
}
|
||||
if ($points <= 0 || $pay->minor() <= 0) {
|
||||
continue;
|
||||
}
|
||||
$title = $parts[2] ?? '';
|
||||
$out[] = [
|
||||
'key' => (string) $i,
|
||||
'points' => $points,
|
||||
'pay_price' => $pay->decimal(),
|
||||
'title' => $title !== '' ? $title : sprintf(__('购买 %d 积分', 'aksrt'), $points),
|
||||
'tag' => $title,
|
||||
];
|
||||
$i++;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return array<string,mixed>|\WP_Error
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user