feat: WeChat Pay V3 integration (fill credentials to activate)
Server: - New lib/wxpay.js: native crypto RSA-SHA256 signing, JSAPI prepay, AES-256-GCM notify decryption, order query (no npm deps) - New dao/payment-order.dao.js: createOrder, markPrepay, markPaidAndActivateSubscription (idempotent + transactional) - New routes/payment.js: GET order status, POST order sync - New routes/payment-notify.js: WeChat async callback handler with signature verification, amount/appid/mchid validation - Modified subscription/purchase: auto-detects wxpay config, returns real payment_params or mock fallback - Schema: payment_orders table with out_trade_no unique key - app.js: express.raw() for notify path, payment routes mounted - config.js: wxpay block with 7 env vars - .env.example: all WeChat Pay fields documented - .gitignore: certs/, *.pem, *.p12 Miniprogram: - subscribe-plans doPurchase: calls real purchase API, falls back to mockPurchase only when server returns mock:true - Added syncAndRedirect for post-payment order confirmation - api.js: getPaymentOrder, syncPaymentOrder - Removed "模拟支付"/"测试环境" from UI text
这个提交包含在:
@@ -159,6 +159,24 @@ CREATE TABLE IF NOT EXISTS firmware_files (
|
||||
KEY idx_firmware_version (version, status)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS payment_orders (
|
||||
order_id VARCHAR(64) NOT NULL COMMENT 'out_trade_no',
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
plan VARCHAR(32) NOT NULL,
|
||||
amount_fen INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'created' COMMENT 'created/paying/paid/closed/failed/refunded',
|
||||
prepay_id VARCHAR(128) NOT NULL DEFAULT '',
|
||||
transaction_id VARCHAR(64) NOT NULL DEFAULT '',
|
||||
trade_state VARCHAR(32) NOT NULL DEFAULT '',
|
||||
raw_notify_json JSON NULL,
|
||||
paid_at DATETIME NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (order_id),
|
||||
KEY idx_payment_orders_user (user_id, status),
|
||||
CONSTRAINT fk_payment_orders_user FOREIGN KEY (user_id) REFERENCES users (user_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT IGNORE INTO system_settings (setting_key, setting_value) VALUES
|
||||
('system_name', '"光子美容仪后台"'),
|
||||
('monthly_price', '99'),
|
||||
|
||||
在新工单中引用
屏蔽一个用户