PAYATHON 2026

有没有官方或权威的支付宝 App 支付 Cordova/Capacitor 插件?

支付阿杰

结论

支付宝开放平台提供 Android 和 iOS 原生 App 支付 SDK,但一般不提供由官方维护的 Cordova 或 Capacitor 支付插件。

网上常见的 cordova-plugin-alipay、capacitor-alipay 等包,大多是社区项目。即使这些插件封装了官方 SDK,也不代表它们是支付宝官方插件。对于涉及真实交易的项目,建议采用以下方案:

  1. 服务端通过支付宝 App 支付接口创建订单并完成签名。
  2. 客户端接入支付宝官方 Android 或 iOS SDK。
  3. 自行编写一层简单的 Capacitor 或 Cordova 原生桥接。
  4. 以支付宝服务端异步通知或主动查询结果作为最终支付依据。

如果要使用第三方插件,需要检查源码、原生 SDK 来源、近期维护情况和隐私行为,不能只参考包名、下载量或 README 中的“官方 SDK”字样。

为什么很难找到“官方插件”

支付宝 App 支付的核心是原生 SDK。Cordova 和 Capacitor 负责把 JavaScript 调用转发到 Android 或 iOS,插件需要处理很多框架和平台相关的问题,包括:

  • Android、iOS 支付 SDK 的依赖和升级;
  • Android 混淆、组件声明和应用签名;
  • iOS URL Scheme、应用跳转和回调;
  • 不同 Capacitor、Cordova 版本的桥接接口;
  • 支付结果序列化;
  • SDK 更新后的兼容性调整。

支付宝维护原生 SDK,不代表它也会维护各类跨端框架的适配插件。判断插件是否由官方提供,应查看支付宝开放平台文档、官方代码仓库或官方发布渠道,不能仅凭 npm 包名判断。

推荐的集成结构

完整的支付链路如下:

Ionic App
    │
    │ 请求创建订单
    ▼
业务服务端
    │
    │ 调用支付宝接口并生成已签名 orderString
    ▼
Ionic App
    │
    │ 通过 Capacitor/Cordova 原生桥接
    ▼
支付宝 Android/iOS App 支付 SDK
    │
    │ 唤起支付宝 App
    ▼
支付宝
    │
    │ 异步通知
    ▼
业务服务端验证签名并更新订单状态

私钥、应用密钥和签名逻辑必须保存在服务端。客户端只接收短期有效且与当前订单绑定的 orderString,再将其交给原生 SDK。

Capacitor 的调用接口示例

可以先定义一个简单的 JavaScript 接口:

import { registerPlugin } from '@capacitor/core';

export interface AlipayPlugin {
  pay(options: {
    orderString: string;
  }): Promise<{
    resultStatus?: string;
    result?: string;
    memo?: string;
  }>;
}

export const Alipay = registerPlugin<AlipayPlugin>('Alipay');

业务代码只负责从服务端获取订单并调用插件:

async function startAlipay(orderId: string) {
  const response = await fetch('/api/payments/alipay/app-order', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ orderId }),
  });

  if (!response.ok) {
    throw new Error('创建支付宝订单失败');
  }

  const { orderString } = await response.json();

  const sdkResult = await Alipay.pay({ orderString });

  // 此结果仅用于更新界面,不作为最终入账依据。
  return sdkResult;
}

服务端接口不能把客户端提交的最终金额当作可信数据。服务端应通过 orderId 查询商品价格、优惠和实际应付金额,再生成支付宝订单。

Android 原生桥接思路

Android 端通常会调用官方 SDK 的 PayTask。下面的代码只展示桥接结构,具体注解、依赖配置和线程 API 需要根据项目当前使用的 Capacitor 版本调整:

@CapacitorPlugin(name = "Alipay")
public class AlipayPlugin extends Plugin {

    @PluginMethod
    public void pay(PluginCall call) {
        String orderString = call.getString("orderString");

        if (orderString == null || orderString.isEmpty()) {
            call.reject("orderString is required");
            return;
        }

        getActivity().runOnUiThread(() -> {
            try {
                PayTask payTask = new PayTask(getActivity());
                Map<String, String> result = payTask.payV2(orderString, true);

                JSObject data = new JSObject();
                data.put("resultStatus", result.get("resultStatus"));
                data.put("result", result.get("result"));
                data.put("memo", result.get("memo"));

                call.resolve(data);
            } catch (Exception e) {
                call.reject("Alipay SDK invocation failed", e);
            }
        });
    }
}

Android SDK 应从支付宝官方文档指定的渠道获取,依赖、混淆规则和必要权限也应按照官方说明配置。不要从多年未维护的插件仓库中复制来源不明的 .aar 或 .jar 文件。

