fix payment points

This commit is contained in:
2026-09-04 23:35:19 +08:00
parent f3fcfe45da
commit 9dc278bd83
6 changed files with 44 additions and 19 deletions
-8
View File
@@ -886,14 +886,6 @@
return; return;
} }
const cashierLink = e.target.closest('.cashier-link');
if (cashierLink && cashierLink.hasAttribute('data-aksrt-pay-content')) {
e.preventDefault();
const postId = parseInt(cashierLink.getAttribute('data-aksrt-pay-content') || '0', 10);
if (postId) openCashier(postId, cashierLink);
return;
}
const btn = e.target.closest('[data-action="aksrt-download"]'); const btn = e.target.closest('[data-action="aksrt-download"]');
if (!btn) return; if (!btn) return;
if (btn.disabled || btn.getAttribute('aria-disabled') === 'true') return; if (btn.disabled || btn.getAttribute('aria-disabled') === 'true') return;
-9
View File
@@ -87,15 +87,6 @@ if (!function_exists('aksrt_is_vip_exempt')) {
function aksrt_get_pay_types(): array { function aksrt_get_pay_types(): array {
return \AKSRT\Core\DomainModel::pay_type_labels(); return \AKSRT\Core\DomainModel::pay_type_labels();
return [
AKSRT_PAY_TYPE_NO => __('不付费', 'aksrt'),
AKSRT_PAY_TYPE_READING => __('付费阅读', 'aksrt'),
AKSRT_PAY_TYPE_DOWNLOAD => __('付费下载', 'aksrt'),
AKSRT_PAY_TYPE_GALLERY => __('付费图库', 'aksrt'),
AKSRT_PAY_TYPE_VIDEO => __('付费视频', 'aksrt'),
AKSRT_PAY_TYPE_VIP => __('VIP 专属', 'aksrt'),
];
} }
/** /**
+4 -2
View File
@@ -39,8 +39,10 @@ final class CommissionLedger {
]); ]);
return $result >= 0; return $result >= 0;
} }
public function record_paid_order(array $order): int { public function record_paid_order(array $order): int {
if (!\AKSRT\Settings\Settings::affiliate_enabled()) return 0; $currency = sanitize_key((string) ($order['currency'] ?? ''));
if ($currency === \AKSRT\Ledger\AssetType::POINTS->value) return 0;
if (!\AKSRT\Settings\Settings::affiliate_enabled()) return 0;
$type = sanitize_key((string) ($order['product_type'] ?? '')); $type = sanitize_key((string) ($order['product_type'] ?? ''));
$map = ['vip' => 'membership', 'resource' => 'content']; $map = ['vip' => 'membership', 'resource' => 'content'];
$order_type = $map[$type] ?? $type; $order_type = $map[$type] ?? $type;
@@ -0,0 +1,15 @@
<?php
use AKSRT\Payment\CommissionLedger;
use PHPUnit\Framework\TestCase;
final class CommissionLedgerTest extends TestCase {
public function test_points_orders_do_not_create_cash_commissions(): void {
$result = CommissionLedger::get_instance()->record_paid_order([
'currency' => 'points',
'amount' => 500,
]);
self::assertSame(0, $result);
}
}
+1
View File
@@ -85,4 +85,5 @@ require_once dirname(__DIR__, 2) . '/src/Ledger/LedgerCommand.php';
require_once dirname(__DIR__, 2) . '/src/Ledger/LedgerResult.php'; require_once dirname(__DIR__, 2) . '/src/Ledger/LedgerResult.php';
require_once dirname(__DIR__, 2) . '/src/Ledger/OperationKey.php'; require_once dirname(__DIR__, 2) . '/src/Ledger/OperationKey.php';
require_once dirname(__DIR__, 2) . '/src/Finance/BusinessNumber.php'; require_once dirname(__DIR__, 2) . '/src/Finance/BusinessNumber.php';
require_once dirname(__DIR__, 2) . '/src/Payment/CommissionLedger.php';
require_once dirname(__DIR__, 2) . '/src/Payment/Withdrawal.php'; require_once dirname(__DIR__, 2) . '/src/Payment/Withdrawal.php';
@@ -129,6 +129,30 @@ test('core asset paths never use floating-point money helpers', () => {
assert.deepEqual(violations, []) assert.deepEqual(violations, [])
}) })
test('points orders bypass cash commissions and purchase dead paths stay removed', () => {
const commission = fs.readFileSync(path.join(root, 'src', 'Payment', 'CommissionLedger.php'), 'utf8')
const paidStart = commission.indexOf('public function record_paid_order')
const paidEnd = commission.indexOf('public function settle_due', paidStart)
const paidMethod = commission.slice(paidStart, paidEnd)
const pointsGuard = paidMethod.indexOf('AssetType::POINTS->value')
const affiliateGuard = paidMethod.indexOf('Settings::affiliate_enabled()')
assert.ok(paidStart >= 0 && paidEnd > paidStart)
assert.ok(pointsGuard >= 0 && affiliateGuard > pointsGuard)
assert.match(paidMethod, /\$currency\s*=\s*sanitize_key/)
const pay = fs.readFileSync(path.join(root, 'inc', 'helpers', 'aksrt-pay.php'), 'utf8')
const payTypesStart = pay.indexOf('function aksrt_get_pay_types')
const cashMethodsStart = pay.indexOf('function aksrt_list_cash_payment_methods', payTypesStart)
const payTypesMethod = pay.slice(payTypesStart, cashMethodsStart)
assert.ok(payTypesStart >= 0 && cashMethodsStart > payTypesStart)
assert.equal((payTypesMethod.match(/(?:^|\n)\s*return\b/g) || []).length, 1)
const cashier = fs.readFileSync(path.join(root, 'assets', 'js', 'cms-download.js'), 'utf8')
assert.match(cashier, /\[data-action="aksrt-need-purchase"\], \[data-aksrt-pay-content\]/)
assert.doesNotMatch(cashier, /const cashierLink\s*=\s*e\.target\.closest\('\.cashier-link'\)/)
})
test('content preview is read-only while purchase requires an operation key', () => { test('content preview is read-only while purchase requires an operation key', () => {
const source = fs.readFileSync(path.join(root, 'src', 'Content', 'PayRest.php'), 'utf8') const source = fs.readFileSync(path.join(root, 'src', 'Content', 'PayRest.php'), 'utf8')
const previewStart = source.indexOf('public function rest_preview') const previewStart = source.indexOf('public function rest_preview')