fix: 补全iOS抖音支付SDK回跳URL

This commit is contained in:
Codex
2026-09-11 13:58:55 +08:00
parent f568fa0f7a
commit b6e45cd707
5 changed files with 78 additions and 3 deletions
+44
View File
@@ -14,6 +14,50 @@ const compiled = ts.transpileModule(source, {
}).outputText;
const info = { appid: 'app', partnerid: 'merchant', prepayid: 'prepay', package: 'Sign=DYPay',
noncestr: 'nonce', timestamp: '1780000000', sign: 'signed+value/==' };
function loadIOS(configure = () => true) {
const iosSource = fs.readFileSync(path.join(__dirname, '../uni_modules/tb-douyin-pay/utssdk/app-ios/index.uts'), 'utf8')
.replace(/^import .*$/gm, '');
const iosJS = ts.transpileModule(iosSource, {
compilerOptions: { target: ts.ScriptTarget.ES2020, module: ts.ModuleKind.CommonJS },
}).outputText;
const registrations = [];
const native = { initialize: (...args) => registrations.push(args), processURL: () => false };
const ctx = { exports: {}, configure, TbDouyinPayNative: native };
vm.runInNewContext(iosJS, ctx);
return { ...ctx.exports, registrations, native };
}
test('actual iOS bridge passes a complete callback URL to the native SDK boundary', () => {
for (const scheme of ['trustbridgeapp', ' trustbridgeapp ', 'trustbridgeapp://', 'trustbridgeapp://dypay']) {
const bridge = loadIOS();
assert.equal(bridge.initDypay({ appId: 'signed-app-id', callbackScheme: scheme }), true);
assert.deepEqual(bridge.registrations, [['signed-app-id', 'trustbridgeapp://dypay', '']]);
}
const bridge = loadIOS();
bridge.initDypay({ appId: 'signed-app-id', callbackScheme: 'trustbridgeapp', universalLink: 'https://example.com/pay/' });
assert.deepEqual(bridge.registrations, [['signed-app-id', 'trustbridgeapp://dypay', 'https://example.com/pay/']]);
});
test('iOS rejects malformed return URLs and failed configuration before native registration', () => {
for (const scheme of ['', ' ', 'invalid scheme', 'trustbridgeapp://other', 'trustbridgeapp://dypay?unexpected=1']) {
const bridge = loadIOS(() => assert.fail('Invalid URL must not change shared configuration'));
assert.equal(bridge.initDypay({ appId: 'app', callbackScheme: scheme }), false);
assert.equal(bridge.registrations.length, 0);
}
const bridge = loadIOS(() => false);
assert.equal(bridge.initDypay({ appId: 'app', callbackScheme: 'trustbridgeapp' }), false);
assert.equal(bridge.registrations.length, 0);
});
test('iOS return hook forwards the original callback URL and preserves SDK handled result', () => {
const bridge = loadIOS();
const url = { absoluteString: 'trustbridgeapp://dypay?resultCode=0' };
for (const handled of [false, true]) {
bridge.native.processURL = received => { assert.equal(received, url); return handled; };
assert.equal(new bridge.TbDouyinPayHook().applicationOpenURLOptions(null, url, null), handled);
}
});
function load(stringify = JSON.stringify) {
const timers = new Map();
let timerId = 0;