#!/usr/bin/env node import { chromium } from 'playwright'; const API_BASE = 'https://server.fmode.cn'; const PARSE_BASE = API_BASE + '/parse/functions'; const APP_ID = 'ncloudmaster'; const PAY_COMPANY = '1AiWpTEDH9'; function getArg(name, fallback = '') { const prefix = `--${name}=`; const match = process.argv.find(arg => arg.startsWith(prefix)); return match ? match.slice(prefix.length) : fallback; } function makeTradeNo(user) { const now = new Date(); const pad = value => String(value).padStart(2, '0'); return 'Cbr' + user.replace(/[^a-zA-Z0-9]/g, '').slice(0, 8) + now.getFullYear() + pad(now.getMonth() + 1) + pad(now.getDate()) + pad(now.getHours()) + pad(now.getMinutes()) + pad(now.getSeconds()) + String(now.getMilliseconds()).padStart(3, '0'); } async function main() { const user = getArg('user', '2luFP8J1H1'); const authid = getArg('authid', 'd1DOPlTNCb'); const fcompany = getArg('fcompany', PAY_COMPANY); const apigid = getArg('apigid', 'G0vmsUI44d'); // fun_id 必须是充值云函数 apigRechargeOnPay 的 objectId;voc-e-commerce 是 APIG 的 path,传它会导致回调找不到云函数、不入账 const funId = getArg('fun_id', 'HOkkX72PMF'); const price = Number(getArg('price', '0.01')); const count = Number(getArg('count', '1')); const oldCount = Number(getArg('oldCount', '1003')); const tradeNo = getArg('trade', makeTradeNo(user)); const bodyText = `国内电商数据中台 接口充值(${count} 次)`; const browser = await chromium.launch({ headless: true }); const page = await browser.newPage(); await page.goto('https://app.fmode.cn/dev/apig-pay/', { waitUntil: 'domcontentloaded' }); const result = await page.evaluate(async ({ API_BASE, PARSE_BASE, APP_ID, PAY_COMPANY, user, authid, fcompany, apigid, funId, price, count, oldCount, tradeNo, bodyText }) => { async function postJSON(url, body) { const resp = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) }); const text = await resp.text(); let data; try { data = JSON.parse(text); } catch { data = text; } return { ok: resp.ok, status: resp.status, data }; } const order = await postJSON(API_BASE + '/api/apig/created-apigorder', { type: 'wxpay', user, authid, fcompany, apigid, oldCount, params: { out_trade_no: tradeNo, total_fee: price, body: bodyText }, count }); const pay = await postJSON(PARSE_BASE + '/pay_code2', { _ApplicationId: APP_ID, company: PAY_COMPANY, out_trade_no: tradeNo, total_fee: price, body: bodyText, fun_id: funId }); const payResult = pay.data?.result || {}; const nonceStr = Array.isArray(payResult.nonce_str) ? payResult.nonce_str[0] : payResult.nonce_str; const status = nonceStr ? await postJSON(PARSE_BASE + '/order_status2', { _ApplicationId: APP_ID, out_trade_no: tradeNo, nonce_str: nonceStr, company: PAY_COMPANY }) : null; return { tradeNo, order, pay, status }; }, { API_BASE, PARSE_BASE, APP_ID, PAY_COMPANY, user, authid, fcompany, apigid, funId, price, count, oldCount, tradeNo, bodyText }); await browser.close(); console.log(JSON.stringify(result, null, 2)); } main().catch(err => { console.error('[failed]', err.message); process.exit(1); });