feat(pay): sales volume, paid order meta, pending resume, limit-over buy
Bump content sales on resource order paid; show order number/time in download box; poll pending gateway payments; support download_limit_over_price overbuy.
This commit is contained in:
@@ -21,6 +21,7 @@ class AKSRT_Domain_Model {
|
||||
public const RESOURCE_MARKER_KEY = '_aksrt_is_resource';
|
||||
public const RESOURCE_DOWNLOAD_COUNT_KEY = '_aksrt_res_download_count';
|
||||
public const RESOURCE_VIEW_COUNT_KEY = '_aksrt_res_view_count';
|
||||
public const RESOURCE_SALES_VOLUME_KEY = '_aksrt_sales_volume';
|
||||
public const POST_VIEW_COUNT_KEY = 'aksrt_post_views';
|
||||
|
||||
public const ORDER_MIGRATED_OPTION = 'aksrt_order_migrated_to_table';
|
||||
@@ -134,6 +135,8 @@ class AKSRT_Domain_Model {
|
||||
'purchase_limit' => 0,
|
||||
'free_preview' => '',
|
||||
'show_sales' => true,
|
||||
// Zibll: free daily quota overbuy price (cash or points by pay_modo).
|
||||
'download_limit_over_price' => 0.0,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -333,6 +336,7 @@ class AKSRT_Domain_Model {
|
||||
$meta['purchase_limit'] = max(0, (int) ($raw['purchase_limit'] ?? 0));
|
||||
$meta['free_preview'] = wp_kses_post((string) ($raw['free_preview'] ?? ''));
|
||||
$meta['show_sales'] = !isset($raw['show_sales']) || !empty($raw['show_sales']);
|
||||
$meta['download_limit_over_price'] = max(0, (float) ($raw['download_limit_over_price'] ?? 0));
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
@@ -150,12 +150,14 @@ if (!function_exists('aksrt_get_download_box_meta')) {
|
||||
$download_count = (int) get_post_meta($p->ID, AKSRT_Domain_Model::RESOURCE_DOWNLOAD_COUNT_KEY, true);
|
||||
$view_count = (int) get_post_meta($p->ID, AKSRT_Domain_Model::POST_VIEW_COUNT_KEY, true);
|
||||
$virtual_sales = max(0, (int) ($pay_meta['virtual_sales'] ?? 0));
|
||||
$sales_volume = (int) get_post_meta($p->ID, AKSRT_Domain_Model::RESOURCE_SALES_VOLUME_KEY, true);
|
||||
$show_sales = !isset($pay_meta['show_sales']) || !empty($pay_meta['show_sales']);
|
||||
$pay_modo = (($pay_meta['pay_modo'] ?? '0') === 'points') ? 'points' : '0';
|
||||
$pay_limit = (int) ($pay_meta['pay_limit'] ?? 0);
|
||||
if (!in_array($pay_limit, [0, 1, 2], true)) {
|
||||
$pay_limit = 0;
|
||||
}
|
||||
$over_price = max(0.0, (float) ($pay_meta['download_limit_over_price'] ?? 0));
|
||||
|
||||
return [
|
||||
'version' => (string) ($pay_meta['version'] ?? ''),
|
||||
@@ -177,8 +179,11 @@ if (!function_exists('aksrt_get_download_box_meta')) {
|
||||
'download_count' => max(0, $download_count),
|
||||
'view_count' => max(0, $view_count),
|
||||
'virtual_sales' => $virtual_sales,
|
||||
'sales_count' => $show_sales ? ($virtual_sales + max(0, $download_count)) : 0,
|
||||
'sales_volume' => max(0, $sales_volume),
|
||||
// Zibll: virtual (pay_cuont) + real sales_volume; fall back to downloads when no sales yet.
|
||||
'sales_count' => $show_sales ? ($virtual_sales + max(0, $sales_volume, $download_count)) : 0,
|
||||
'show_sales' => $show_sales,
|
||||
'download_limit_over_price' => $over_price,
|
||||
'require_login' => !empty($pay_meta['require_login']),
|
||||
'require_captcha' => !empty($pay_meta['require_captcha']),
|
||||
'subject_label' => __('内容', 'aksrt'),
|
||||
@@ -186,6 +191,52 @@ if (!function_exists('aksrt_get_download_box_meta')) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Latest paid content order for a user/post (resource product_type).
|
||||
*
|
||||
* @return array<string,mixed>|null
|
||||
*/
|
||||
if (!function_exists('aksrt_get_user_content_paid_order')) {
|
||||
function aksrt_get_user_content_paid_order(int $post_id, int $user_id = 0): ?array {
|
||||
$uid = $user_id > 0 ? $user_id : get_current_user_id();
|
||||
if ($uid <= 0 || $post_id <= 0 || !class_exists('AKSRT_Order_Repository')) {
|
||||
return null;
|
||||
}
|
||||
$orders = AKSRT_Order_Repository::get_instance()->get_user_orders($uid, [
|
||||
'product_type' => AKSRT_Domain_Model::ORDER_PRODUCT_RESOURCE,
|
||||
'status' => '',
|
||||
'limit' => 20,
|
||||
'offset' => 0,
|
||||
]);
|
||||
foreach ($orders as $order) {
|
||||
if ((int) ($order['product_id'] ?? 0) !== $post_id) {
|
||||
continue;
|
||||
}
|
||||
$status = (string) ($order['status'] ?? '');
|
||||
if (AKSRT_Domain_Model::is_paid_order_status($status)) {
|
||||
return $order;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment real sales volume for a paid content post (idempotent per order via order meta note flag optional).
|
||||
*/
|
||||
if (!function_exists('aksrt_bump_content_sales_volume')) {
|
||||
function aksrt_bump_content_sales_volume(int $post_id, int $delta = 1): int {
|
||||
if ($post_id <= 0 || $delta === 0) {
|
||||
return 0;
|
||||
}
|
||||
$key = AKSRT_Domain_Model::RESOURCE_SALES_VOLUME_KEY;
|
||||
$cur = (int) get_post_meta($post_id, $key, true);
|
||||
$next = max(0, $cur + $delta);
|
||||
update_post_meta($post_id, $key, $next);
|
||||
return $next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the amount a given user should pay for a post (Zibll VIP tier min).
|
||||
*
|
||||
|
||||
@@ -270,14 +270,22 @@ if (!function_exists('aksrt_check_free_download_quota')) {
|
||||
|
||||
$used = aksrt_get_user_free_downloaded_number($user_id);
|
||||
if ($used >= $limit) {
|
||||
$data = [
|
||||
'status' => 429,
|
||||
'limit' => $limit,
|
||||
'used' => $used,
|
||||
];
|
||||
// Optional overbuy price for free-quota exhausted (Zibll download_limit_over_price).
|
||||
// Callers may pass post context via filter.
|
||||
$over = apply_filters('aksrt_download_limit_over_price', 0.0, $user_id);
|
||||
if ($over > 0) {
|
||||
$data['download_limit_over_price'] = $over;
|
||||
$data['allow_limit_over'] = true;
|
||||
}
|
||||
return new WP_Error(
|
||||
'aksrt_download_limit',
|
||||
__('您今日下载免费资源个数已超限,请明日再下载。', 'aksrt'),
|
||||
[
|
||||
'status' => 429,
|
||||
'limit' => $limit,
|
||||
'used' => $used,
|
||||
]
|
||||
$data
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user