feat(credits): exchange balance for points

Replace the legacy points-to-balance and external points purchase flows
with direct integer balance-to-points exchange. Enforce exchange and
points-transfer limits and capability checks across the UI and REST API.
This commit is contained in:
kate522 committed 2026-08-13 15:20:06 +08:00
1 parent f9bce15c9a
commit 1247f9bf4e
18 files changed
+234 -648

No files matched your search

-73
View File
@@ -30,74 +30,6 @@ trait BalanceServiceCharge {
return;
}
// Points purchase fulfill (zibll order_type=9).
if ($type === \AKSRT\Core\DomainModel::ORDER_PRODUCT_POINTS_BUY) {
if (!class_exists('AKSRT\\Credits\\Credits')) {
return;
}
$note = json_decode((string) ($order['note'] ?? ''), true);
if (!is_array($note)) {
$note = [];
}
if (!empty($note['points_credited'])) {
return;
}
$rate = 100;
if (class_exists('\AKSRT\Settings\Settings')) {
$rate = max(1, (int) (\AKSRT\Settings\Settings::get_all()['points_rate'] ?? 100));
}
$points = isset($note['points_amount'])
? (int) $note['points_amount']
: (int) round((float) ($order['amount'] ?? 0) * $rate);
if ($points <= 0) {
return;
}
global $wpdb;
if ($wpdb->query('START TRANSACTION') === false) {
return;
}
$add = Credits::add(
$user_id,
$points,
'points_buy',
['type' => 'order', 'order' => $order_number],
sprintf(__('购买积分订单 %s', 'aksrt'), $order_number),
false
);
if (is_wp_error($add)) {
$wpdb->query('ROLLBACK');
return;
}
$note['points_credited'] = 1;
$note['credited_points'] = $points;
$updated = $wpdb->update(
$wpdb->prefix . 'aksrt_order',
['note' => wp_json_encode($note, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)],
['order_number' => $order_number],
['%s'],
['%s']
);
if ($updated === false) {
$wpdb->query('ROLLBACK');
wp_cache_delete($user_id, 'user_meta');
return;
}
if ($wpdb->query('COMMIT') === false) {
$wpdb->query('ROLLBACK');
wp_cache_delete($user_id, 'user_meta');
return;
}
do_action('aksrt_credits_added', $user_id, $points, 'points_buy', (int) $add);
if (class_exists('\AKSRT\Payment\OrderRepository')) {
\AKSRT\Payment\OrderRepository::get_instance()->update_status(
$order_number,
\AKSRT\Payment\Order::STATUS_COMPLETED,
['note' => __('购买积分已到账。', 'aksrt')]
);
}
return;
}
if ($type !== \AKSRT\Core\DomainModel::ORDER_PRODUCT_RECHARGE) {
return;
}
@@ -204,11 +136,6 @@ trait BalanceServiceCharge {
'service_charge' => (int) ($cfg['transfer']['service_charge'] ?? 0),
'desc' => (string) ($cfg['transfer']['desc'] ?? ''),
],
'exchange' => [
'enabled' => !empty($cfg['exchange']['enabled']),
'rate' => (int) ($cfg['exchange']['rate'] ?? 100),
'desc' => (string) ($cfg['exchange']['desc'] ?? ''),
],
'pass_charge' => is_array($cfg['pass_charge'] ?? null) ? $cfg['pass_charge'] : [],
];
}