# Apple Pay

允许客户在他们的 iPhone、iPad 或 Apple Watch 上用 Apple Pay 安全地付款。

参考 Apple 的[兼容性文档](https://support.apple.com/en-us/HT208531)，了解哪些设备支持 Apple Pay。

Apple Pay 与大多数 Stripe 产品和功能兼容。Stripe 用户可以在 iOS 9 及更高版本的 iOS 应用程序以及 iOS 10 或 macOS Sierra 及以上版本的 Safari 网页上接受 [Apple Pay](https://stripe.com/apple-pay)。处理 Apple Pay 付款时没有额外费用，[定价](https://stripe.com/pricing/local-payment-methods#apple-pay)与其他银行卡交易一样。

Apple Pay 可由在受支持国家的参与银行那里开户的持卡人使用。有关更多信息，请参考 Apple 的[参与银行](https://support.apple.com/en-us/ht204916)文档。

#### 支付方式属性

- **客户所在地**

  印度以外的全球

- **出示货币**

  参见[受支持的出示货币](https://docs.stripe.com/currencies.md#presentment-currencies)

- **支付确认**

  客户发起

- **支付方式类型**

  钱包

- **经常性付款**

  [是](https://docs.stripe.com/apple-pay.md#recurring-payments)

- **提现时间**

  适用标准提现时间

- **Connect 支持**

  是

- **争议支持**

  [是](https://docs.stripe.com/apple-pay/disputes-refunds.md#disputed-payments)

- **手动捕获支持**

  是

- **退款/部分退款**

  [是 / 是](https://docs.stripe.com/apple-pay/disputes-refunds.md#refunds)

#### 商家所在地

除印度外，全球的 Stripe 账户都可以用本国结算货币接受 Apple Pay 付款。

#### 产品支持

- Connect
- Checkout1

- Payment Links
- Elements
- Subscriptions
- Invoicing

1当 Checkout 的 [ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) 为 `embedded_page` 时，它仅支持 Safari 和 iOS 的 17 或更高版本。

## 付款流程

以下是您的结账页面的 Apple Pay 付款流程演示：
![Apple Pay 付款流程动画显示 Stripe 结账页面、Apple Pay 按钮和测试时的确认对话框。](https://b.stripecdn.com/docs-statics-srv/assets/apple-pay.3447ce2deeaab40d6d231eed4dc34644.gif)

## Apple Pay 的应用内购买资格

本指南将说明如何配置您的应用，使其可直接通过 Apple Pay 接收实体商品、服务及其他符合条件商品的付款。Stripe 会处理这些支付交易，您只需支付 Stripe 的[手续费](https://stripe.com/pricing)即可。

对于在美国或欧洲经济区 (EEA) 销售的数字产品、内容及订阅服务，您的应用可通过跳转至外部支付页面的方式接收 Apple Pay 付款。您可使用以下支付用户界面：

- [Stripe Checkout](https://docs.stripe.com/mobile/digital-goods/checkout.md)
- [Web Elements](https://docs.stripe.com/mobile/digital-goods/custom-checkout.md)
- [Payment Links](https://docs.stripe.com/mobile/digital-goods/payment-links.md)（最适合产品和定价数量有限的场景）

在其他地区，您的应用无法通过 Apple Pay 接收数字产品、内容或订阅服务相关款项。

## 接受 Apple Pay

Stripe 提供了多种添加 Apple Pay 的方法。有关集成的详细信息，请选择您最喜欢的方法：

# Native iOS

> This is a Native iOS for when platform is ios. View the full page at https://docs.stripe.com/apple-pay?platform=ios.

> 如果您使用的是 Stripe [预构建用户界面](https://docs.stripe.com/payments/mobile.md)，请改为遵循[本指南](https://docs.stripe.com/payments/mobile/accept-payment.md?platform=ios&type=payment#apple-pay)中的步骤。

通过 [Stripe iOS SDK](https://github.com/stripe/stripe-ios)，您可以接受 Apple Pay 及传统的信用卡支付方式。开始之前，您需要注册 [Apple Developer Program](https://developer.apple.com/programs/)。接下来，执行这些步骤：

1. [设置 Stripe](https://docs.stripe.com/apple-pay.md#setup)
1. [注册 Apple Merchant ID](https://docs.stripe.com/apple-pay.md#merchantid)
1. [创建新的 Apple Pay 证书](https://docs.stripe.com/apple-pay.md#csr)
1. [用 Xcode 集成](https://docs.stripe.com/apple-pay.md#xcode-pay)
1. [检查是否支持 Apple Pay](https://docs.stripe.com/apple-pay.md#check-if-apple-pay-supported)
1. [创建付款请求](https://docs.stripe.com/apple-pay.md#create-payment-request)
1. [出示支付表单](https://docs.stripe.com/apple-pay.md#present-payment-sheet)
1. [向 Stripe 提交付款](https://docs.stripe.com/apple-pay.md#handle-payment)

## 设置 Stripe [服务器端] [客户端]

首先，您需要有 Stripe 账户。[立即注册](https://dashboard.stripe.com/register)。

### 服务器端

该集成要求您的服务器上的端点与 Stripe API 通讯。请用官方库从您的服务器访问 Stripe API：

#### Ruby

```bash
# Available as a gem
sudo gem install stripe
```

```ruby
# If you use bundler, you can add this line to your Gemfile
gem 'stripe'
```

### 客户端

[Stripe iOS SDK](https://github.com/stripe/stripe-ios) 是开源的，[有完整的文档](https://stripe.dev/stripe-ios/index.html)，并且与支持 iOS 13 或更高版本操作系统的应用程序兼容。

#### Swift Package Manager

要安装 SDK，按这些步骤进行：

1. 在 Xcode 中，选择**文件** > **添加工具包依赖…**并输入 `https://github.com/stripe/stripe-ios-spm` 作为仓库 URL。
1. 从我们的[发布页面](https://github.com/stripe/stripe-ios/releases)选择最新的版本号。
1. 将 **StripeApplePay** 产品添加到[您的目标应用程序](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app)。

#### CocoaPods

1. 如果您还没有[CocoaPods](https://guides.cocoapods.org/using/getting-started.html)，请安装其最新版本。
1. 如果您目前没有 [Podfile](https://guides.cocoapods.org/syntax/podfile.html)，请运行以下命令创建一个：
   ```bash
   pod init
   ```
1. 将这一行代码添加到您的 `Podfile`：
   ```podfile
   pod 'StripeApplePay'
   ```
1. 运行以下命令：
   ```bash
   pod install
   ```
1. 今后，一定记得用 `.xcworkspace` 文件来打开您在 Xcode 中的项目，不要使用 `.xcodeproj` 文件。
1. 将来，要更新到 SDK 的最新版本，运行：
   ```bash
   pod update StripeApplePay
   ```

#### Carthage

1. 如果您还没有[Carthage](https://github.com/Carthage/Carthage#installing-carthage)，请安装其最新版本。
1. 将这一行代码添加到您的 `Cartfile`。
   ```cartfile
   github "stripe/stripe-ios"
   ```
1. 按照 [Carthage 安装说明](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos)进行。确保嵌入[这里](https://github.com/stripe/stripe-ios/tree/master/StripeApplePay/README.md#manual-linking)所列的所有必要框架。
1. 将来，要更新到 SDK 的最新版本，运行以下命令即可：
   ```bash
   carthage update stripe-ios --platform ios
   ```

#### 手动框架

1. 前往我们的 [GitHub 发布页面](https://github.com/stripe/stripe-ios/releases/latest)，下载并解压缩 **Stripe.xcframework.zip**。
1. 将 **StripeApplePay.xcframework** 拖拽到您的 Xcode 项目中 **General**（常规）设置的 **Embedded Binaries**（嵌入式二进制文件）部分。一定要选择 **Copy items if needed**（需要时复制项目）。
1. 为[这里](https://github.com/stripe/stripe-ios/tree/master/StripeApplePay/README.md#manual-linking)所列的所有必要框架重复第 2 步。
1. 将来，要更新到 SDK 的最新版本，重复第 1-3 步。

> 有关最新 SDK 发布及过往版本的详细信息，请查看 GitHub 上的[发布](https://github.com/stripe/stripe-ios/releases)页面。要想在新版本发布时接收通知，请[查看仓库的发布](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository)。

在应用程序启动时使用您的 Stripe [公钥](https://dashboard.stripe.com/test/apikeys) 配置 SDK。这样可使您的应用程序向 Stripe API 发出请求。

#### Swift

```swift
import UIKitimportStripeApplePay

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {StripeAPI.defaultPublishableKey = "<<YOUR_PUBLISHABLE_KEY>>"
        // do any other necessary launch configuration
        return true
    }
}
```

> 测试时使用您的[测试密钥](https://docs.stripe.com/keys.md#obtain-api-keys)，发布应用时使用[真实模式](https://docs.stripe.com/keys.md#test-live-modes)密钥。

## 注册 Apple Merchant ID

可通过在 Apple 开发人员网站[注册新的标识符](https://developer.apple.com/account/resources/identifiers/add/merchant)来获取 Apple 商家 ID。

在表单中填写描述和标识符。描述内容仅供您自己记录之用，之后可随时更改。Stripe 建议用您的应用的名称作为标识符（例如，`merchant.com.{{YOUR_APP_NAME}}`）。

## 创建新的 Apple Pay 证书

为您的应用创建证书，以加密支付数据。

转到管理平台中的 [iOS 证书设置](https://dashboard.stripe.com/settings/ios_certificates)，点击**添加新应用程序**，然后按照说明进行操作。

下载证书签名请求 (CSR) 文件，来从 Apple 获取安全证书，以便使用 Apple Pay。

必须用一个 CSR 文件发布具体的一个证书。如果您切换您的 Apple Merchant ID，则必须前往管理平台的 [iOS 证书设置](https://dashboard.stripe.com/settings/ios_certificates)中获取一个新的 CSR 和证书。

## 集成 Xcode

将 Apple Pay 功能添加到您的应用程序。在 Xcode 中，打开您的项目设置，点击**签名和功能**选项卡，然后添加 **Apple Pay** 功能。此时，系统可能会提示您登入您的开发人员账户。选择您之前创建的商家 ID，您的应用程序就可以接受 Apple Pay 了。
![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png)

在 Xcode 中启用 Apple Pay 功能

## 检查是否支持 Apple Pay

在您的应用程序中显示 Apple Pay 此支付选项之前，请确定用户的设备支持 Apple Pay，并且他们的钱包中添加了银行卡：

#### Swift

```swift
import StripeApplePay
import PassKit

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

    override func viewDidLoad() {
        super.viewDidLoad()
        // Only offer Apple Pay if the customer can pay with it
        applePayButton.isHidden = !StripeAPI.deviceSupportsApplePay()
        applePayButton.addTarget(self, action: #selector(handleApplePayButtonTapped), for: .touchUpInside)
    }

    // ...continued in next step
}
```

## 创建付款请求

当用户点击 **Apple Pay** 按钮时，调用 [StripeAPI paymentRequestWithMerchantIdentifier:country:currency:](https://stripe.dev/stripe-ios/stripe-payments/Classes/StripeAPI.html#/c:@M@StripeCore@objc\(cs\)StripeAPI\(cm\)paymentRequestWithMerchantIdentifier:country:currency:)，创建一个 [PKPaymentRequest](https://developer.apple.com/documentation/passkit/pkpaymentrequest)。

然后，配置 `PKPaymentRequest` 以显示贵商家的名称和总金额。您还可以收集账单详情或配送信息等信息。

关于如何自定义付款请求的完整指南，请参见 [Apple 文档](https://developer.apple.com/design/human-interface-guidelines/apple-pay/overview/checkout-and-payment/#customize-the-payment-sheet)。

#### Swift

```swift
func handleApplePayButtonTapped() {
    let merchantIdentifier = "merchant.com.your_app_name"
    let paymentRequest = StripeAPI.paymentRequest(withMerchantIdentifier: merchantIdentifier, country: "US", currency: "USD")

    // Configure the line items on the payment request
    paymentRequest.paymentSummaryItems = [
        // The final line should represent your company;
        // it'll be prepended with the word "Pay" (that is, "Pay iHats, Inc $50")
        PKPaymentSummaryItem(label: "iHats, Inc", amount: 50.00),
    ]
    // ...continued in next step
}
```

## 出示支付表单

用 `PKPaymentRequest` 创建一个 [STPApplePayContext](https://stripe.dev/stripe-ios/stripe-applepay/Classes/STPApplePayContext.html) 实例，并使用它来呈现 Apple Pay 表单。

#### Swift

```swift
func handleApplePayButtonTapped() {
    // ...continued from previous step

    // Initialize an STPApplePayContext instance
    if let applePayContext = STPApplePayContext(paymentRequest: paymentRequest, delegate: self) {
        // Present Apple Pay payment sheet
        applePayContext.presentApplePay(on: self)
    } else {
        // There is a problem with your Apple Pay configuration
    }
}
```

Apple 要求用户操作触发 Apple Pay 模态窗口（例如，点击按钮或与表单交互）。确保您的代码遵循以下规则：

- 通过用户激活事件直接调用支付表单。
- 将支付表单的代码添加到用户操作事件处理器的顶部或顶部附近，并且需位于任何异步或长时间运行的代码之前。
- 在用户操作后，设置一个合理的时间限制来调用 `confirmPayment`。

## 向 Stripe 提交付款

### 服务器端

生成一个端点，创建一个具有 [amount](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-amount) 和 [currency](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-currency) 的 PaymentIntent。始终在服务器端决定扣款金额，这是一个可信的环境，客户端不行。这样可防止客户自己选择价格。

#### curl

```bash
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -d "amount"=1099 \
  -d "currency"="usd"
```

### 客户端

#### Payment Intents API

实现 `applePayContext(_:didCreatePaymentMethod:paymentInformation:)`，以便返回从上述端点获取的 PaymentIntent 客户端私钥；如果请求失败则抛出错误。

在您返回客户端私钥后，`STPApplePayContext` 将完成支付、关闭 Apple Pay 表单，并调用 `applePayContext(_:didCompleteWithStatus:error:)` 并传入支付状态。请实现该方法以向客户展示收据。

#### Swift

```swift
extension CheckoutViewController {
    func applePayContext(_ context: STPApplePayContext, didCreatePaymentMethod paymentMethod: StripeAPI.PaymentMethod, paymentInformation: PKPayment) async throws -> String {
        let clientSecret = try await ... // Retrieve the PaymentIntent client secret from your backend (see Server-side step above)
        // Return the client secret or throw an error
        return clientSecret
    }

    func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPApplePayContext.PaymentStatus, error: Error?) {
          switch status {
        case .success:
            // Payment succeeded, show a receipt view
            break
        case .error:
            // Payment failed, show the error
            break
        case .userCancellation:
            // User canceled the payment
            break
        @unknown default:
            fatalError()
        }
    }
}
```

最后，[处理支付后事件](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=ios#ios-post-payment)，例如向客户发送订单确认邮件、在数据库中记录销售信息，或启动发货流程。

#### Payment Intents API（服务器端确认）

实现 `applePayContext(_:didCreatePaymentMethod:paymentInformation:)`，以便将 `paymentMethod.id` 发送到您的服务器，并创建和确认 PaymentIntent。请返回从服务器返回的 PaymentIntent 客户端私钥，如果请求失败则抛出错误。

在您返回客户端私钥后，`STPApplePayContext` 将完成支付、关闭 Apple Pay 表单，并调用 `applePayContext(_:didCompleteWithStatus:error:)` 并传入支付状态。请实现该方法以向客户展示收据。

#### Swift

```swift
extension CheckoutViewController {
    func applePayContext(_ context: STPApplePayContext, didCreatePaymentMethod paymentMethod: StripeAPI.PaymentMethod, paymentInformation: PKPayment) async throws -> String {
        let clientSecret = try await ... // Call your backend to create and confirm a PaymentIntent and get its client secret
        // Return the client secret or throw an error
        return clientSecret
    }

    func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPApplePayContext.PaymentStatus, error: Error?) {
          switch status {
        case .success:
            // Payment succeeded, show a receipt view
            break
        case .error:
            // Payment failed, show the error
            break
        case .userCancellation:
            // User canceled the payment
            break
        @unknown default:
            fatalError()
        }
    }
}
```

### 故障排除

如果您在尝试创建令牌时看到 Stripe API 出现错误，则很可能是您的 Apple Pay Certificate 有问题。如本页所述，您需要生成一个新证书并上传到 Stripe。请确保您使用的是从您的管理平台获得的 CSR，而不是您自己生成的那个。Xcode 经常错误地缓存旧的证书，所以除了生成新证书外，Stripe 建议创建一个新的 Apple Merchant ID。

如果您收到错误：

> 您尚未将您的 Apple 商家账户添加到 Stripe

您的应用程序好像正在发送用以前的（非 Stripe） CSR/Certificate 加密的数据。务必撤销您的 Apple Merchant ID 下任何不是由 Stripe 生成的证书。如果这样不能解决问题，请删除您的 Apple 账户中的商家 ID，然后重新创建它。然后，根据之前使用的相同（Stripe 提供的） CSR 创建一个新证书。您不需要将此新的证书上传到 Stripe。完成后，在您的应用程序中打开并关闭 Apple Pay Credentials，以确保正确刷新。

## App Clips

`StripeApplePay` 模态是一个简版 Stripe SDK，为在 [App Clip](https://developer.apple.com/app-clips/) 中使用进行了优化。按照[以上步骤](https://docs.stripe.com/apple-pay.md?platform=ios#accept)将 `StripeApplePay` 模态添加到您的 App Clip 的目标中。

> 仅 Swift 中支持 `StripeApplePay` 模态。Objective-C 用户必须从 `Stripe` 模态导入 `STPApplePayContext`。

### 从 STPApplePayContext 迁移

如果您当前使用的是 `STPApplePayContext` 并且想切换到简版 Apple Pay SDK，则按照这些步骤进行：

1. 在您的 App Clip 目标的依赖中，将 `Stripe` 模态替换为 `StripeApplePay` 模态。
1. 在您的代码中，将 `import Stripe` 替换为 `import StripeApplePay`。
1. 将您使用的 `STPApplePayContextDelegate` 替换为新的 `ApplePayContextDelegate` 协议。
1. 更改您的 `applePayContext(_:didCreatePaymentMethod:)` 实现，以接受 `StripeAPI.PaymentMethod`。
1. 更改您的 `applePayContext(_:didCompleteWith:error:)` 部署，以接受 `STPApplePayContext.PaymentStatus`。

### Before

```swift


    func applePayContext(_ context: STPApplePayContext,
      paymentInformation: PKPayment,
        // ...
    }

    func applePayContext(_ context: STPApplePayContext,
      error: Error?) {
        // ...
    }
}
```

### After

```swift
import StripeApplePay
class CheckoutViewController: UIViewController, ApplePayContextDelegate {
    func applePayContext(_ context: STPApplePayContext,didCreatePaymentMethod paymentMethod: StripeAPI.PaymentMethod,
      paymentInformation: PKPayment
        // ...} async throws -> String {

    func applePayContext(_ context: STPApplePayContext,didCompleteWith status: STPApplePayContext.PaymentStatus,
      error: Error?) {
        // ...
    }
}
```

## 经常性付款

在 iOS 16 或更高版本中，可通过在 `PKPaymentRequest` 上设置 `recurringPaymentRequest` 或 `automaticReloadPaymentRequest` 属性来采用[商家令牌](https://developer.apple.com/apple-pay/merchant-tokens/)。

经常性付款只能使用已保存的支付方式进行[非会话交易](https://docs.stripe.com/apple-pay/apple-pay-recurring.md#set-up-off-session-payments)。

#### Swift

```swift
extension CheckoutViewController {
  func handleApplePayButtonTapped() {
    let request = StripeAPI.paymentRequest(withMerchantIdentifier: merchantIdentifier, country: "US", currency: "USD")

    let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99"))
    billing.startDate = Date()
    billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365)
    billing.intervalUnit = .month

    request.recurringPaymentRequest = PKRecurringPaymentRequest(paymentDescription: "Recurring",
                                                                regularBilling: billing,
                                                                managementURL: URL(string: "https://my-backend.example.com/customer-portal")!)
    request.recurringPaymentRequest?.billingAgreement = "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'"
    request.paymentSummaryItems = [billing]
  }
}
```

要了解有关如何通过 Apple Pay 使用经常性付款的更多信息，请参阅 [Apple 的 PassKit 文档](https://developer.apple.com/documentation/passkit/pkpaymentrequest)。

## 订单跟踪

要在 iOS 16 或以上版本中采用[订单跟踪](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking)，在您的 `ApplePayContextDelegate` 中部署 [applePayContext(context:willCompleteWithResult:handler:)](https://github.com/stripe/stripe-ios/blob/22.8.0/StripeApplePay/StripeApplePay/Source/ApplePayContext/STPApplePayContext.swift#L38) 函数。Stripe 在支付完成后调用您的部署环境，但是在 iOS 关闭 Apple Pay 表单之前。

在您的部署环境中：

1. 从您的服务器获取已完成订单的详情。
1. 将这些详情添加到提供的 [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult)。
1. 调用主队列上提供的完成处理程序。

要了解有关订单跟踪的更多信息，请参阅 [Apple 钱包订单文档](https://developer.apple.com/documentation/walletorders)。

#### Swift

```swift
extension CheckoutViewController {
    func applePayContext(_ context: STPApplePayContext, willCompleteWithResult authorizationResult: PKPaymentAuthorizationResult) async -> PKPaymentAuthorizationResult {
        // Fetch the order details from your service
        do {
          let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: myOrderID)
          authorizationResult.orderDetails = PKPaymentOrderDetails(
            orderTypeIdentifier: myOrderDetails.orderTypeIdentifier, // "com.myapp.order"
            orderIdentifier: myOrderDetails.orderIdentifier, // "ABC123-AAAA-1111"
            webServiceURL: myOrderDetails.webServiceURL, // "https://my-backend.example.com/apple-order-tracking-backend"
            authenticationToken: myOrderDetails.authenticationToken // "abc123"
          )
          // Return your modified PKPaymentAuthorizationResult
          return authorizationResult
        } catch {
          return PKPaymentAuthorizationResult(status: .failure, errors: [error])
        }
    }
}
```


# React Native iOS

> This is a React Native iOS for when platform is react-native. View the full page at https://docs.stripe.com/apple-pay?platform=react-native.

您可以使用 Stripe 的 [React Native SDK](https://github.com/stripe/stripe-react-native)，同时支持 Apple Pay 和传统信用卡支付。开始之前，您需要加入 [Apple Developer Program](https://developer.apple.com/programs/)，并[在服务器和应用程序中配置好 Stripe](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=react-native#react-native-setup)。接下来，按照以下步骤操作：

1. [注册 Apple Merchant ID](https://docs.stripe.com/apple-pay.md#merchantid)
1. [创建新的 Apple Pay 证书](https://docs.stripe.com/apple-pay.md#csr)
1. [用 Xcode 集成](https://docs.stripe.com/apple-pay.md#xcode-pay)
1. [在 StripeProvider 中设置您的 Apple Merchant ID](https://docs.stripe.com/apple-pay.md#set-merchantid)
1. [检查是否支持 Apple Pay](https://docs.stripe.com/apple-pay.md#check-if-apple-pay-supported)
1. [出示支付表单](https://docs.stripe.com/apple-pay.md#present-payment-sheet)
1. [向 Stripe 提交付款](https://docs.stripe.com/apple-pay.md#handle-payment)

> 如果您使用的是 React Native 和 Expo，则 Expo Go 不支持 Apple Pay。要将 Expo 与 Apple Pay 结合使用，您必须创建一个[开发版本](https://docs.expo.dev/get-started/set-up-your-environment/?mode=development-build&platform=ios)。如果您已经有 Expo Go 项目，您可以[将其迁移到开发版本](https://docs.expo.dev/develop/development-builds/expo-go-to-dev-build/)。

## 注册 Apple Merchant ID

可通过在 Apple 开发人员网站[注册新的标识符](https://developer.apple.com/account/resources/identifiers/add/merchant)来获取 Apple 商家 ID。

在表单中填写描述和标识符。描述内容仅供您自己记录之用，之后可随时更改。Stripe 建议用您的应用的名称作为标识符（例如，`merchant.com.{{YOUR_APP_NAME}}`）。

## 创建新的 Apple Pay 证书

为您的应用创建证书，以加密支付数据。

转到管理平台中的 [iOS 证书设置](https://dashboard.stripe.com/settings/ios_certificates)，点击**添加新应用程序**，然后按照说明进行操作。

下载证书签名请求 (CSR) 文件，来从 Apple 获取安全证书，以便使用 Apple Pay。

必须用一个 CSR 文件发布具体的一个证书。如果您切换您的 Apple Merchant ID，则必须前往管理平台的 [iOS 证书设置](https://dashboard.stripe.com/settings/ios_certificates)中获取一个新的 CSR 和证书。

## 集成 Xcode

将 Apple Pay 功能添加到您的应用程序。在 Xcode 中，打开您的项目设置，点击**签名和功能**选项卡，然后添加 **Apple Pay** 功能。此时，系统可能会提示您登入您的开发人员账户。选择您之前创建的商家 ID，您的应用程序就可以接受 Apple Pay 了。
![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png)

在 Xcode 中启用 Apple Pay 功能

## 在 StripeProvider 中设置您的 Apple Merchant ID

在 `StripeProvider` 组件中，指定您成功注册的 Apple Merchant ID：

```jsx
import { StripeProvider } from '@stripe/stripe-react-native';

function App() {
  return (
    <StripeProvider
      publishableKey="<<YOUR_PUBLISHABLE_KEY>>"
      merchantIdentifier="merchant.com.{{YOUR_APP_NAME}}"
    >
      {/* Your app code here */}
    </StripeProvider>
  );
}
```

## 检查是否支持 Apple Pay

在您的应用程序中显示 Apple Pay 此支付选项之前，请确定用户的设备支持 Apple Pay，并且他们的钱包中添加了银行卡：

```jsx
import { PlatformPayButton, isPlatformPaySupported } from '@stripe/stripe-react-native';

function PaymentScreen() {
  const [isApplePaySupported, setIsApplePaySupported] = useState(false);

  useEffect(() => {
    (async function () {
      setIsApplePaySupported(await isPlatformPaySupported());
    })();
  }, [isPlatformPaySupported]);

  // ...

  const pay = async () => {
    // ...
  };

  // ...

  return (
    <View>
      {isApplePaySupported && (
        <PlatformPayButton
          onPress={pay}
          type={PlatformPay.ButtonType.Order}
          appearance={PlatformPay.ButtonStyle.Black}
          borderRadius={4}
          style={{
            width: '100%',
            height: 50,
          }}
        />
      )}
    </View>
  );
}
```

## 创建 Payment Intent

### 服务器端

生成一个端点，创建一个具有 [amount](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-amount) 和 [currency](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-currency) 的 PaymentIntent。始终在服务器端决定扣款金额，这是一个可信的环境，客户端不行。这样可防止客户自己选择价格。

#### curl

```bash
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -d "amount"=1099 \
  -d "currency"="usd"
```

### 客户端

创建一个从您的服务器请求 PaymentIntent 的方法：

```jsx
function PaymentScreen() {
  // ...
  const fetchPaymentIntentClientSecret = async () => {
    const response = await fetch(`${API_URL}/create-payment-intent`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        some: 'value',
      }),
    });
    const { clientSecret } = await response.json();

    return clientSecret;
  };
  // ...
}
```

### 故障排除

如果您在尝试创建令牌时看到 Stripe API 出现错误，则很可能是您的 Apple Pay Certificate 有问题。如本页所述，您需要生成一个新证书并上传到 Stripe。请确保您使用的是从您的管理平台获得的 CSR，而不是您自己生成的那个。Xcode 经常错误地缓存旧的证书，所以除了生成新证书外，Stripe 建议创建一个新的 Apple Merchant ID。

如果您收到错误：

> 您尚未将您的 Apple 商家账户添加到 Stripe

您的应用程序好像正在发送用以前的（非 Stripe） CSR/Certificate 加密的数据。务必撤销您的 Apple Merchant ID 下任何不是由 Stripe 生成的证书。如果这样不能解决问题，请删除您的 Apple 账户中的商家 ID，然后重新创建它。然后，根据之前使用的相同（Stripe 提供的） CSR 创建一个新证书。您不需要将此新的证书上传到 Stripe。完成后，在您的应用程序中打开并关闭 Apple Pay Credentials，以确保正确刷新。

## 出示支付表单

在您的 [`PlatformPayButton`的](https://stripe.dev/stripe-react-native/api-reference/index.html#PlatformPayButton) `onPress` 属性中，调用 `confirmPlatformPayPayment` 以打开 Apple Pay 面板。要在支付面板上显示客户的购物车商品，请将商品作为参数传入。最后一个商品必须代表您的公司及总金额；它会在面板中显示，并在前面加上“支付”一词（例如，“支付 iHats, Inc. 50 USD”）。

> 在您的那些处理客户操作的代码中，不要在显示支付表单前包含任何复杂或异步操作。如果用户操作不直接调用支付表单，Apple Pay 会返回一个错误。

```jsx
import { confirmPlatformPayPayment } from '@stripe/stripe-react-native';

function PaymentScreen() {
  // ... see above

  const pay = async () => {
    const clientSecret = await fetchPaymentIntentClientSecret()
    const { error, paymentIntent } = await confirmPlatformPayPayment(
      clientSecret,
      {
        applePay: {
          cartItems: [
            {
              label: 'Example item name',
              amount: '14.00',
              paymentType: PlatformPay.PaymentType.Immediate,
            },
            {
              label: 'Tax',
              amount: '1.60',
              paymentType: PlatformPay.PaymentType.Immediate,
            },
            {
              label: 'iHats, Inc.',
              amount: '15.60',
              paymentType: PlatformPay.PaymentType.Immediate,
            },
          ],
          merchantCountryCode: 'US',
          currencyCode: 'USD',
          requiredShippingAddressFields: [
            PlatformPay.ContactField.PostalAddress,
          ],
          requiredBillingContactFields: [PlatformPay.ContactField.PhoneNumber],
        },
      }
    );
    if (error) {
      // handle error
    } else {
      Alert.alert('Success', 'Check the logs for payment intent details.');
      console.log(JSON.stringify(paymentIntent, null, 2));
    }
  };

  // ... see above
}
```

## Optional: 创建 Payment Method [客户端]

如果您在您的服务器上确认付款，则可以用 Apple Pay 仅收集 `PaymentMethod`，而非确认付款。为此，调用 `createPlatformPayPaymentMethod` 方法：

```javascript
import {PlatformPayButton, isPlatformPaySupported, createPlatformPayPaymentMethod} from '@stripe/stripe-react-native';

function PaymentScreen() {
  const [isApplePaySupported, setIsApplePaySupported] = useState(false);

  useEffect(() => {
    (async function () {
      setIsApplePaySupported(await isPlatformPaySupported());
    })();
  }, [isPlatformPaySupported]);

  const createPaymentMethod = async () => {
    const { error, paymentMethod } = await createPlatformPayPaymentMethod({
      applePay: {
        cartItems: [
          {
            label: 'Example item name',
            amount: '14.00',
            paymentType: PlatformPay.PaymentType.Immediate,
          },
          {
            label: 'Total',
            amount: '12.75',
            paymentType: PlatformPay.PaymentType.Immediate,
          },
        ],
        merchantCountryCode: 'US',
        currencyCode: 'USD',
      },
    });

    if (error) {
      Alert.alert(error.code, error.message);
      return;
    } else if (paymentMethod) {
      Alert.alert(
        'Success',
        `The payment method was created successfully. paymentMethodId: ${paymentMethod.id}`
      );
    }
  };

  return (
    <View >
      {isApplePaySupported && (
        <PlatformPayButton
          onPress={createPaymentMethod}
          type={PlatformPay.ButtonType.SetUp}
          appearance={PlatformPay.ButtonStyle.WhiteOutline}
          style={{
            width: '65%',
            height: 50,
          }}
        />
      )}
    </View>
  );
}
```

## Optional: 经常性付款 [客户端]

在 iOS 16 及以上版本中，可通过在 `confirmPlatformPayPayment()` 和 `confirmPlatformPaySetupIntent` 的 `applePay` 参数对象中设置 `request` 字段来采用[商家令牌](https://developer.apple.com/apple-pay/merchant-tokens/)。

```js
await confirmPlatformPayPayment(
  clientSecret,
  {
    applePay: {
      // Make sure to include the rest of the necessary fields
      request: {
        type: PlatformPay.PaymentRequestType.Recurring,
        description: 'String describing my payment',
        managementUrl:
          'www.<a URL where the user can update the payment method for the recurring payment>.com',
        billing: {
          paymentType: PlatformPay.PaymentType.Recurring,
          intervalUnit: PlatformPay.IntervalUnit.Month,
          intervalCount: 3,
          label: 'My label',
          amount: '39.00',
        },
      },
    },
  }
);
```

要了解有关如何通过 Apple Pay 使用经常性付款的更多信息，请参阅 [Apple 的 PassKit 文档](https://developer.apple.com/documentation/passkit/pkpaymentrequest)。

## Optional: 订单跟踪 [客户端]

要在 iOS 16 及以上版本中采用[订单跟踪](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking)，为 `PlatformPayButton` 组件使用 `setOrderTracking` 回调。

在您的部署环境中：

1. 从您的服务器获取已完成订单的详情。
1. 用结果在 `setOrderTracking` 中从您的服务器调用提供的完成处理程序。

```jsx
<PlatformPayButton
  // Make sure to include the rest of the necessary props
  setOrderTracking={(completion) => {
    const { orderIdentifier, orderType, authToken, webServiceUrl } =
      fetchOrderDetailsFromMyBackend();
    completion(orderIdentifier, orderType, authToken, webServiceUrl);
  }}
/>
```

要了解有关订单跟踪的更多信息，请参阅 [Apple 钱包订单文档](https://developer.apple.com/documentation/walletorders)。


# Web

> This is a Web for when platform is web. View the full page at https://docs.stripe.com/apple-pay?platform=web.

您可以使用 [Checkout](https://docs.stripe.com/payments/checkout.md) 或 [Elements](https://docs.stripe.com/payments/elements.md) 在网页端接受 Apple Pay 付款。在 Checkout 中使用 Apple Pay 无需额外配置。对于 Elements，请参考 [Express Checkout Element](https://docs.stripe.com/elements/express-checkout-element.md) 或 [接受付款](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=elements&api-integration=checkout)指南，了解如何将 Apple Pay 添加到您的网站。

### 网页版集成考虑因素

- **在 [Elements](https://docs.stripe.com/payments/elements.md) 上使用 iframe 时**：使用 iframe 时，它的来源必须与顶级来源匹配（当指定 `allow="payment"` 属性时，Safari 17+ 除外）。如果两页的协议、主机（完整域名）和端口（如果指定）相同，则这两页相同。
- **顶级域名和 iframe 域名**：如果顶级域名与 iframe 不同，那么顶级域名和 iframe 的来源域名必须都得是关联账户[注册的支付方式域名](https://docs.stripe.com/payments/payment-methods/pmd-registration.md)。
- **现有的Stripe.js v2 集成**：方便时尽早升级到 Checkout 或 Elements。
- **将 [Checkout](https://docs.stripe.com/payments/checkout.md) 与设置为 `embedded_page` 的 [ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) 一起使用时**：仅支持 Safari 17 或更高版本以及 iOS 17 或更高版本。

在网页上使用 Apple Pay 需遵守 [Apple Pay 网页使用服务条款](https://stripe.com/apple-pay/legal)。

### 使用 Apple Pay 注册域名

要使用 Apple Pay，您必须在 Apple 这里注册要显示 Apple Pay 按钮的所有网站域名。这包括生产和测试模式下的顶级域名（例如 **stripe.com**）和子域名（例如 **shop.stripe.com**）。

> #### 子域名
> 
> `www` 是一个子域名（例如，**www.stripe.com**），您也必须注册。

Stripe 为您处理 Apple 商家验证，包括创建 Apple Merchant ID（Apple 商家 ID）和 Certificate Signing Request（证书签名请求）。请勿遵循 Apple Pay 文档中的商家验证流程。而应按照以下步骤作：

1. 指示 Stripe 在 Apple 这里注册您的域名。您可以在管理平台的[支付方式域名页面](https://dashboard.stripe.com/settings/payment_method_domains)，_或_用您的真实私钥通过 API 来完成此操作，如下所示。每个账户注册域名的次数不要超过一次。

```curl
curl https://api.stripe.com/v1/payment_method_domains \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "domain_name=example.com"
```

当将[直接收款](https://docs.stripe.com/connect/direct-charges.md) 与*Connect* (Connect is Stripe's solution for multi-party businesses, such as marketplace or software platforms, to route payments between sellers, customers, and other recipients)结合使用时，您需要通过 API 为每个 Connected 子账户配置域。对于使用其他收费类型的 Connected 子账户，此配置不是必需操作。

注册了您的域名之后，您即可开始用真实 API 密钥在您的网站上收款。

## 经常性付款

我们建议您启用 Apple Pay 商户令牌，以便支持商户发起的交易 (MIT)，例如定期付款、延迟付款以及自动充值。商户令牌 (MPAN) 可将您的业务与客户的 Apple Wallet 支付方式连接起来，使其可在多台设备上使用；即使在设备丢失或被盗后将该支付方式从原设备中移除，该支付信息也能在新设备上保持有效。有关集成详情，请参阅 [Apple Pay 商户令牌](https://docs.stripe.com/apple-pay/merchant-tokens.md?pay-element=ece)。


## 测试 Apple Pay

要测试 Apple Pay，必须使用真实的信用卡卡号和测试 [API 密钥](https://docs.stripe.com/keys.md)。Stripe 会识别到您处于测试模式，并返回一个成功的测试卡令牌供您使用，因此您可以在不收款的情况下使用真实卡来测试付款。

您无法将[Stripe测试卡](https://docs.stripe.com/testing.md#use-test-cards)或 [Apple Pay 测试卡](https://developer.apple.com/apple-pay/sandbox-testing/)保存到 Apple Pay 钱包来测试 Apple Pay。

# Web

> This is a Web for when platform is web. View the full page at https://docs.stripe.com/apple-pay?platform=web.

如果您不满足设备和集成要求，Stripe 不会显示 Apple Pay 这一支付选项。使用我们的[测试页](https://docs.stripe.com/testing/wallets.md)来帮助您排除故障。


## See also

- [iOS 集成](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=mobile&platform=ios)
- [网页版 Apple Pay](https://docs.stripe.com/elements/express-checkout-element.md)
- [Apple Pay 最佳实践](https://docs.stripe.com/apple-pay/best-practices.md)
