feat(pay): content cashier, resource orders at VIP price, purchase/download JS loop

Wire zibll-style one-shot points/cash cashier for post+_aksrt_pay downloads:
server amount from aksrt_get_user_pay_price, ORDER_PRODUCT_RESOURCE unlock,
frontend need-purchase opens modal, download box purchased/VIP/purchase CTAs.
This commit is contained in:
kate522 committed 2026-07-14 11:52:44 +08:00
1 parent abe2f57417
commit 770205623d
11 files changed
+1142 -170

No files matched your search

+31 -50
View File
@@ -121,38 +121,41 @@ class AKSRT_Content_Visibility {
// Member-only purchase restriction (Zibll pay_limit).
if ($pay_limit > 0 && $pay_type !== AKSRT_Domain_Model::PAY_TYPE_NO) {
$state['need_vip'] = true;
$state['need_vip'] = $uid <= 0 || $user_vip_level < $pay_limit;
$allowed_member = $uid > 0 && $user_vip_level >= $pay_limit;
if ($pay_type === AKSRT_Domain_Model::PAY_TYPE_DOWNLOAD) {
$download_cost = function_exists('aksrt_resource_download_cost')
? (int) aksrt_resource_download_cost($resource_post)
: (int) ceil($price);
// If member is free via VIP price, cost is 0.
// Cash: order gate only. Points: cashier once → paid order zeros cost.
$download_cost = 0;
if ($pay_modo === 'points' && $price > 0 && !$has_paid_order) {
$download_cost = (int) ceil($price);
}
if ($allowed_member && $price <= 0) {
$download_cost = 0;
}
$state['download_cost'] = max(0, $download_cost);
$state['need_login'] = $uid <= 0;
$state['need_purchase'] = $allowed_member && $state['download_cost'] > 0 && !$has_paid_order;
$state['has_paid_access'] = $allowed_member && ($has_paid_order || $state['download_cost'] <= 0);
$state['need_purchase'] = $allowed_member && $price > 0 && !$has_paid_order;
$state['has_paid_access'] = $allowed_member && ($has_paid_order || $price <= 0);
$state['can_view'] = true;
$state['can_download'] = $allowed_member && ($uid > 0) && ($has_paid_order || $state['download_cost'] <= 0);
$state['can_download'] = $allowed_member && ($uid > 0) && ($has_paid_order || $price <= 0);
if (!$allowed_member) {
$state['can_download'] = false;
$state['has_paid_access'] = false;
$state['need_purchase'] = false;
$state['need_vip'] = true;
}
return $state;
}
$state['has_paid_access'] = ($allowed_member && $price <= 0) || $has_paid_order || ($allowed_member && $has_vip_access && $pay_type === AKSRT_Domain_Model::PAY_TYPE_VIP);
// For reading/gallery/video with pay_limit: members still need to purchase unless free.
// reading/gallery/video with pay_limit
if ($allowed_member) {
$state['has_paid_access'] = $has_paid_order || $price <= 0;
$state['need_purchase'] = !$state['has_paid_access'];
$state['need_vip'] = false;
} else {
$state['has_paid_access'] = false;
$state['need_purchase'] = false;
$state['need_vip'] = true;
}
$state['can_view'] = $state['has_paid_access'];
$state['can_download'] = false;
@@ -160,34 +163,23 @@ class AKSRT_Content_Visibility {
}
if ($pay_type === AKSRT_Domain_Model::PAY_TYPE_DOWNLOAD) {
$download_cost = function_exists('aksrt_resource_download_cost')
? (int) aksrt_resource_download_cost($resource_post)
: (int) ceil($price);
// Zibll: cash = order unlock; points = one-shot cashier order (not per-download deduct).
$download_cost = 0;
if ($pay_modo === 'points' && $price > 0 && !$has_paid_order) {
$download_cost = (int) ceil($price);
}
$state['download_cost'] = max(0, $download_cost);
// Zibll pay_free_logged_show: free download still requires login.
$free_logged_show = !empty($paid_settings['free_logged_show']);
$state['need_login'] = !empty($paid_settings['download_login'])
|| !empty($pay_meta['require_login'])
|| ($free_logged_show && $state['download_cost'] <= 0);
|| ($free_logged_show && $price <= 0);
$state['require_captcha'] = !empty($paid_settings['download_captcha']) || !empty($pay_meta['require_captcha']);
// Cash mode with cost handled by orders: need purchase when no order and base price > 0.
$needs_pay = $state['download_cost'] > 0 || ($pay_modo === '0' && $price > 0 && !$has_paid_order && empty($paid_settings['download_credit']));
if ($pay_modo === '0' && $price > 0 && empty($paid_settings['download_credit'])) {
$state['need_purchase'] = !$has_paid_order && !($has_vip_access && $price <= 0);
$state['has_paid_access'] = $has_paid_order || $price <= 0;
// Download still gated by login/credit path for token; cash unlock is order-based.
$state['can_view'] = true;
$state['can_download'] = ($has_paid_order || $price <= 0) && (!$state['need_login'] || $uid > 0);
return $state;
}
$state['need_purchase'] = !$has_paid_order && $state['download_cost'] > 0 && !$has_free_access;
// VIP with free tier amount already reflected in download_cost.
$state['has_paid_access'] = $has_paid_order || $state['download_cost'] <= 0 || $has_free_access;
$state['need_purchase'] = !$has_paid_order && $price > 0;
$state['has_paid_access'] = $has_paid_order || $price <= 0 || $has_free_access;
$state['can_view'] = true;
$state['can_download'] = (!$state['need_login'] || $uid > 0) && ($has_paid_order || $state['download_cost'] <= 0 || true);
// can_download true only means "may request token"; rest_request still deducts credits.
$state['can_download'] = (!$state['need_login'] || $uid > 0) && ($has_paid_order || $price <= 0);
return $state;
}
@@ -270,14 +262,19 @@ class AKSRT_Content_Visibility {
]);
}
// Cash purchase required (order path).
if (!empty($state['need_purchase']) && empty($state['has_paid_access']) && $cost <= 0 && (($state['pay_modo'] ?? '0') === '0')) {
// Cash or points: require cashier purchase (resource order) before download token.
if (!empty($state['need_purchase']) && empty($state['has_paid_access'])) {
$pay_modo = (string) ($state['pay_modo'] ?? '0');
$price = (float) ($state['price'] ?? 0);
return new WP_Error('aksrt_need_purchase', __('请先购买后再下载。', 'aksrt'), [
'status' => 402,
'pay_modo' => $pay_modo,
'amount' => $pay_modo === 'points' ? (int) ceil($price) : $price,
'post_id' => (int) ($state['post_id'] ?? 0),
]);
}
// Zibll daily free-download quota.
// Zibll daily free-download quota (only when free / already unlocked).
if ($cost <= 0 && function_exists('aksrt_check_free_download_quota')) {
$quota = aksrt_check_free_download_quota($uid, $cost);
if (is_wp_error($quota)) {
@@ -285,22 +282,6 @@ class AKSRT_Content_Visibility {
}
}
$pay_modo = (string) ($state['pay_modo'] ?? '0');
$need_credit_check = $cost > 0 && (
$pay_modo === 'points'
|| !empty($paid_settings['download_credit'])
);
if ($need_credit_check) {
$balance = class_exists('AKSRT_Credits') ? AKSRT_Credits::balance($uid) : 0;
if ($balance < $cost) {
return new WP_Error('aksrt_credits_insufficient', __('积分不足,无法下载。', 'aksrt'), [
'status' => 402,
'balance' => $balance,
'cost' => $cost,
]);
}
}
return true;
}