鸿蒙跳转支付宝小程序支付后 onNewWant 未收到回调
结论
只在 module.json5 中声明 scheme,不能保证支付完成后一定触发 onNewWant。还需要满足以下条件:
EntryAbility配置了完整的 URI 匹配规则,包括action、entity和scheme。EntryAbility的启动模式是singleton。已有实例接收到新的 Want 时,才会触发onNewWant。- 冷启动时,在
onCreate中也处理支付回调。 - 支付完成后,支付宝小程序或支付宝客户端确实发起了类似
aliMiniAppPayScheme://...的跳转。 backSCAppScheme作为支付宝拉起 URL 的独立参数传入,没有被误拼到qrcode参数中。
如果支付完成后,支付宝没有主动打开回调 URI,鸿蒙侧不会自行触发 onNewWant。
配置 EntryAbility
在 module.json5 中为 EntryAbility 添加完整的 skills 配置,并将启动模式设为 singleton:
{
"module": {
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"exported": true,
"launchType": "singleton",
"skills": [
{
"actions": [
"ohos.want.action.viewData"
],
"entities": [
"entity.system.browsable"
],
"uris": [
{
"scheme": "aliminipppayscheme"
}
]
}
]
}
]
}
}
自定义 scheme 建议全部使用小写,并确保以下三处完全一致:
module.json5中的scheme- 传给支付宝的
backSCAppScheme - 支付完成后实际打开的回调 URI
例如,统一使用:
aliminipppayscheme
对应的回调 URI 可以写成:
aliminipppayscheme://pay/result?status=success
修改 module.json5 后,需要重新安装应用。只做热更新或重新运行页面,有时不会让新的 URI 匹配配置生效。
正确处理 Ability 生命周期
onNewWant 只会在 Ability 实例已经存在,并且新请求被路由到该实例时触发。如果应用进程已被回收,回调 URI 会重新创建 Ability,此时触发的是 onCreate。
因此,两个入口都需要处理:
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.handlePayCallback(want);
}
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
this.handlePayCallback(want);
}
private handlePayCallback(want: Want): void {
const uri = want.uri ?? '';
hilog.info(
0x0000,
'PayCallback',
'received callback uri: %{public}s',
uri
);
if (!uri.startsWith('aliminipppayscheme://')) {
return;
}
// 根据实际回调 URI 解析支付标识。
// 最终支付结果仍应以服务端查询或异步通知为准。
}
}
测试时不要只观察 onNewWant。如果应用是冷启动,回调很可能进入 onCreate。
正确构造拉起支付宝的 URL
qrcode 通常也是一个完整 URL,必须先编码。否则,其中的 &、? 或 # 可能破坏外层 alipays:// URL 的参数结构。
const qrcode = 'https://example.com/pay?...';
const link =
'alipays://platformapi/startapp' +
'?saId=xxx' +
`&qrcode=${encodeURIComponent(qrcode)}` +
'&backSCAppScheme=aliminipppayscheme';
需要确认 backSCAppScheme 位于外层查询参数中,而不是 qrcode URL 的一部分。
如果支付宝接口要求传入完整的回调 URI,而不是单独的 scheme,应按照相应的支付宝接口文档传递。例如:
const callbackUri = 'aliminipppayscheme://pay/result';
const link =
'alipays://platformapi/startapp' +
'?saId=xxx' +
`&qrcode=${encodeURIComponent(qrcode)}` +
`&backSCAppScheme=${encodeURIComponent(callbackUri)}`;
backSCAppScheme 要求传入 scheme 名称还是完整 URI,取决于采用的支付宝小程序支付接入方式和客户端版本。不能只根据参数名称判断,应以接口的实际约定为准。
先验证鸿蒙侧的 URI 路由
排查支付宝之前,可以先直接测试自定义 scheme 能否拉起应用。
直接打开以下 URI:
aliminipppayscheme://pay/result?status=test
如果 onCreate 或 onNewWant 能收到 want.uri,说明鸿蒙侧配置基本正确。此时,若支付完成后仍没有回调,应重点检查支付宝侧是否真的执行了返回跳转。
如果直接打开 URI 也无法进入 Ability,需要重点检查:
actions是否包含ohos.want.action.viewDataentities是否包含entity.system.browsablescheme是否完全一致EntryAbility是否设置为singleton- 修改配置后是否重新编译并安装
- 是否有其他 Ability 声明了相同的 scheme
- 回调 URI 是否合法,例如
aliminipppayscheme://pay/result
支付宝侧必须主动返回
backSCAppScheme 通常只是向支付宝或小程序提供返回地址,并不表示所有支付流程都会自动使用它。还需要确认:
- 当前的支付宝拉起方式是否支持
backSCAppScheme - 支付宝客户端是否正确识别该参数
- 小程序完成支付后是否调用了相应的”返回商家应用”能力
- 用户取消支付、关闭小程序和支付成功时,是否使用不同的返回逻辑
- 回调 URI 是否包含预期参数
可以在支付成功页面增加一个明确的”返回商家应用”入口进行验证。如果点击后能回到鸿蒙应用,但自动返回仍不生效,问题通常出在支付宝小程序的支付完成流程,而不是 EntryAbility。
注意事项
自定义 scheme 回调只能说明应用被重新打开,不能作为支付成功的可信凭证。URI 参数可能缺失、重复触发或被伪造。应用收到回调后,应根据订单号向业务服务端查询最终状态,或者以支付宝服务端的异步通知为准。
还需要处理重复回调,避免 onCreate、onNewWant 或用户多次点击返回入口时,重复更新订单或重复跳转页面。
备注:内容仅供参考。
