Skip to content
开发者工具
使用AI助手和工具加速开发

SDK-Apple pay

注意:

需申请开通
如需使用该功能,请提前联系您的 BD/AM 或技术支持团队申请开通。

客户端SDK模式专为原生iOS应用程序设计。通过 PayerMax Apple Pay SDK,您可以在 iOS App 中提供原生的 Touch ID / Face ID 支付体验,同时无需自行处理 Apple Pay Token 的复杂解密工作。PayerMax 后端代您完成解密与收单,您只需极少量的 Swift 代码即可完成完整的支付闭环。 在开始之前,您需要已加入Apple Developer Program

1. 交互流程

商户 App、商户服务端、PayerMax SDK、Apple PassKit 以及 PayerMax 后端的交互时序如下:

%%{init: {
  'theme': 'base',
  'themeVariables': {
    'primaryColor': '#e6f0ff',
    'primaryTextColor': '#333',
    'primaryBorderColor': '#5b9bd5',
    'lineColor': '#888',
    'actorMargin': 40,
    'noteBkgColor': '#0056b3',
    'noteTextColor': '#ffffff',
    'noteBorderColor': '#004a99'
  }
}}%%
sequenceDiagram
    participant App as 商户App
    participant MerchantServer as 商户服务端
    participant PMSDK as PayerMax SDK
    participant PassKit
    participant PMBackend as PayerMax后端

    %% 流程步骤
    App->>MerchantServer: 请求创建订单
    MerchantServer->>PMBackend: 调用 /applyApplePaySession(金额/币种/国家)
    PMBackend-->>MerchantServer: amount / currency / country / merchantId / networks / orderToken
    MerchantServer-->>App: 返回订单参数(amount/currency/country/merchantId/networks/orderToken)
    App->>PMSDK: present(PKPaymentRequest)
    PMSDK->>PassKit: 弹出 Apple Pay 面板
    PassKit-->>PMSDK: didAuthorize(PKPayment 加密 token)
    PMSDK->>PMBackend: POST /orderAndPay (含 orderToken 及加密 payload)
    PMBackend-->>PMSDK: 收单结果(成功/失败)
    PMSDK-->>App: completion(result)

2. 接入前步骤

在开始编写代码之前,您需要完成 Apple 侧的资产配置,并与 PayerMax 交换必要的证书。以下配置是启动 Apple Pay 的前提。

2.1 创建商户 IDs

登录 Apple Developer 网站,在 Certificates,Identifiers & Profiles -> Identifiers -> Merchant IDs 页面中注册一个新的 Merchant ID。该 ID 用于唯一标识您的商户身份,并在 Apple Pay 的加密流程中扮演关键角色。 在表单中填写描述和标识符。描述内容仅供您自己记录之用,之后可随时更改。PayerMax 建议用您的应用程序的名称作为标识符(例如,merchant.com.{{YOUR_APP_NAME}})。

2.2 配置 Payment Processing Certificate

为您的应用创建证书,以加密支付数据。PayerMax 采用后端自持解密方案,即由 PayerMax 后端持有私钥并负责解密 Apple Pay Token,商户客户端无需接触任何私钥。 配置步骤如下:

  1. 联系 PayerMax 技术支持,获取专属的 Certificate Signing Request(CSR)文件。
  2. Apple Develope 后台,使用 PayerMax 提供的 CSR 文件为您的 Merchant ID 生成 Payment Processing Certificate。
  3. 将生成的证书文件(.cer)提交给 PayerMax,由 PayerMax 后端完成导入与配置。

注意:
请务必使用 PayerMax 提供的 CSR 文件生成证书,而非自行生成 CSR。一个 CSR 文件只能签发一张证书。如果您更换了 Apple Merchant ID,则必须重新联系 PayerMax 技术支持获取新的 CSR 和证书。

3. 接口介绍

3.1 接口列表

关联步骤调用方向接口类型接口 PATH
4.3 创建付款请求商户服务端 -> PayerMax后端接口/applyApplePaySession
4.4 出示支付表单与提交付款SDK -> PayerMax后端接口/orderAndPay
4.5 获取支付结果PayerMax -> 商户后端接口/collectResultNotifyUrl

3.2 环境信息

  • 测试环境:https:// pay-gate-uat.payermax.com/aggregate-pay/api/gateway/ <接口PATH>

  • 集成环境:https:// pay-gate.payermax.com/aggregate-pay/api/gateway/ <接口PATH>

3.3 请求 Header

json
{
  "Accept": "application/json",
  "sign": "请参考签名规则:https://docs-v2.payermax.com/202606-version/developer/config-settings.html",
  "Content-Type": "application/json"
}

4. 开始集成

4.1 获取 SDK

PayerMax 推荐使用现代的依赖管理工具来引入 Apple Pay SDK ,支持 Swift Package Manager (SPM) 和 CocoaPods 两种方式。

1. Swift Package Manager (SPM)