支付调用可能阻塞当前线程。实际开发时,应根据官方 SDK 的调用要求和当前 Capacitor 版本,把耗时操作放到合适的执行线程,避免阻塞 UI。

iOS 原生桥接思路

iOS 端一般通过官方 AlipaySDK 调起支付。下面同样只展示桥接结构:

import Capacitor
import AlipaySDK

@objc(AlipayPlugin)
public class AlipayPlugin: CAPPlugin, CAPBridgedPlugin {
    public let identifier = "AlipayPlugin"
    public let jsName = "Alipay"
    public let pluginMethods: [CAPPluginMethod] = [
        CAPPluginMethod(name: "pay", returnType: CAPPluginReturnPromise)
    ]

    @objc func pay(_ call: CAPPluginCall) {
        guard let orderString = call.getString("orderString"),
              !orderString.isEmpty else {
            call.reject("orderString is required")
            return
        }

        let scheme = "your-app-url-scheme"

        AlipaySDK.defaultService().payOrder(
            orderString,
            fromScheme: scheme
        ) { result in
            call.resolve([
                "resultStatus": result?["resultStatus"] as? String ?? "",
                "result": result?["result"] as? String ?? "",
                "memo": result?["memo"] as? String ?? ""
            ])
        }
    }
}

your-app-url-scheme 必须替换成应用实际使用的 URL Scheme,并与支付宝开放平台和 iOS 工程中的配置保持一致。

不同 Capacitor 版本的插件注册方式可能不同。支付宝 iOS SDK 的导入方式、方法签名和回调处理,也应以接入时的官方文档为准。这段代码用于说明桥接边界,不能替代项目所用版本的官方配置说明。

Cordova 项目如何处理

Cordova 的整体方案相同,区别主要在于 JavaScript 桥接形式:

cordova.exec(
  function success(result) {
    console.log('Alipay SDK result:', result);
  },
  function failure(error) {
    console.error('Alipay invocation failed:', error);
  },
  'Alipay',
  'pay',
  [{ orderString }]
);

对应的 Android 和 iOS 原生插件需要分别实现 pay 动作。对于没有既有 Cordova 依赖的新项目,通常可以优先考虑 Capacitor,其原生工程更便于直接接入和升级官方 SDK。已有 Cordova 项目则不必仅为支付功能强制迁移。

如何评估第三方插件

如果不打算自行维护桥接层,也可以筛选社区插件,但至少需要检查以下内容:

  • 仓库是否公开完整源码;
  • 最近是否仍有提交和版本发布;
  • 是否支持项目当前使用的 Capacitor、Cordova、Android Gradle Plugin 和 Xcode;
  • Android 和 iOS SDK 是否来自支付宝官方发布渠道;
  • 仓库中是否直接打包了过时的 SDK 二进制文件;
  • 是否要求把应用私钥、支付宝私钥或签名逻辑放进客户端;
  • 是否包含无关网络请求、统计 SDK 或动态代码下载;
  • 是否正确处理 URL Scheme、生命周期和重复回调;
  • 是否提供明确的许可证、安全说明和升级记录;
  • 支付宝 SDK 更新后,项目团队是否有能力自行维护 fork。

如果插件要求把应用私钥保存在 Ionic 代码、资源文件或原生工程中,就不应采用。

支付结果不能只看客户端回调

支付宝 App 返回的 resultStatus 可以帮助客户端改善交互,例如显示“处理中”或触发订单查询,但不能直接作为发货、充值或开通服务的依据。

支付结果应按以下流程处理:

  1. 支付宝向服务端发送异步通知。
  2. 服务端按照官方规则验证通知签名。
  3. 校验 app_id、商户订单号、金额、卖家身份等关键字段。
  4. 通过幂等事务更新本地订单。
  5. 客户端向业务服务端查询订单的最终状态。

即使客户端显示支付成功,也要等待服务端确认。客户端可能被篡改,回调也可能被伪造,支付过程中还可能遇到超时、通知延迟或应用切换失败。

实际选型建议

对于需要长期维护或涉及较高交易金额的应用,建议自行封装内部插件。支付桥接本身通常只有少量代码,后续维护主要集中在官方 SDK、平台配置和服务端验签。内部封装能锁定依赖来源,也便于审计和升级。

如果使用社区插件,最好将其固定在经过审计的提交或版本上,并保留自己的 fork。上线前至少要完成 Android 和 iOS 真机测试,并验证支付成功、取消、失败、重复通知、应用被系统终止及网络中断等场景。

选型时不必执着于寻找名称上“权威”的跨端插件。更重要的是确认底层使用支付宝官方原生 SDK、私钥只保存在服务端、插件源码可以审计,并且团队能够持续维护和升级。

备注:内容仅供参考。