From aad83072a89a6e3a5d0c4ce3073e9c71a3f7d713 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 18 Sep 2026 22:14:27 +0800 Subject: [PATCH] =?UTF-8?q?refactor(pay):=20=E7=BB=9F=E4=B8=80=E6=B5=81?= =?UTF-8?q?=E6=B0=B4=E5=8F=B7=EF=BC=8C=E7=A7=BB=E9=99=A4=E8=AE=A2=E5=8D=95?= =?UTF-8?q?/=E6=B5=81=E6=B0=B4/=E6=8F=90=E7=8E=B0=E4=B8=89=E7=B1=BB?= =?UTF-8?q?=E5=8F=B7=E7=A0=81=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 订单号、资金流水号、提现单号此前各自带前缀配置,同一笔业务在不同界面会 呈现多个号码口径,对账与客诉排查都要先做一次前缀换算。现收敛为单一流水号 分配器,不再按业务类型区分号码形态。 - 删除 payment_order_prefix / payment_flow_prefix / payment_withdrawal_prefix 三项配置项及其生成、校验链路 - BusinessNumber::allocate() 成为唯一入口,输出 {YmdHis}{6 位随机}, 共 20 位无前缀,满足 VARCHAR(32) 与网关 out_trade_no ≤ 32 的限制 - 订单、资金流水、提现、卡密渠道交易号四处生成点全部改走该分配器 - 后台支付中心表头「订单号 / 提现单号」统一为「流水号」 - 前台用户中心与订单卡片文案同步统一;前台订单详情合并为单行流水号, 账本流水号不再下发到前台,避免同一单据出现两个对外号码 - 同步更新 financial-flow / pay-card / card-pass-order-numbers 契约测试 与 BusinessNumberTest 断言 按用户要求不做双路逻辑与数据迁移,直接替换为统一方案,历史行不做转换。 验证:node --test tests/**/*.test.cjs 362/364 通过,新增 37 项契约;失败的 2 项在改动前的干净 HEAD 基线上同样失败(基线 327 项 / 失败 2 项),分别命中 遗留的 fa fa- 标记与 FA 版本号断言,与本次改动无关。phpunit 44 项 / 103 断言全部通过;php -l 全部改动的 PHP 文件通过。 --- .../admin/src/constants/sections/payment.js | 2 +- .../src/schema/sections/payment/gateway.js | 12 ++---- .../src/schema/sections/payment/knowledge.js | 2 +- assets/js/credits.js | 2 +- assets/js/order-center.js | 4 +- assets/js/vip-purchase-coordinator.js | 2 +- inc/helpers/aksrt-pay.php | 2 +- .../user-center-renderers/profile-creator.php | 2 +- .../user-center-renderers/profile-orders.php | 6 +-- src/Admin/Native/PayFlows.php | 4 +- src/Admin/Native/PayIncome.php | 4 +- src/Admin/Native/PayOrders.php | 8 ++-- src/Admin/Native/PayWithdrawals.php | 4 +- src/Admin/Schema/SchemaPayment.php | 9 ++-- src/Admin/SchemaProvider.php | 3 -- src/Finance/BusinessNumber.php | 32 +++++++------- src/Finance/FinancialFlowService.php | 8 ++-- src/Payment/ChargeCard.php | 15 +++---- src/Payment/OrderRepositoryCore.php | 36 +++------------- src/Payment/PaymentOrchestrator.php | 2 +- src/Payment/UserOrders.php | 5 +-- src/Payment/Withdrawal.php | 4 +- src/Settings/CreditsPaymentGroups.php | 2 +- src/Settings/MailTemplates.php | 8 ++-- src/Settings/PaymentRuntime.php | 3 -- templates/parts/resource-download-box.php | 2 +- tests/admin/card-pass-order-numbers.test.cjs | 18 ++++---- tests/asset-ledger/BusinessNumberTest.php | 24 +++++++---- .../financial-flow-contract.test.cjs | 42 +++++++++++++++---- .../widget-system/pay-card-contract.test.cjs | 3 +- 30 files changed, 126 insertions(+), 144 deletions(-) diff --git a/assets/admin/src/constants/sections/payment.js b/assets/admin/src/constants/sections/payment.js index 13a804bb..e48f90b8 100644 --- a/assets/admin/src/constants/sections/payment.js +++ b/assets/admin/src/constants/sections/payment.js @@ -73,7 +73,7 @@ export const paymentSection = { route: '/payment/gateway', status: 'available', title: '收款接口', - desc: '微信/支付宝接口选择、PayPal/Stripe 开关、货币结算、显示顺序与订单编号前缀。', + desc: '微信/支付宝接口选择、PayPal/Stripe 开关、货币结算、显示顺序与订单支付时效。', canonicalDomain: 'payment', section: 'gateway', }), diff --git a/assets/admin/src/schema/sections/payment/gateway.js b/assets/admin/src/schema/sections/payment/gateway.js index c0dcb190..1e8a00ce 100644 --- a/assets/admin/src/schema/sections/payment/gateway.js +++ b/assets/admin/src/schema/sections/payment/gateway.js @@ -30,14 +30,14 @@ const currencyOptions = [ /** * 收款接口 — 参考主题双下拉式重构:微信/支付宝接口选择(官方/易支付/关闭)、 - * PayPal/Stripe 独立开关、货币与结算、订单与编号(含三个前缀)、 + * PayPal/Stripe 独立开关、货币与结算、订单与编号、 * 收款接口显示顺序,以及 5 个凭据配置块(支付宝/微信/PayPal/Stripe/易支付)。 */ export const gatewaySchema = { key: 'payment.gateway', title: '收款接口', icon: 'fa fas fa-credit-card', - description: '配置收款通道:微信与支付宝可在官方/易支付之间选择,PayPal 与 Stripe 独立开关。订单前缀、流水号前缀、提现单号前缀在本页配置。', + description: '配置收款通道:微信与支付宝可在官方/易支付之间选择,PayPal 与 Stripe 独立开关。订单、资金流水与提现统一使用同一套自动流水号,无需配置前缀。', defaults: { pay_wechat_sdk_options: 'null', pay_alipay_sdk_options: 'null', @@ -49,9 +49,6 @@ export const gatewaySchema = { pay_alipay_settle: { settle_rate: '1', settle_mark: '¥', settle_unit: '元' }, pay_sdk_custom_title_s: false, pay_sdk_custom_title: '', - payment_order_prefix: 'AKSRT', - payment_flow_prefix: 'AK', - payment_withdrawal_prefix: 'TX', payment_order_expiry: 30, pay_wait_float_s: true, pay_sdk_order: {}, @@ -167,11 +164,8 @@ export const gatewaySchema = { key: 'order', title: '订单与编号', icon: 'fa fas fa-hashtag', - description: '订单号、流水号与提现单号的前缀配置(原名配置项保留于此)。', + description: '订单支付时效与浮窗提示;订单、资金流水与提现的流水号由系统统一自动分配,无需配置。', fields: [ - { key: 'payment_order_prefix', label: '订单前缀', type: 'input', default: 'AKSRT', help: '订单号生成前缀' }, - { key: 'payment_flow_prefix', label: '流水号前缀', type: 'input', sanitize_type: 'business_prefix', default: 'AK', maxlength: 12, help: '仅允许字母、数字、下划线和短横线,最多 12 位。' }, - { key: 'payment_withdrawal_prefix', label: '提现单号前缀', type: 'input', sanitize_type: 'business_prefix', default: 'TX', maxlength: 12, help: '仅允许字母、数字、下划线和短横线,最多 12 位。' }, { key: 'payment_order_expiry', label: '订单支付时效(分钟)', type: 'number', default: 30, min: 5, max: 1440, help: '用户下单后,最大支付时间,超过后订单将自动关闭(不能低于5分钟)' }, { key: 'pay_wait_float_s', label: '浮窗显示待支付订单', type: 'switch', default: true, help: '将用户待支付订单一直显示在右上角,提醒用户付款' }, ], diff --git a/assets/admin/src/schema/sections/payment/knowledge.js b/assets/admin/src/schema/sections/payment/knowledge.js index 6712d6db..0ac5ab5a 100644 --- a/assets/admin/src/schema/sections/payment/knowledge.js +++ b/assets/admin/src/schema/sections/payment/knowledge.js @@ -124,7 +124,7 @@ export const knowledgeSchema = { { key: 'pay_mark', label: '付费标记', type: 'input', default: '付费' }, { key: 'payment_show_ip', label: '显示用户IP', type: 'switch', default: false }, { key: 'payment_show_device', label: '显示设备信息', type: 'switch', default: false }, - { key: 'payment_show_order_no', label: '显示订单号', type: 'switch', default: true }, + { key: 'payment_show_order_no', label: '显示流水号', type: 'switch', default: true }, { key: 'payment_show_create_time', label: '显示创建时间', type: 'switch', default: true }, { key: 'payment_show_pay_time', label: '显示支付时间', type: 'switch', default: true }, ], diff --git a/assets/js/credits.js b/assets/js/credits.js index 9c9ed6b8..582638fd 100644 --- a/assets/js/credits.js +++ b/assets/js/credits.js @@ -994,7 +994,7 @@ var number = document.createElement('span'); number.className = 'uc-withdraw-history__number muted-2-color em09'; var numberLabel = document.createElement('span'); - numberLabel.textContent = '提现单号:'; + numberLabel.textContent = '流水号:'; number.appendChild(numberLabel); var code = document.createElement('code'); code.textContent = text(item && item.withdrawal_number); diff --git a/assets/js/order-center.js b/assets/js/order-center.js index e74b0213..d44bf28a 100644 --- a/assets/js/order-center.js +++ b/assets/js/order-center.js @@ -86,7 +86,7 @@ html += '
' + escapeHtml(title) + ""; html += '' + escapeHtml(order.product_type_label || "") + "
"; html += '
'; - [["订单编号", order.order_number], ["流水号", order.flow_number || "—"], ["创建时间", order.created_at], ["支付时间", order.paid_at || "—"]].forEach(function (row) { + [["流水号", order.order_number], ["创建时间", order.created_at], ["支付时间", order.paid_at || "—"]].forEach(function (row) { html += "
" + escapeHtml(row[0]) + "
" + escapeHtml(row[1] || "—") + "
"; }); html += "
"; @@ -186,7 +186,7 @@ : ""; return '
' + '
' + escapeHtml(order.product_type_label || "") + '' + escapeHtml(order.status_label || "") + "
" + - '
' + image + '

' + escapeHtml(order.product_name || "订单") + "

订单号 " + escapeHtml(order.order_number) + "

" + formatMoney(order) + "实付
" + + '
' + image + '

' + escapeHtml(order.product_name || "订单") + "

流水号 " + escapeHtml(order.order_number) + "

" + formatMoney(order) + "实付
" + '
' + countdown + actionHtml(order) + "
"; } diff --git a/assets/js/vip-purchase-coordinator.js b/assets/js/vip-purchase-coordinator.js index ffcff75d..213b7928 100644 --- a/assets/js/vip-purchase-coordinator.js +++ b/assets/js/vip-purchase-coordinator.js @@ -377,7 +377,7 @@ if (data.redirect && (data.payment_url || data.qr_content)) { callback(options, "onPending", data); if (!data.order_number) { - var missing = { ok: false, status: 500, json: { message: "支付订单号缺失" } }; + var missing = { ok: false, status: 500, json: { message: "流水号缺失" } }; callback(options, "onError", missing); return missing; } diff --git a/inc/helpers/aksrt-pay.php b/inc/helpers/aksrt-pay.php index b8195d9e..4ade0008 100644 --- a/inc/helpers/aksrt-pay.php +++ b/inc/helpers/aksrt-pay.php @@ -1567,7 +1567,7 @@ if (!function_exists('aksrt_get_paid_box_html')) { } $amount_text = $cash_symbol . aksrt_format_price($order_amount); } - $paid_info = '
' . esc_html__('订单号', 'aksrt') . '' . esc_html($order_number) . '
'; + $paid_info = '
' . esc_html__('流水号', 'aksrt') . '' . esc_html($order_number) . '
'; if ($paid_at !== '') { $paid_info .= '
' . esc_html__('支付时间', 'aksrt') . '' . esc_html($paid_at) . '
'; } diff --git a/inc/helpers/user-center-renderers/profile-creator.php b/inc/helpers/user-center-renderers/profile-creator.php index 096254ed..8c926881 100644 --- a/inc/helpers/user-center-renderers/profile-creator.php +++ b/inc/helpers/user-center-renderers/profile-creator.php @@ -102,7 +102,7 @@ $currency_labels = [ $status = (string) ($item['status'] ?? '') === 'pending' ? 'pending' : 'settled'; $amount = $format($item['amount'] ?? 0, $unit); $order_number = trim((string) ($item['order_number'] ?? '')); - $order_number = $order_number !== '' ? $order_number : __('订单编号未知', 'aksrt'); + $order_number = $order_number !== '' ? $order_number : __('流水号未知', 'aksrt'); $post = get_post((int) ($item['post_id'] ?? 0)); $source = $post instanceof WP_Post && $post->post_type === 'post' ? get_the_title($post) diff --git a/inc/helpers/user-center-renderers/profile-orders.php b/inc/helpers/user-center-renderers/profile-orders.php index 2c421c32..114d3673 100644 --- a/inc/helpers/user-center-renderers/profile-orders.php +++ b/inc/helpers/user-center-renderers/profile-orders.php @@ -62,9 +62,9 @@ $status_options = [ @@ -112,7 +112,7 @@ $status_options = [
-

+