PAYATHON 2026

如何在 iOS 项目中按正确步骤集成 Alipay?

支付小周

结论

iOS 接入支付宝支付,一般按以下流程完成:

  1. 在支付宝开放平台创建应用并开通支付能力。
  2. 配置应用公钥、签名方式和服务端异步通知地址。
  3. 将支付宝官方 iOS SDK 加入项目。
  4. 配置独立的 URL Scheme。
  5. 由服务端创建支付订单,并使用 RSA2 签名。
  6. 客户端调用 AlipaySDK 发起支付。
  7. 在应用的回调入口处理支付宝返回。
  8. 服务端验证异步通知的签名,并以服务端查询结果或异步通知为最终支付依据。

接入时常见的问题包括:在客户端保存商户私钥或生成签名、URL Scheme 配置不一致、遗漏回调处理,以及直接将客户端返回结果视为支付成功。

一、准备支付宝开放平台配置

先在支付宝开放平台创建应用,并确认应用已获得所需支付产品的权限。通常需要准备:

  • app_id
  • 商户签约信息
  • RSA2 密钥对
  • 应用公钥或支付宝公钥配置
  • 服务端异步通知地址 notify_url
  • 支付宝 iOS SDK

支付产品、账号类型或 SDK 版本不同,配置入口也可能不同。具体应以当前支付宝开放平台控制台和相应产品文档为准。

配置密钥时,需要区分以下三项:

  • 商户应用私钥:只保存在服务端,用于订单签名。
  • 应用公钥:上传到支付宝开放平台。
  • 支付宝公钥:保存在服务端,用于验证支付宝通知签名。

不要将商户应用私钥打包进 iOS 应用。IPA 可以被分析,私钥一旦泄露,攻击者可能伪造签名请求。

二、集成官方 iOS SDK

从支付宝开放平台下载与当前支付产品对应的 iOS SDK,再按照 SDK 包中的接入说明导入项目。常见做法是添加官方提供的 framework、xcframework、静态库和资源文件。

导入后检查以下配置:

  • SDK 是否加入了正确的 Target。
  • Framework Search Paths 或相关构建路径是否正确。
  • SDK 要求的系统依赖库是否已经链接。
  • Objective-C 项目能否导入对应头文件。
  • Swift 项目是否已通过模块导入或 Bridging Header 使用 SDK。

Objective-C 项目通常采用类似下面的导入方式:

#import <AlipaySDK/AlipaySDK.h>

如果当前 SDK 的模块名或头文件路径与示例不同,应使用下载包中实际提供的名称,不要直接套用旧版本示例。

三、配置 URL Scheme

支付宝 App 支付完成后,会通过 URL Scheme 返回商户应用。

在 Xcode 中打开:

Target
→ Info
→ URL Types

添加一个 URL Type,并设置唯一的 URL Scheme,例如:

com.example.myapp.alipay

建议使用反向域名形式,以免与其他应用冲突。代码传给支付宝 SDK 的 Scheme 必须与此处配置完全一致,大小写也要相同。

还可以直接检查 Info.plist 是否包含对应配置:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>com.example.myapp.alipay</string>
        </array>
    </dict>
</array>

如果 SDK 需要通过 canOpenURL: 检查支付宝客户端,可能还要在 LSApplicationQueriesSchemes 中添加官方文档指定的 Scheme。该列表可能随 SDK 版本变化,应以当前 SDK 接入文档为准,不要根据旧示例随意添加。

四、在服务端创建并签名订单

用户在客户端点击支付后,客户端应先向业务服务器请求支付参数:

iOS App → 业务服务器 → 支付宝

服务端负责:

  1. 创建业务订单。
  2. 生成唯一的商户订单号。
  3. 组装支付宝支付请求参数。
  4. 使用商户应用私钥执行 RSA2 签名。
  5. 将完整的支付订单字符串返回给 iOS 客户端。

客户端接口可以返回以下格式:

{
  "orderString": "app_id=...&biz_content=...&sign=...&sign_type=RSA2..."
}

服务端还要自行校验金额、商品信息和用户身份,不能直接信任客户端提交的金额。例如,客户端只提交商品 ID 和数量,实际支付金额由服务端根据数据库计算。

以下操作不应放在客户端:

生成商户订单号
决定最终金额
保存商户私钥
执行 RSA2 签名

这些操作都应在可信的服务端环境中完成。

五、客户端发起支付

取得服务端返回的完整 orderString 后,即可调用支付宝 SDK。

Objective-C 示例

#import <AlipaySDK/AlipaySDK.h>

- (void)startAlipayWithOrderString:(NSString *)orderString {
    if (orderString.length == 0) {
        return;
    }

    NSString *scheme = @"com.example.myapp.alipay";

    [[AlipaySDK defaultService] payOrder:orderString
                             fromScheme:scheme
                               callback:^(NSDictionary *resultDic) {
        NSLog(@"Alipay result: %@", resultDic);

        NSString *resultStatus = resultDic[@"resultStatus"];
        [self handleAlipayResultStatus:resultStatus];
    }];
}

- (void)handleAlipayResultStatus:(NSString *)resultStatus {
    if ([resultStatus isEqualToString:@"9000"]) {
        // SDK 返回支付完成,但仍需向业务服务器确认最终订单状态
        [self queryOrderStatusFromServer];
    } else if ([resultStatus isEqualToString:@"6001"]) {
        // 用户取消支付
    } else {
        // 支付失败、处理中或其他状态
        [self queryOrderStatusFromServer];
    }
}