在 Xcode 中,选择 File > Add Package Dependencies...,输入以下仓库地址,然后选择最新的版本号,并将 PayerMaxApplePay 模块添加到您的应用程序目标(Target)中:

plain
https://github.com/payermax/payermax-ios-sdk

2. CocoaPods

在您的 Podfile 中添加以下依赖 ,然后运行 pod install

ruby
pod 'PayerMax/ApplePay'

4.2 集成 Xcode 与配置能力

在 Xcode 中,打开您的项目设置,选择目标(Target),然后点击 Signing & Capabilities 选项卡。点击左上角的 + Capability,在弹出的列表中搜索并添加 Apple Pay 功能。

在 Apple Pay 配置区域,勾选您在第 2.1 步中创建的 Merchant ID。这一步会将 Merchant ID 写入应用程序的 entitlement 文件中,使您的应用程序具备拉起 Apple Pay 的权限。

4.3 初始化配置与检查可用性

在您的应用程序启动时(例如在 AppDelegate 中),使用您在 PayerMax 商户后台获取的 Publishable Key 完成 SDK 初始化。在向用户展示 Apple Pay 按钮之前,调用 PMApplePayConfiguration.canMakePayments() 验证当前设备是否支持 Apple Pay 且用户已绑卡。

swift
import UIKit
import PayerMaxApplePay
import PassKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

        // 使用您在 PayerMax 商户后台获取的 Publishable Key 完成 SDK 初始化
        PMAPIClient.defaultPublishableKey = "your_publishable_key"

        return true
    }
}

class CheckoutViewController: UIViewController {
    let applePayButton = PKPaymentButton(paymentButtonType: .buy, paymentButtonStyle: .black)

    override func viewDidLoad() {
        super.viewDidLoad()

        // 仅在设备支持 Apple Pay 且用户已绑卡时展示按钮
        if PMApplePayConfiguration.canMakePayments() {
            applePayButton.addTarget(self, action: #selector(handleApplePayButtonTapped), for: .touchUpInside)
            view.addSubview(applePayButton)
        }
    }
}

4.4 发起支付请求与处理结果

当用户点击 Apple Pay 按钮时,商户 App 先请求自己的服务端创建订单;商户服务端调用 PayerMax 的 /applyApplePaySession 接口,获取 amountcurrencymerchantIdnetworks 等支付参数以及 orderToken 后返回给 App。

App 拿到参数后,调用 PMApplePayConfiguration.paymentRequest 构造 PKPaymentRequest,再通过 PMApplePayContext 展示原生 Apple Pay 面板。用户通过 Face ID 或 Touch ID 授权后,SDK 自动将加密 Token 连同 orderToken 上送至 PayerMax 后端的 /orderAndPay 接口完成收单确认,最终通过 delegate 回调将结果返回给商户 App。

服务端

商户服务端需提供一个接口,内部调用 PayerMax /applyApplePaySession,并将订单参数返回给客户端:

json
// POST /applyApplePaySession 请求示例
{
  "version": "1.5",
  "keyVersion": "1",
  "requestTime": "2025-05-14T16:30:27.174+08:00",
  "appId": "your_app_id",
  "merchantNo": "your_merchant_no",
  "data": {
    "outTradeNo": "your_order_id",
    "totalAmount": 50.00,
    "currency": "USD",
    "country": "US",
    "userId": "your_user_id",
    "subject": "Your Order Subject"
  }
}
json
// 响应示例
{
  "code": "APPLY_SUCCESS",
  "msg": "Success.",
  "data": {
    "amount": "50.00",
    "currency": "USD",
    "country": "US",
    "merchantId": "merchant.com.yourcompany.yourapp",
    "networks": ["visa", "masterCard", "amex"],
    "orderToken": "T2025051210335071234567"
  }
}

客户端

swift
@objc func handleApplePayButtonTapped() {
    // 从您的服务端获取订单参数
    // 您的服务端负责调用 PayerMax /applyApplePaySession 接口并将结果返回给 App
    fetchOrderParamsFromYourServer { [weak self] result in
        guard let self = self else { return }
        switch result {
        case .success(let orderParams):
            // orderParams 包含服务端返回的 amount、currency、country、merchantId、networks、orderToken
            let paymentRequest = PMApplePayConfiguration.paymentRequest(
                withMerchantIdentifier: orderParams.merchantId, // 来自服务端
                country: orderParams.country,                   // 来自服务端
                currency: orderParams.currency                  // 来自服务端
            )

            // 配置付款请求上的摘要行
            // 最后一行应代表您的公司;它将以"Pay"一词开头(即"Pay Your Company $50")
            // 金额来自服务端,不得由客户端自行决定
            paymentRequest.paymentSummaryItems = [
                PKPaymentSummaryItem(
                    label: "Your Company Name",
                    amount: NSDecimalNumber(string: orderParams.amount) // 来自服务端
                )
            ]

            // 保存 orderToken 供后续 /orderAndPay 使用
            self.orderToken = orderParams.orderToken

            // 初始化 PMApplePayContext 并展示 Apple Pay 面板
            // 注意:present 必须由用户手势直接触发,不能在异步操作后延迟调用
            if let applePayContext = PMApplePayContext(
                paymentRequest: paymentRequest,
                delegate: self
            ) {
                applePayContext.presentApplePay(on: self)
            } else {
                print("初始化 Apple Pay 失败,请检查 Merchant ID 配置")
            }

        case .failure(let error):
            print("获取订单参数失败: \(error.localizedDescription)")
        }
    }
}

// MARK: - PMApplePayContextDelegate

extension CheckoutViewController: PMApplePayContextDelegate {

