PAYATHON 2026

鸿蒙跳转支付宝小程序支付后 onNewWant 未收到回调

支付阿杰

结论

只在 module.json5 中声明 scheme,不能保证支付完成后一定触发 onNewWant。还需要满足以下条件:

  1. EntryAbility 配置了完整的 URI 匹配规则,包括 action、entity 和 scheme。
  2. EntryAbility 的启动模式是 singleton。已有实例接收到新的 Want 时,才会触发 onNewWant。
  3. 冷启动时,在 onCreate 中也处理支付回调。
  4. 支付完成后,支付宝小程序或支付宝客户端确实发起了类似 aliMiniAppPayScheme://... 的跳转。
  5. 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.viewData
  • entities 是否包含 entity.system.browsable
  • scheme 是否完全一致
  • EntryAbility 是否设置为 singleton
  • 修改配置后是否重新编译并安装
  • 是否有其他 Ability 声明了相同的 scheme
  • 回调 URI 是否合法,例如 aliminipppayscheme://pay/result

支付宝侧必须主动返回

backSCAppScheme 通常只是向支付宝或小程序提供返回地址,并不表示所有支付流程都会自动使用它。还需要确认:

  • 当前的支付宝拉起方式是否支持 backSCAppScheme
  • 支付宝客户端是否正确识别该参数
  • 小程序完成支付后是否调用了相应的”返回商家应用”能力
  • 用户取消支付、关闭小程序和支付成功时,是否使用不同的返回逻辑
  • 回调 URI 是否包含预期参数

可以在支付成功页面增加一个明确的”返回商家应用”入口进行验证。如果点击后能回到鸿蒙应用,但自动返回仍不生效,问题通常出在支付宝小程序的支付完成流程,而不是 EntryAbility。

注意事项

自定义 scheme 回调只能说明应用被重新打开,不能作为支付成功的可信凭证。URI 参数可能缺失、重复触发或被伪造。应用收到回调后,应根据订单号向业务服务端查询最终状态,或者以支付宝服务端的异步通知为准。

还需要处理重复回调,避免 onCreate、onNewWant 或用户多次点击返回入口时,重复更新订单或重复跳转页面。

备注:内容仅供参考。