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 接口,获取 amount、currency、merchantId、networks 等支付参数以及 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 获取支付结果 ​

PMApplePayContextDelegate 的 didCompleteWith 回调中的 .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.