    // 用户授权后,SDK 回调此方法,您需要返回服务端的 orderToken 用于后续 /orderAndPay
    func applePayContext(
        _ context: PMApplePayContext,
        didCreatePaymentMethod paymentMethod: PMPaymentMethod,
        paymentInformation: PKPayment
    ) async throws -> String {
        // 返回创建订单时服务端下发的 orderToken
        // SDK 将携带此 token 及加密 payload 自动调用 PayerMax /orderAndPay
        return self.orderToken
    }

    // 支付完成后,SDK 回调此方法,status 为最终支付结果
    func applePayContext(
        _ context: PMApplePayContext,
        didCompleteWith status: PMApplePayContext.PaymentStatus,
        error: Error?
    ) {
        switch status {
        case .success:
            // 支付成功,展示订单确认页面
            print("支付成功")
        case .error:
            // 支付失败,展示错误提示
            print("支付失败: \(error?.localizedDescription ?? "")")
        case .userCancellation:
            // 用户主动取消
            break
        @unknown default:
            break
        }
    }
}

说明:金额应始终由服务端决定,客户端仅负责展示。请勿在客户端硬编码金额,以防止恶意篡改。/orderAndPay 由 SDK 在用户授权后自动调用,商户无需手动处理。

4.5 获取支付结果

PMApplePayContextDelegatedidCompleteWith 回调中的 .success 状态表明 PayerMax 后端已完成收单确认。除此之外,PayerMax 还会通过异步 Webhook 通知向您的服务端推送最终的支付结果。 建议您同时监听 Webhook 通知,而不是仅依赖客户端回调,以确保在用户关闭应用程序等异常场景下也能可靠地获取支付状态。详情请查看支付结果-支付结果通知

5. 测试与上线

5.1 沙盒测试

Apple Pay 的测试需要使用专门的沙盒环境。您无法将普通测试卡添加到真机的 Apple 钱包中,需要按照以下步骤进行配置:

  1. Apple Developer 网站创建一个沙盒测试账号(Sandbox Tester)。
  2. 在测试 iPhone 或 iPad 上,前往 设置 > App Store,使用沙盒测试账号登录。
  3. 前往 设置 > 钱包与 Apple Pay,使用 Apple 提供的测试卡号添加一张测试卡。
  4. 在 SDK 初始化时,使用测试环境的 Publishable Key:
swift
// 测试环境初始化
PMAPIClient.defaultPublishableKey = "your_test_publishable_key"

注意:在测试环境中,127.0.0.1、局域网 IP、localhost 都无法拉起 Apple Pay,需要放在带有 SSL 证书的 HTTPS 域名下。

5.2 切换生产环境

测试完成后,将 Publishable Key 替换为生产环境的值即可完成上线切换:

swift
// 生产环境初始化
PMAPIClient.defaultPublishableKey = "your_live_publishable_key"

6. 常见问题排查

如果在集成过程中遇到问题,请优先参考下表中的常见原因与解决方案。

错误现象可能原因解决方案
ApplePay面板无法弹出MerchantID配置不匹配检查Xcode的ApplePayCapability中勾选的MerchantID,是否与服务端 /applyApplePaySession 返回的 merchantId 完全一致。
ApplePay面板无法弹出设备未绑卡或不支持Apple Pay确认 PMApplePayConfiguration.canMakePayments() 返回 true
若返回 false,请检查测试设备是否已在钱包中添加了沙盒测试卡。
后端返回Token解密失败使用了错误的CSR生成证书确保您在Apple Developer后台使用的是PayerMax提供的CSR文件,而非自行生成的CSR。如有疑问,请联系PayerMax技术支持重新获取CSR。
Xcode中ApplePay配置失效Xcode缓存了旧的证书信息在Xcode中关闭并重新打开ApplePay Capability(先取消勾选MerchantID,保存后再重新勾选),以强制刷新 entitlement 配置。
支付金额显示异常客户端金额与服务端不一致请确保 paymentSummaryItems 中的金额与服务端 /applyApplePaySession 接口返回的订单金额严格一致,否则可能导致支付失败或风控拦截。
网络重试导致重复扣款未正确处理幂等性SDK内部已将Apple返回的 transactionIdentifier 作为幂等键(Idempotency-Key)传递给PayerMax后端。请确认您的服务端已正确处理该幂等键,以防止重复扣款。

此页面的内容有帮助吗?

感谢您帮助改进 PayerMax 产品文档!

Released under the MIT License.