feat(M05-D): 完成收款配置与幂等分账
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { generateKeyPairSync } from 'node:crypto';
|
||||
import { buildApp } from '../dist/app.js';
|
||||
import { loadConfig } from '../dist/config.js';
|
||||
import { signAccessToken } from '../dist/auth/jwt.js';
|
||||
import { WechatPayClient } from '../dist/payments/wechat-pay-client.js';
|
||||
|
||||
assert.equal(loadConfig({
|
||||
NODE_ENV: 'production',
|
||||
QIPAI_JWT_SECRET: 'production-profit-share-secret-long-enough',
|
||||
QIPAI_PROFIT_SHARE_MOCK_ENABLED: 'true'
|
||||
}).payment.profitShareMockEnabled, false);
|
||||
assert.equal(loadConfig({
|
||||
NODE_ENV: 'test',
|
||||
QIPAI_PROFIT_SHARE_MOCK_ENABLED: 'true'
|
||||
}).payment.profitShareMockEnabled, true);
|
||||
|
||||
const keys = generateKeyPairSync('rsa', {
|
||||
modulusLength: 2048,
|
||||
publicKeyEncoding: { type: 'spki', format: 'pem' },
|
||||
privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
|
||||
});
|
||||
let apiRequest;
|
||||
const client = new WechatPayClient({
|
||||
async request(input) {
|
||||
apiRequest = input;
|
||||
return {
|
||||
status: 200,
|
||||
headers: {},
|
||||
body: JSON.stringify({ order_id: 'wx-share-order', state: 'FINISHED' })
|
||||
};
|
||||
}
|
||||
});
|
||||
const shareResult = await client.createProfitSharing({
|
||||
appId: 'wx-test',
|
||||
merchantId: '1900000109',
|
||||
serialNo: 'serial-test',
|
||||
privateKeyPem: keys.privateKey,
|
||||
apiV3Key: '0123456789abcdef0123456789abcdef',
|
||||
platformCertificates: {},
|
||||
profitShareReceivers: {}
|
||||
}, {
|
||||
transactionId: 'wx-transaction-001',
|
||||
outOrderNo: 'share-request-001',
|
||||
receivers: [{
|
||||
type: 'MERCHANT_ID',
|
||||
account: 'receiver-account-private',
|
||||
amountCents: 1200,
|
||||
description: 'sanitized share'
|
||||
}],
|
||||
finish: true
|
||||
});
|
||||
assert.equal(shareResult.state, 'FINISHED');
|
||||
assert.match(apiRequest.url, /\/v3\/profitsharing\/orders$/);
|
||||
assert.match(apiRequest.body, /"amount":1200/);
|
||||
assert.equal(apiRequest.headers.Authorization.includes(keys.privateKey), false);
|
||||
|
||||
const secret = 'profit-sharing-route-secret-32-characters';
|
||||
const token = signAccessToken({
|
||||
sub: '21', sid: '5c4d3af8-c63c-4edb-bf95-b84127bb3f6e',
|
||||
tid: '7', aid: '9', rv: 1
|
||||
}, secret, 900);
|
||||
let executeInput;
|
||||
const app = await buildApp({
|
||||
payment: {
|
||||
jwtSecret: secret,
|
||||
testAdapterEnabled: false,
|
||||
authRepository: {
|
||||
async validateSession() {
|
||||
return {
|
||||
id: '5c4d3af8-c63c-4edb-bf95-b84127bb3f6e',
|
||||
tenantId: '7', platformAppId: '9',
|
||||
expiresAt: new Date(Date.now() + 60000),
|
||||
user: {
|
||||
id: '21', tenantId: '7', userType: 'ADMIN', status: 'ACTIVE',
|
||||
roleVersion: 1, nickname: '', avatarUrl: '', phone: ''
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
accessControl: {
|
||||
async getAccessProfile() {
|
||||
return {
|
||||
roles: ['TENANT_ADMIN'],
|
||||
capabilities: ['tenant.manage'],
|
||||
storeIds: []
|
||||
};
|
||||
}
|
||||
},
|
||||
repository: {
|
||||
async createPayment() { return {}; },
|
||||
async processTestCallback() { return {}; }
|
||||
},
|
||||
profitSharing: {
|
||||
async saveCollectionAccount() {
|
||||
return { accountId: '41', created: true };
|
||||
},
|
||||
async saveReceiver() {
|
||||
return { receiverId: '42', created: true };
|
||||
},
|
||||
async savePolicy() {
|
||||
return { saved: true };
|
||||
},
|
||||
async execute(input) {
|
||||
executeInput = input;
|
||||
return {
|
||||
shares: [{ shareId: '43', amountCents: 1200, status: 'SUCCEEDED' }],
|
||||
idempotent: false
|
||||
};
|
||||
},
|
||||
async list() {
|
||||
return { accounts: [], shares: [] };
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const executed = await app.inject({
|
||||
method: 'POST',
|
||||
url: '/admin-api/pay/profit-shares',
|
||||
headers: { authorization: `Bearer ${token}` },
|
||||
payload: {
|
||||
paymentId: '31',
|
||||
clientRequestId: 'share-request-001',
|
||||
mode: 'MOCK'
|
||||
}
|
||||
});
|
||||
assert.equal(executed.statusCode, 200);
|
||||
assert.equal(executeInput.tenantId, '7');
|
||||
assert.equal(executeInput.access.capabilities[0], 'tenant.manage');
|
||||
|
||||
await app.close();
|
||||
console.log('PASS: M05-D Wechat profit-sharing request, production mock gate and admin routes.');
|
||||
Reference in New Issue
Block a user