feat(payment): rebuild order details and asset records
This commit is contained in:
1 parent
476e2f961d
commit
7b55cfb190
57 files changed
+2080
-1294
No files matched your search
+18
-23
@@ -19,7 +19,7 @@ trait PayOrders {
|
||||
*/
|
||||
public function fulfill_paid_order(string $order_number, array $paid_order) {
|
||||
$product_type = sanitize_key((string) ($paid_order['product_type'] ?? ''));
|
||||
if ($product_type !== \AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE) {
|
||||
if (!\AKSRT\Core\DomainModel::is_resource_product_type($product_type)) {
|
||||
return true;
|
||||
}
|
||||
$post_id = (int) ($paid_order['product_id'] ?? 0);
|
||||
@@ -131,7 +131,8 @@ trait PayOrders {
|
||||
return $assert;
|
||||
}
|
||||
|
||||
$priced = $assert['priced'];
|
||||
$priced = $assert['priced'];
|
||||
$content_type = \AKSRT\Core\DomainModel::resolve_order_product_type(\AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE, ['pay_type' => $assert['meta']['pay_type'] ?? '']);
|
||||
if ((($priced['modo'] ?? '0') !== 'points')) {
|
||||
return new \WP_Error('aksrt_wrong_modo', __('该内容不支持积分支付。', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
@@ -164,6 +165,7 @@ trait PayOrders {
|
||||
|
||||
$note = wp_json_encode([
|
||||
'content_pay' => 1,
|
||||
'pay_type' => (string) ($assert['meta']['pay_type'] ?? ''),
|
||||
'pay_modo' => 'points',
|
||||
'post_id' => $post_id,
|
||||
'price_type' => $price_type,
|
||||
@@ -178,7 +180,7 @@ trait PayOrders {
|
||||
if (is_array($existing)) {
|
||||
$existing_meta = $this->decode_order_note_meta($existing);
|
||||
if ((int) ($existing['user_id'] ?? 0) !== $user_id
|
||||
|| sanitize_key((string) ($existing['product_type'] ?? '')) !== \AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE
|
||||
|| sanitize_key((string) ($existing['product_type'] ?? '')) !== $content_type
|
||||
|| (int) ($existing['product_id'] ?? 0) !== $post_id
|
||||
|| (string) ($existing['currency'] ?? '') !== 'points'
|
||||
|| (int) ($existing['amount'] ?? 0) !== $amount
|
||||
@@ -224,12 +226,12 @@ trait PayOrders {
|
||||
sprintf(__('积分购买《%s》', 'aksrt'), get_the_title($post_id)),
|
||||
$user_id,
|
||||
['post_id' => $post_id],
|
||||
static function () use ($is_new_order, $repo, $order_number, $operation_key, $user_id, $post_id, $amount, $note) {
|
||||
static function () use ($is_new_order, $repo, $order_number, $operation_key, $user_id, $post_id, $amount, $note, $content_type) {
|
||||
if ($is_new_order) {
|
||||
$created = $repo->create([
|
||||
'order_number' => $order_number,
|
||||
'user_id' => $user_id,
|
||||
'product_type' => \AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE,
|
||||
'product_type' => $content_type,
|
||||
'product_id' => $post_id,
|
||||
'amount' => $amount,
|
||||
'currency' => 'points',
|
||||
@@ -245,7 +247,6 @@ trait PayOrders {
|
||||
}
|
||||
$paid = \AKSRT\Payment\Order::get_instance()->update_status($order_number, \AKSRT\Payment\Order::STATUS_PAID, [
|
||||
'payment_method' => 'points',
|
||||
'payment_transaction_id' => 'points_' . $order_number,
|
||||
'note' => sprintf(__('积分支付 %d 积分。', 'aksrt'), $amount),
|
||||
'require_transition' => true,
|
||||
]);
|
||||
@@ -264,9 +265,7 @@ trait PayOrders {
|
||||
'amount' => $amount,
|
||||
'pay_modo' => 'points',
|
||||
'balance' => $ledger->balance($user_id, \AKSRT\Ledger\AssetType::POINTS),
|
||||
'transaction_id' => $deducted->transaction_id,
|
||||
'flow_number' => $deducted->flow_number,
|
||||
'replayed' => $deducted->replayed,
|
||||
'replayed' => $deducted->replayed,
|
||||
'message' => __('支付成功', 'aksrt'),
|
||||
'reload' => true,
|
||||
],
|
||||
@@ -289,6 +288,7 @@ trait PayOrders {
|
||||
$post = $assert['post'];
|
||||
$meta = $assert['meta'];
|
||||
$priced = $assert['priced'];
|
||||
$content_type = \AKSRT\Core\DomainModel::resolve_order_product_type(\AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE, ['pay_type' => $meta['pay_type'] ?? '']);
|
||||
if ((($priced['modo'] ?? '0') === 'points')) {
|
||||
return new \WP_Error('aksrt_wrong_modo', __('该内容仅支持积分支付。', 'aksrt'), ['status' => 400]);
|
||||
}
|
||||
@@ -331,6 +331,7 @@ trait PayOrders {
|
||||
}
|
||||
$note = wp_json_encode([
|
||||
'content_pay' => 1,
|
||||
'pay_type' => (string) ($meta['pay_type'] ?? ''),
|
||||
'pay_modo' => '0',
|
||||
'post_id' => $post_id,
|
||||
'price_type' => $price_type,
|
||||
@@ -355,7 +356,7 @@ trait PayOrders {
|
||||
$replayed = is_array($existing);
|
||||
if (is_array($existing)) {
|
||||
if ((int) ($existing['user_id'] ?? 0) !== max(0, $user_id)
|
||||
|| sanitize_key((string) ($existing['product_type'] ?? '')) !== \AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE
|
||||
|| sanitize_key((string) ($existing['product_type'] ?? '')) !== $content_type
|
||||
|| (int) ($existing['product_id'] ?? 0) !== $post_id
|
||||
|| sanitize_key((string) ($existing['payment_method'] ?? '')) !== 'free'
|
||||
|| (string) ($existing['amount'] ?? '') !== '0.00'
|
||||
@@ -366,7 +367,7 @@ trait PayOrders {
|
||||
} else {
|
||||
$order_number = $repo->create([
|
||||
'user_id' => max(0, $user_id),
|
||||
'product_type' => \AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE,
|
||||
'product_type' => $content_type,
|
||||
'product_id' => $post_id,
|
||||
'amount' => '0.00',
|
||||
'currency' => 'CNY',
|
||||
@@ -384,7 +385,7 @@ trait PayOrders {
|
||||
if ($status !== \AKSRT\Payment\Order::STATUS_PAID) {
|
||||
$paid = \AKSRT\Payment\Order::get_instance()->update_status($order_number, \AKSRT\Payment\Order::STATUS_PAID, [
|
||||
'payment_method' => 'free',
|
||||
'payment_transaction_id' => 'free_' . $order_number,
|
||||
'payment_transaction_id' => '',
|
||||
'note' => __('优惠后无需支付。', 'aksrt'),
|
||||
]);
|
||||
if (!$paid) {
|
||||
@@ -398,7 +399,7 @@ trait PayOrders {
|
||||
'amount' => '0.00',
|
||||
'pay_modo' => '0',
|
||||
'free' => true,
|
||||
'transaction_id' => 'free_' . $order_number,
|
||||
'transaction_id' => '',
|
||||
'replayed' => $replayed,
|
||||
'message' => __('无需支付,已可访问。', 'aksrt'),
|
||||
'reload' => true,
|
||||
@@ -430,7 +431,7 @@ trait PayOrders {
|
||||
$pending_coupon = (string) ($pending_meta['coupon']['code'] ?? $pending_coupon);
|
||||
}
|
||||
$can_resume = (int) ($pending['user_id'] ?? 0) === max(0, $user_id)
|
||||
&& sanitize_key((string) ($pending['product_type'] ?? '')) === \AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE
|
||||
&& sanitize_key((string) ($pending['product_type'] ?? '')) === $content_type
|
||||
&& (int) ($pending['product_id'] ?? 0) === $post_id
|
||||
&& (string) ($pending['amount'] ?? '') === $amount_decimal
|
||||
&& strtoupper((string) ($pending['currency'] ?? '')) === 'CNY'
|
||||
@@ -448,6 +449,7 @@ trait PayOrders {
|
||||
} else {
|
||||
$note = wp_json_encode([
|
||||
'content_pay' => 1,
|
||||
'pay_type' => (string) ($meta['pay_type'] ?? ''),
|
||||
'pay_modo' => '0',
|
||||
'post_id' => $post_id,
|
||||
'price_type' => $price_type,
|
||||
@@ -469,7 +471,7 @@ trait PayOrders {
|
||||
|
||||
$order_number = \AKSRT\Payment\OrderRepository::get_instance()->create([
|
||||
'user_id' => max(0, $user_id),
|
||||
'product_type' => \AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE,
|
||||
'product_type' => $content_type,
|
||||
'product_id' => $post_id,
|
||||
'amount' => $amount_decimal,
|
||||
'currency' => 'CNY',
|
||||
@@ -495,16 +497,12 @@ trait PayOrders {
|
||||
$payment_method = $user_id > 0 ? 'balance' : 'alipay';
|
||||
}
|
||||
if ($can_resume && (string) ($order['status'] ?? '') === \AKSRT\Payment\Order::STATUS_PAID) {
|
||||
$ledger_key = \AKSRT\Ledger\OperationKey::deterministic('order-payment', [$order_number]);
|
||||
$history = \AKSRT\Ledger\LedgerQuery::get_instance()->history(['operation_key' => $ledger_key, 'page' => 1, 'per_page' => 1]);
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'order_number' => $order_number,
|
||||
'amount' => $amount_decimal,
|
||||
'pay_modo' => '0',
|
||||
'transaction_id' => (int) ($history['items'][0]['id'] ?? 0),
|
||||
'flow_number' => \AKSRT\Finance\FinancialFlowQuery::get_instance()->order_payment_number($order_number),
|
||||
'replayed' => true,
|
||||
'balance' => \AKSRT\Ledger\LedgerService::get_instance()->balance_decimal($user_id),
|
||||
'message' => __('支付成功', 'aksrt'),
|
||||
@@ -559,7 +557,6 @@ trait PayOrders {
|
||||
'message' => $payment_result['message'],
|
||||
'reload' => false,
|
||||
'poll' => true,
|
||||
'transaction_id' => 0,
|
||||
'replayed' => false,
|
||||
],
|
||||
];
|
||||
@@ -571,7 +568,6 @@ trait PayOrders {
|
||||
'order_number' => $order_number,
|
||||
'amount' => $amount_decimal,
|
||||
'pay_modo' => '0',
|
||||
'transaction_id' => (int) ($payment_result['ledger_transaction_id'] ?? 0),
|
||||
'replayed' => !empty($payment_result['replayed']),
|
||||
'balance' => $user_id > 0 ? \AKSRT\Ledger\LedgerService::get_instance()->balance_decimal($user_id) : '0.00',
|
||||
'message' => $payment_result['message'],
|
||||
@@ -590,13 +586,12 @@ trait PayOrders {
|
||||
return null;
|
||||
}
|
||||
$orders = \AKSRT\Payment\OrderRepository::get_instance()->get_user_orders($user_id, [
|
||||
'product_type' => \AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE,
|
||||
'status' => \AKSRT\Core\DomainModel::ORDER_STATUS_PENDING,
|
||||
'limit' => 20,
|
||||
'offset' => 0,
|
||||
]);
|
||||
foreach ($orders as $order) {
|
||||
if ((int) ($order['product_id'] ?? 0) === $post_id) {
|
||||
if ((int) ($order['product_id'] ?? 0) === $post_id && \AKSRT\Core\DomainModel::is_resource_product_type((string) ($order['product_type'] ?? ''))) {
|
||||
return $order;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,9 +179,7 @@ trait PayRest {
|
||||
$order = $repo->get($order_number);
|
||||
// Guest may only poll own guest cash orders (user_id=0): content resource.
|
||||
$ptype = sanitize_key((string) ($order['product_type'] ?? ''));
|
||||
$guest_types = [
|
||||
\AKSRT\Core\DomainModel::ORDER_PRODUCT_RESOURCE,
|
||||
];
|
||||
$guest_types = \AKSRT\Core\DomainModel::resource_order_product_types();
|
||||
if ($order && ((int) ($order['user_id'] ?? -1) !== 0 || !in_array($ptype, $guest_types, true))) {
|
||||
$order = null;
|
||||
}
|
||||
|
||||
@@ -411,8 +411,6 @@ trait VipServicePurchase {
|
||||
return new \WP_Error('aksrt_order_create_failed', __('创建订单失败', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
if (is_array($existing) && (string) ($existing['status'] ?? '') === \AKSRT\Payment\Order::STATUS_PAID) {
|
||||
$ledger_key = \AKSRT\Ledger\OperationKey::deterministic('order-payment', [$order_number]);
|
||||
$history = \AKSRT\Ledger\LedgerQuery::get_instance()->history(['operation_key' => $ledger_key, 'page' => 1, 'per_page' => 1]);
|
||||
return [
|
||||
'success' => true,
|
||||
'data' => [
|
||||
@@ -421,8 +419,6 @@ trait VipServicePurchase {
|
||||
'level' => $level,
|
||||
'days' => $days,
|
||||
'action' => $action,
|
||||
'transaction_id' => (int) ($history['items'][0]['id'] ?? 0),
|
||||
'flow_number' => \AKSRT\Finance\FinancialFlowQuery::get_instance()->order_payment_number($order_number),
|
||||
'replayed' => true,
|
||||
'balance' => \AKSRT\Ledger\LedgerService::get_instance()->balance_decimal($user_id),
|
||||
'message' => __('会员购买已完成', 'aksrt'),
|
||||
@@ -491,7 +487,6 @@ trait VipServicePurchase {
|
||||
'message' => $payment_result['message'],
|
||||
'reload' => false,
|
||||
'poll' => true,
|
||||
'transaction_id' => 0,
|
||||
'replayed' => false,
|
||||
],
|
||||
];
|
||||
@@ -505,7 +500,6 @@ trait VipServicePurchase {
|
||||
'level' => $level,
|
||||
'days' => $days,
|
||||
'action' => $action,
|
||||
'transaction_id' => (int) ($payment_result['ledger_transaction_id'] ?? 0),
|
||||
'replayed' => !empty($payment_result['replayed']),
|
||||
'balance' => \AKSRT\Ledger\LedgerService::get_instance()->balance_decimal($user_id),
|
||||
'message' => $action === 'renew'
|
||||
@@ -549,6 +543,7 @@ trait VipServicePurchase {
|
||||
if (!empty($meta['card_pass']) || sanitize_key((string) ($meta['vip_pay_type'] ?? '')) === 'card_pass') {
|
||||
return true;
|
||||
}
|
||||
$vip_before = $this->get_membership_snapshot($user_id);
|
||||
|
||||
$level = (int) ($meta['level'] ?? 0);
|
||||
$days = (int) ($meta['days'] ?? 0);
|
||||
@@ -611,9 +606,16 @@ trait VipServicePurchase {
|
||||
$fulfilled = (int) get_user_meta($user_id, 'aksrt_vip_level', true) >= max($previous_level, $level)
|
||||
&& ($new_expiry === 0 || $days <= 0 || $new_expiry >= max($previous_expiry, time()) + ($days * DAY_IN_SECONDS));
|
||||
}
|
||||
if (!$fulfilled) {
|
||||
if (!$fulfilled) {
|
||||
return new \WP_Error('aksrt_vip_fulfillment_failed', __('会员权益发放失败。', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
$vip_after = $this->get_membership_snapshot($user_id);
|
||||
if (!\AKSRT\Payment\OrderRepository::get_instance()->merge_meta($order_number, [
|
||||
'vip_before' => $vip_before,
|
||||
'vip_after' => $vip_after,
|
||||
])) {
|
||||
return new \WP_Error('aksrt_vip_snapshot_failed', __('会员订单快照保存失败。', 'aksrt'), ['status' => 500]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -860,7 +862,6 @@ trait VipServicePurchase {
|
||||
}
|
||||
$paid = \AKSRT\Payment\Order::get_instance()->update_status($order_number, \AKSRT\Payment\Order::STATUS_PAID, [
|
||||
'payment_method' => 'points',
|
||||
'payment_transaction_id' => 'points_' . $order_number,
|
||||
'note' => sprintf(__('积分兑换会员 %d 积分。', 'aksrt'), $cost),
|
||||
'require_transition' => true,
|
||||
]);
|
||||
@@ -880,9 +881,7 @@ trait VipServicePurchase {
|
||||
'level' => $level,
|
||||
'days' => $days,
|
||||
'balance' => $ledger->balance($user_id, \AKSRT\Ledger\AssetType::POINTS),
|
||||
'transaction_id' => $deducted->transaction_id,
|
||||
'flow_number' => $deducted->flow_number,
|
||||
'replayed' => $deducted->replayed,
|
||||
'replayed' => $deducted->replayed,
|
||||
'message' => __('兑换成功', 'aksrt'),
|
||||
'reload' => true,
|
||||
],
|
||||
|
||||
Reference in new issue
Block a user