payOrder:fromScheme:callback: 是常见 SDK 版本中的接口。如果所用 SDK 的公开方法签名不同,应以该版本的头文件和官方示例为准。

客户端回调通常包含 resultStatus、result 和 memo 等字段,但业务代码不能仅凭某个状态码直接发货。收到回调后,应尽快调用自己的订单查询接口,确认服务端记录的订单状态。

六、处理支付宝返回应用的回调

使用 AppDelegate

通过 AppDelegate 接收 URL 的项目,可以这样处理:

#import <AlipaySDK/AlipaySDK.h>

- (BOOL)application:(UIApplication *)app
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {

    if ([url.host isEqualToString:@"safepay"]) {
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url
                                                  standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"Alipay callback: %@", resultDic);

            // 回到业务服务器查询订单状态
            [self queryOrderStatusFromServer];
        }];
    }

    return YES;
}

部分旧项目还要实现旧版 URL 回调方法:

- (BOOL)application:(UIApplication *)application
             openURL:(NSURL *)url
   sourceApplication:(NSString *)sourceApplication
          annotation:(id)annotation {

    if ([url.host isEqualToString:@"safepay"]) {
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url
                                                  standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"Alipay callback: %@", resultDic);
        }];
    }

    return YES;
}

是否需要实现旧方法,取决于项目支持的 iOS 版本和生命周期配置。

使用 SceneDelegate

启用 Scene 生命周期的项目,还要在 SceneDelegate 中接收 URL:

#import <AlipaySDK/AlipaySDK.h>

- (void)scene:(UIScene *)scene
openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts API_AVAILABLE(ios(13.0)) {

    NSURL *url = URLContexts.allObjects.firstObject.URL;
    if (url == nil) {
        return;
    }

    if ([url.host isEqualToString:@"safepay"]) {
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url
                                                  standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"Alipay scene callback: %@", resultDic);

            // 查询服务端订单状态
        }];
    }
}

如果项目同时支持不同的 iOS 生命周期,需要确认实际生效的入口已经实现。支付可以正常跳转到支付宝,却无法返回应用时,通常应检查 Scheme 和回调入口配置。

七、服务端处理异步通知

支付宝会向配置的 notify_url 发送服务端异步通知。服务端收到通知后,至少要完成以下处理:

  1. 使用支付宝公钥验证签名。
  2. 检查通知中的 app_id、商户号等身份信息。
  3. 检查商户订单号是否存在。
  4. 核对订单金额、币种和商品信息。
  5. 判断订单是否已经处理,保证接口幂等。
  6. 更新订单状态。
  7. 按支付宝协议返回正确响应。

处理流程可以写成:

收到支付宝通知
    ↓
验证 RSA2 签名
    ↓
检查 app_id、订单号、金额
    ↓
检查订单是否已经支付
    ↓
以事务方式更新订单状态
    ↓
返回协议要求的成功响应

同一条通知可能被重复发送,因此不能每收到一次通知就再次发货。可以通过订单状态、唯一索引或数据库事务实现幂等处理。

八、不要只依赖客户端回调

客户端回调可能因以下情况而丢失或失真:

  • 用户支付后直接结束应用。
  • 网络在返回应用时中断。
  • App 没有收到 URL 回调。
  • 回调到达时应用发生崩溃。
  • 客户端回调内容被篡改。
  • 支付结果仍处于处理中。

最终判断流程应为:

客户端回调
    ↓
提示用户支付结果正在确认
    ↓
向业务服务器查询订单
    ↓
业务服务器根据异步通知或支付宝查询接口确认状态
    ↓
展示最终结果

只有业务服务器确认订单支付成功后,才能发货、开通会员或增加余额。

九、常见排查点

如果仍然无法唤起支付宝,可以依次检查:

  • SDK 是否正确加入当前 Target。
  • 服务端返回的 orderString 是否完整。
  • orderString 是否被重复 URL 编码或错误转义。
  • app_id 是否与开放平台中的应用一致。
  • RSA2 签名使用的私钥是否与上传的应用公钥匹配。
  • 应用是否已经签约并开通对应支付产品。
  • URL Scheme 是否已经写入 Info.plist。
  • fromScheme 是否与项目配置完全一致。
  • 真机是否安装了支付宝客户端。
  • 当前 SDK 是否支持项目使用的 Xcode 和 iOS 版本。
  • 使用 Scene 生命周期时,是否遗漏了 SceneDelegate 回调。
  • 服务端和客户端是否混用了测试环境、沙箱环境与正式环境。

如果能够跳转到支付宝,但支付完成后无法返回应用,应重点检查 URL Scheme 和 URL 回调方法。如果支付宝立即提示订单错误,则要检查服务端订单参数、签名、公钥配置和支付产品权限。

注意事项

  • 必须使用 HTTPS 与业务服务器通信。
  • 商户私钥只能保存在服务端。
  • 日志中不要输出私钥、完整签名或用户敏感信息。
  • 商户订单号必须唯一。
  • 金额应由服务端计算并再次校验。
  • 客户端状态码只能用于提示用户,不能作为最终账务依据。
  • 服务端收到异步通知后必须验签,并进行幂等处理。
  • SDK 方法、系统依赖和回调配置可能随版本变化,应以所下载 SDK 的头文件和当期官方接入文档为准。

备注:内容仅供参考。