Ionic 4 中 SumUp terminal payment callback 无法返回
结论
问题出在协议配置不一致。SumUp 返回的是:
com.unmeat.app://result
而 ionic-plugin-deeplinks 的 DEEPLINK_SCHEME 配置成了 https。deeplink 的 scheme 和 host 必须与 callback 完全一致。另一种处理方式是把 SumUp callback 改为当前配置的 HTTPS App Link。
支付完成后的应用回跳通常更适合使用自定义 scheme:
com.unmeat.app://result
此外,还要确认 app-id 与 Android 应用实际使用的 application ID 完全一致,并对 callback 参数进行 URL 编码。
推荐配置
可以将 deeplink 配置改为:
{
"URL_SCHEME": "com.unmeat.app",
"DEEPLINK_SCHEME": "com.unmeat.app",
"DEEPLINK_HOST": "result",
"ANDROID_PATH_PREFIX": "/"
}
没有使用的第二至第五组配置应直接删除,不要传入空格。" " 并不是空值,而是一个实际字符,可能会生成无效或多余的 intent filter。
不同版本的 ionic-plugin-deeplinks 对 URL_SCHEME 和 DEEPLINK_SCHEME 的用途可能略有不同。某些版本使用 URL_SCHEME 注册自定义协议,而 DEEPLINK_SCHEME 和 DEEPLINK_HOST 用于 Android App Links。因此,修改配置后还要检查生成的 AndroidManifest.xml,确认其中存在能够匹配以下 URI 的 intent filter:
com.unmeat.app://result
关键声明应类似:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="com.unmeat.app"
android:host="result" />
</intent-filter>
调整 SumUp 启动地址
建议使用 encodeURIComponent() 编码 callback,避免嵌套 URI 被错误解析:
const callback = encodeURIComponent('com.unmeat.app://result');
this.options.uri =
'sumupmerchant://pay/1.0' +
'?affiliate-key=AFFILIATE_KEY' +
'&app-id=com.unmeat_test.app' +
'&total=22' +
'¤cy=CHF' +
'&title=' + encodeURIComponent('Test Order') +
'&receipt-mobilephone=' +
'&receipt-email=' +
'&callback=' + callback;
this.appLauncher.launch(this.options).then(
success => {
console.log('Success Launch', success);
},
error => {
console.log('Fail Launch', error);
}
);
也可以先把参数放入数组再拼接,减少漏编码的情况:
const params = [
`affiliate-key=${encodeURIComponent('AFFILIATE_KEY')}`,
`app-id=${encodeURIComponent('com.unmeat_test.app')}`,
`total=${encodeURIComponent('22')}`,
`currency=${encodeURIComponent('CHF')}`,
`title=${encodeURIComponent('Test Order')}`,
`callback=${encodeURIComponent('com.unmeat.app://result')}`
];
this.options.uri = `sumupmerchant://pay/1.0?${params.join('&')}`;
检查 app-id
示例中使用了两个不同的标识:
app-id=com.unmeat_test.app
callback=com.unmeat.app://result
callback scheme 不必与 application ID 相同,但 app-id 必须符合 SumUp 接口要求,并对应调用方应用实际使用的 Android application ID。需要检查:
<widget id="com.unmeat_test.app">
以及生成后的 Android 配置。如果应用实际使用的 ID 是 com.unmeat.app,启动参数也要改成:
app-id=com.unmeat.app
不能只根据 deeplink scheme 判断 application ID,应以项目的实际构建配置为准。
Ionic 中接收回调
注册 deeplink 监听时,需要匹配 result host:
this.deeplinks.route({
'/': {},
'/result': {}
}).subscribe(
match => {
console.log('SumUp callback received', match);
},
noMatch => {
console.log('Unmatched deeplink', noMatch);
}
);
在 com.unmeat.app://result 中,result 是 URI 的 host,插件不一定会把它识别为 /result 路径。更稳妥的做法是同时记录原始回调,确认当前插件版本对 host 和 path 的解析方式:
this.deeplinks.route({}).subscribe(
match => {
console.log('Deep link match', match);
},
noMatch => {
console.log('Deep link received but not matched', noMatch);
}
);
如果路由插件无法稳定匹配只有 host 的 URI,可以在 callback 中加入明确的路径:
com.unmeat.app://result/payment
对应配置仍为:
scheme = com.unmeat.app
host = result
path = /payment
修改后必须重新构建
Cordova 插件变量会写入 Android 原生配置。只修改 JavaScript 或 config.xml 后进行热更新,通常不会让这些变更生效。需要删除并重新添加插件或 Android 平台,再重新安装 APK。具体命令取决于项目所使用的 Ionic/Cordova 版本。
完成修改后,逐字符核对以下值:
callback scheme: com.unmeat.app
manifest scheme: com.unmeat.app
callback host: result
manifest host: result
通过外部测试成功打开应用,只能说明某个 intent filter 可以启动该应用。这不能证明 SumUp 收到的 callback 参数正确,也不能证明当前 deeplink 路由规则能够匹配回调 URI。
备注:内容仅供参考。
