Initial commit: Memind H5 portal with MindSpace, Plaza, and agent jobs.

Track application source and tests; exclude local env, user workspaces, and runtime data via .gitignore.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
John
2026-06-15 15:04:43 -07:00
commit 2e14873f2d
272 changed files with 64133 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import {
buildXml,
createWechatPayClient,
loadWechatPayConfig,
parseXmlFields,
signV2Params,
} from './wechat-pay.mjs';
test('signV2Params is deterministic and uppercase MD5', () => {
const params = {
appid: 'wx8888888888888888',
mch_id: '1900000109',
body: 'test',
nonce_str: 'ibuaiVcKdpRxkhJA',
};
const apiKey = '8934e7d15453e97507ef794cf7b0519d';
const sign = signV2Params(params, apiKey);
assert.match(sign, /^[0-9A-F]{32}$/);
assert.equal(sign, signV2Params(params, apiKey));
assert.notEqual(sign, signV2Params({ ...params, body: 'other' }, apiKey));
});
test('parseXmlFields and buildXml round-trip', () => {
const xml = buildXml({
return_code: 'SUCCESS',
out_trade_no: 'TK123',
total_fee: '500',
});
const fields = parseXmlFields(xml);
assert.equal(fields.return_code, 'SUCCESS');
assert.equal(fields.out_trade_no, 'TK123');
assert.equal(fields.total_fee, '500');
});
test('loadWechatPayConfig selects v2 when APIv2 key is configured', () => {
const previous = {
enabled: process.env.H5_WECHAT_PAY_ENABLED,
appId: process.env.H5_WECHAT_APP_ID,
mchId: process.env.H5_WECHAT_MCH_ID,
apiV2Key: process.env.H5_WECHAT_API_V2_KEY,
apiVersion: process.env.H5_WECHAT_API_VERSION,
notifyUrl: process.env.H5_WECHAT_NOTIFY_URL,
v3Key: process.env.H5_WECHAT_API_V3_KEY,
serialNo: process.env.H5_WECHAT_SERIAL_NO,
privateKey: process.env.H5_WECHAT_PRIVATE_KEY,
};
process.env.H5_WECHAT_PAY_ENABLED = '1';
process.env.H5_WECHAT_APP_ID = 'wxtestappid';
process.env.H5_WECHAT_MCH_ID = '1234567890';
process.env.H5_WECHAT_API_V2_KEY = 'test-api-v2-key-32chars-long!!!!';
process.env.H5_WECHAT_NOTIFY_URL = 'https://example.com/webhooks/wechat-pay/notify';
delete process.env.H5_WECHAT_API_VERSION;
delete process.env.H5_WECHAT_API_V3_KEY;
delete process.env.H5_WECHAT_SERIAL_NO;
delete process.env.H5_WECHAT_PRIVATE_KEY;
try {
const config = loadWechatPayConfig();
assert.equal(config.apiVersion, 'v2');
assert.equal(config.enabled, true);
const client = createWechatPayClient(config);
assert.equal(client.apiVersion, 'v2');
assert.equal(client.enabled, true);
} finally {
for (const [key, value] of Object.entries(previous)) {
const envKey = {
enabled: 'H5_WECHAT_PAY_ENABLED',
appId: 'H5_WECHAT_APP_ID',
mchId: 'H5_WECHAT_MCH_ID',
apiV2Key: 'H5_WECHAT_API_V2_KEY',
apiVersion: 'H5_WECHAT_API_VERSION',
notifyUrl: 'H5_WECHAT_NOTIFY_URL',
v3Key: 'H5_WECHAT_API_V3_KEY',
serialNo: 'H5_WECHAT_SERIAL_NO',
privateKey: 'H5_WECHAT_PRIVATE_KEY',
}[key];
if (value === undefined) delete process.env[envKey];
else process.env[envKey] = value;
}
}
});
test('verifyNotify validates v2 callback signature', () => {
const apiKey = 'test-api-v2-key-32chars-long!!!!';
const fields = {
return_code: 'SUCCESS',
result_code: 'SUCCESS',
out_trade_no: 'TKORDER001',
transaction_id: '4200001234',
total_fee: '1000',
nonce_str: 'abc123',
};
fields.sign = signV2Params(fields, apiKey);
const body = buildXml(fields);
const client = createWechatPayClient({
enabled: true,
apiVersion: 'v2',
appId: 'wxtest',
mchId: '123',
apiKey,
notifyUrl: 'https://example.com/notify',
skipNotifyVerify: false,
});
const { transaction } = client.verifyNotify({ headers: {}, body });
assert.equal(transaction.out_trade_no, 'TKORDER001');
assert.equal(transaction.trade_state, 'SUCCESS');
assert.equal(transaction.amount.total, 1000);
});