# 收款

安全地在线上收款。

对于大多数集成，Stripe 建议将 Checkout Sessions API 与 Payment Element 搭配使用，而非 Payment Intents。Checkout Sessions 可覆盖与 Payment Intents（使用 `price_data` 的基础收款功能，或者构建包含明细项、税费等的完整结账流程）类似的应用场景。Adaptive Pricing 等部分功能仅在 Checkout Sessions 中可用。除非用户明确要求，否则不要使用 Payment Intent API，因为它需要的代码明显更多。进一步了解 Elements 与 Checkout Sessions API 搭配使用的信息：https://docs.stripe.com/payments/quickstart.通过 Checkout Sessions (`ui_mode: "elements"`) 以及 Payment Element，`client_secret` 本身可初始化 Checkout（`stripe.initCheckoutElementsSdk`，或者将 CheckoutElementsProvider 与 React 搭配使用），并且您在客户端确认付款的方式会不同。如果使用 React，则需要确保从 `@stripe/react-stripe-js/checkout` 导入，将 `CheckoutElementsProvider` 与客户端密钥搭配使用，并使用 `checkout.confirm` 确认。如果使用 HTML，确保使用 `checkout = stripe.initCheckoutElementsSdk({clientSecret: promise}); checkout.createPaymentElement(); paymentElement = checkout.createPaymentElement(); paymentElement.mount("#payment-element");`，并通过 `loadActionsResult = await checkout.loadActions(); actions = loadActionsResult.actions; error = await actions.confirm();` 确认。

编程智能体：使用适用于您操作系统的安装脚本[安装 Stripe CLI](https://docs.stripe.com/cli/install)。打开新的终端并运行 `stripe sandbox create --help`，以配置一个具有有效 API 密钥的匿名 Stripe 沙盒。无需注册账户。

制作支付表单或使用预构建的结账页面来开始接收线上付款。

# Android 应用内集成

![](https://b.stripecdn.com/docs-statics-srv/assets/android-overview.471eaf89a760f5b6a757fd96b6bb9b60.png)

用 [PaymentSheet](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html) 类将 Stripe 的预构建支付 UI 集成到您的 Android 应用程序的结账流程。

或者，从[代码快速入门](https://docs.stripe.com/payments/mobile/quickstart.md?platform=android)开始，构建或下载可运行的示例。

> #### Accounts v2 API 支持
> 
> Payment Sheet 不支持 *客户配置的账户* (Account configurations represent role-based functionality that you can enable for accounts, such as merchant, customer, or recipient)，仅支持 `Customer` 对象。

## 设置 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 Android SDK](https://github.com/stripe/stripe-android) 是开源的，且[有完整的文档](https://stripe.dev/stripe-android/)。

安装 SDK 时，将 `stripe-android` 添加到您的 [app/build.gradle](https://developer.android.com/studio/build/dependencies) 文件的 `dependencies` 块中：

#### Kotlin

```kotlin
plugins {
    id("com.android.application")
}

android { ... }

dependencies {
  // ...

  // Stripe Android SDK
  implementation("com.stripe:stripe-android:23.26.0")
  // Include the financial connections SDK to support US bank account as a payment method
  implementation("com.stripe:financial-connections:23.26.0")
}
```

> 有关最新 SDK 发布及过往版本的详细信息，请查看 GitHub 上的[发布](https://github.com/stripe/stripe-android/releases)页面。要想在新版本发布时接收通知，请[查看仓库的发布情况](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository)。

## 启用支付方式

查看您的[支付方式设置](https://dashboard.stripe.com/settings/payment_methods)，启用您想支持的支付方式。您至少需要启用一个支付方式才能创建 *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods)。

默认情况下，Stripe 支持信用卡和其他常见的支付方式，可以帮助您获得更多客户，但建议您开启与您的业务和客户相关的其他支付方式。查看[支付方式支持](https://docs.stripe.com/payments/payment-methods/payment-method-support.md)，了解支持的产品和支付方式，并查看我们的[定价页面](https://stripe.com/pricing/local-payment-methods)了解费用。

## 添加端点 [服务器端]

> #### 注意
> 
> 要在创建 PaymentIntent 之前显示 PaymentSheet，请参阅[收集支付详情后再创建 Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment)。

该集成使用三个 Stripe API 对象：

1. [PaymentIntent](https://docs.stripe.com/api/payment_intents.md)：Stripe 用它来表示您从客户收款的意图，跟踪您的扣款尝试及整个过程中付款状态的变化情况。
2. （可选）[Customer](https://docs.stripe.com/api/customers.md)：要设置用于未来支付的支付方式，您必须将其关联到客户。当客户在您的企业创建账户时，请创建对象来代表该客户。如果您的客户以访客身份付款，您可以在付款前创建 `Customer` 对象，随后再将其与您内部的客户账户表示关联起来。
3. （可选）[CustomerSession](https://docs.stripe.com/api/customer_sessions.md)：用于表示客户的对象信息属于敏感数据，无法从应用中直接获取。`CustomerSession` 会为 SDK 提供针对 `Customer` 对象的临时、受限访问权限，并提供额外的[配置选项](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components)。

> 如果您从不为客户保存卡片，您可以从集成中省略 `Customer` 对象和 `CustomerSession` 对象。

出于安全原因，您的应用无法创建这些对象。相反，在服务器上会添加一个端点，其功能如下：

1. 检索 `Customer` 对象或创建新对象。
2. 为 `Customer` 创建 [CustomerSession](https://docs.stripe.com/api/customer_sessions.md)。
3. 创建包含[金额](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount)、[货币](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-currency)和[客户](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer)的 `PaymentIntent`。
4. 向您的应用返回 `PaymentIntent` 的*客户端密钥* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer))、`CustomerSession` 的 `client_secret`、`Customer` ID，以及您的[可发布密钥](https://dashboard.stripe.com/apikeys)。

请确保在 `PaymentIntent` 上设置的 `Customer`，与您在 `CustomerSession` 上设置的保持一致。

在结账过程中显示给客户的支付方式也包含在 PaymentIntent 中。您可以让 Stripe 从管理平台设置中提取支付方式，也可以手动列出它们。无论选择哪种方式，都要知道在 PaymentIntent 中传递的货币会过滤显示给客户的支付方式。例如，如果您在 PaymentIntent 中传递 `eur`，并且在管理平台中启用了 OXXO，则不会向客户显示 OXXO，因为 OXXO 不支持 `eur` 支付。

除非您的集成需要基于代码的选项来提供支付方式，否则 Stripe 建议使用自动选项。这是因为 Stripe 会评估货币、支付方式限制和其他参数，以确定支持的支付方式列表。优先显示可提高转化率且与货币和客户所在地最相关的支付方式。

#### 从管理平台管理支付方式

您可以在[管理平台](https://dashboard.stripe.com/settings/payment_methods)中管理支付方式。Stripe 会根据您配置的可用支付方式，并结合交易金额、币种和支付流程等因素，创建 `PaymentIntent`。如果您不想使用管理平台，或者希望手动指定允许的支付方式，可以使用 `allowed_payment_method_types` 参数。

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create a CustomerSession for the Customer
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \

  -d "automatic_payment_methods[enabled]"=true \
```

#### 手动列出支付方式

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create a CustomerSession for the Customer
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "components[mobile_payment_element][enabled]"=true \
  -d "components[mobile_payment_element][features][payment_method_save]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_redisplay]"=enabled \
  -d "components[mobile_payment_element][features][payment_method_remove]"=enabled

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "allowed_payment_method_types[]"="bancontact" \
  -d "allowed_payment_method_types[]"="card" \
  -d "allowed_payment_method_types[]"="ideal" \
  -d "allowed_payment_method_types[]"="klarna" \
  -d "allowed_payment_method_types[]"="sepa_debit" \
```

> 每个支付方式都要支持在 PaymentIntent 中传递的货币，且您的公司必须要位于各支付方式支持的某个国家/地区。查看[支付方式集成选项](https://docs.stripe.com/payments/payment-methods/integration-options.md)页面，查看具体支持哪些。

## 收集付款详情 [客户端]

显示移动端 Payment Element 前，您的结账页面应：

- 显示购买的产品和总金额
- 用 [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android) 收集所需的配送信息
- 包含一个结账按钮来展示 Stripe 的 UI

#### Jetpack Compose

[初始化](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-builder/index.html)您的结账活动的 `onCreate` 内的一个 `PaymentSheet` 实例，从而传递一个支付方式来处理结果。

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult

@Composable
fun App() {
  val paymentSheet = remember { PaymentSheet.Builder(::onPaymentSheetResult).build() }
}

private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
  // implemented in the next steps
}
```

接下来，从您在上一步中创建的端点中获取 PaymentIntent 客户端私钥、Customer Session 客户端私钥、客户 ID 和可发布私钥。使用 `PaymentConfiguration` 设置可发布私钥，并存储其他内容，以便在您展示 PaymentSheet 时使用。

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import com.stripe.android.PaymentConfiguration
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult

@Composable
fun App() {
  val paymentSheet = remember { PaymentSheet.Builder(::onPaymentSheetResult) }.build()
  val context = LocalContext.current
  var customerConfig by remember { mutableStateOf<PaymentSheet.CustomerConfiguration?>(null) }
  varpaymentIntentClientSecret by remember { mutableStateOf<String?>(null) }

  LaunchedEffect(context) {
    // Make a request to your own server and retrieve payment configurations
    val networkResult = ...
    if (networkResult.isSuccess) {
paymentIntentClientSecret = networkResult.paymentIntent
        customerConfig = PaymentSheet.CustomerConfiguration.createWithCustomerSession(
          id = networkResult.customer,
          clientSecret = networkResult.customerSessionClientSecret
        )
        PaymentConfiguration.init(context, networkResult.publishableKey)
    }
  }
}

private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
  // implemented in the next steps
}
```

当客户点击您的结账按钮时，调用 [presentWithPaymentIntent](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#1814490530%2FFunctions%2F2002900378) 来显示支付表单。客户完成付款后，表单将消失，然后 [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) 将调用 [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html)。

```kotlin

import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import com.stripe.android.PaymentConfiguration
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult

@Composable
fun App() {
  val paymentSheet = remember { PaymentSheet.Builder(::onPaymentSheetResult) }.build()
  val context = LocalContext.current
  var customerConfig by remember { mutableStateOf<PaymentSheet.CustomerConfiguration?>(null) }
  var paymentIntentClientSecret by remember { mutableStateOf<String?>(null) }

  LaunchedEffect(context) {
    // Make a request to your own server and retrieve payment configurations
    val networkResult = ...
    if (networkResult.isSuccess) {
        paymentIntentClientSecret = networkResult.paymentIntent
        customerConfig = PaymentSheet.CustomerConfiguration.createWithCustomerSession(
          id = networkResult.customer,
          clientSecret = networkResult.customerSessionClientSecret
        )
        PaymentConfiguration.init(context, networkResult.publishableKey)
    }
  }

  Button(
    onClick = {
      val currentConfig = customerConfig
      val currentClientSecret =paymentIntentClientSecret

      if (currentConfig != null && currentClientSecret != null) {
        presentPaymentSheet(paymentSheet, currentConfig, currentClientSecret)
      }
    }
  ) {
    Text("Checkout")
  }
}

private fun presentPaymentSheet(
  paymentSheet: PaymentSheet,
  customerConfig: PaymentSheet.CustomerConfiguration,
paymentIntentClientSecret: String
) {
  paymentSheet.presentWithPaymentIntent(
paymentIntentClientSecret,
    PaymentSheet.Configuration.Builder(merchantDisplayName = "My merchant name")
      .customer(customerConfig)
      // Set `allowsDelayedPaymentMethods` to true if your business handles
      // delayed notification payment methods like US bank accounts.
      .allowsDelayedPaymentMethods(true)
      .build()
  )
}

private fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
  when(paymentSheetResult) {
    is PaymentSheetResult.Canceled -> {
      print("Canceled")
    }
    is PaymentSheetResult.Failed -> {
      print("Error: ${paymentSheetResult.error}")
    }
    is PaymentSheetResult.Completed -> {
      // Display for example, an order confirmation screen
      print("Completed")
    }
  }
}
```

#### 视图（经典）

[初始化](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#-394860221%2FConstructors%2F2002900378)您的结账活动的 `onCreate` 内的 `PaymentSheet` 实例，传递一个支付方式来处理结果。

#### Kotlin

```kotlin
import com.stripe.android.paymentsheet.PaymentSheet

class CheckoutActivity : AppCompatActivity() {
  lateinit var paymentSheet: PaymentSheet

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    paymentSheet = PaymentSheet.Builder(::onPaymentSheetResult).build(this)
  }

  fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
    // implemented in the next steps
  }
}
```

接下来，从您在上一步中创建的端点中获取 PaymentIntent 客户端私钥、Customer Session 客户端私钥、客户 ID 和可发布私钥。使用 `PaymentConfiguration` 设置可发布私钥，并存储其他内容，以便在您展示 PaymentSheet 时使用。

#### Kotlin

```kotlin
import com.stripe.android.paymentsheet.PaymentSheet

class CheckoutActivity : AppCompatActivity() {
  lateinit var paymentSheet: PaymentSheet
  lateinit var customerConfig: PaymentSheet.CustomerConfiguration
  lateinit varpaymentIntentClientSecret: String

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    paymentSheet = PaymentSheet.Builder(::onPaymentSheetResult).build(this)
    lifecycleScope.launch {
      // Make a request to your own server and retrieve payment configurations
      val networkResult = MyBackend.getPaymentConfig()
      if (networkResult.isSuccess) {
paymentIntentClientSecret = networkResult.paymentIntent
        customerConfig = PaymentSheet.CustomerConfiguration.createWithCustomerSession(
          id = networkResult.customer,
          clientSecret = networkResult.customerSessionClientSecret
        )
        PaymentConfiguration.init(context, networkResult.publishableKey)
      }
    }
  }

  fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
    // implemented in the next steps
  }
}
```

当客户点击您的结账按钮时，调用 [presentWithPaymentIntent](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#1814490530%2FFunctions%2F2002900378) 来显示支付表单。客户完成付款后，表单将消失，然后 [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/index.html) 将调用 [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html)。

#### Kotlin

```kotlin
// ...
class CheckoutActivity : AppCompatActivity() {
  lateinit var paymentSheet: PaymentSheet
  lateinit var customerConfig: PaymentSheet.CustomerConfiguration
  lateinit var paymentIntentClientSecret: String
  // ...
  fun presentPaymentSheet() {
    paymentSheet.presentWithPaymentIntent(
paymentIntentClientSecret,
      PaymentSheet.Configuration.Builder(merchantDisplayName = "My merchant name")
        .customer(customerConfig)
        // Set `allowsDelayedPaymentMethods` to true if your business handles
        // delayed notification payment methods like US bank accounts.
        .allowsDelayedPaymentMethods(true)
        .build()
    )
  }

  fun onPaymentSheetResult(paymentSheetResult: PaymentSheetResult) {
    when(paymentSheetResult) {
      is PaymentSheetResult.Canceled -> {
        print("Canceled")
      }
      is PaymentSheetResult.Failed -> {
        print("Error: ${paymentSheetResult.error}")
      }
      is PaymentSheetResult.Completed -> {
        // Display for example, an order confirmation screen
        print("Completed")
      }
    }
  }
}
```

将 `allowsDelayedPaymentMethods` 设置为 true，以允许[延迟通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)支付方式，例如美国银行账户。对于这些支付方式，只有当 `PaymentSheet` 完成后才能知道最终的付款状态是成功还是失败。如果您支持这些类型的支付方式，请告知客户他们的订单已被确认，并且仅在付款成功时履行订单（例如，为他们安排发货）。

## 处理付款后事件 [服务器端]

付款完成时，Stripe 会发送一个 [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) 事件。使用 [管理平台 Webhook 工具](https://dashboard.stripe.com/webhooks)、或按照 [Webhook 指南](https://docs.stripe.com/webhooks/quickstart.md)来接收这些事件并运行操作，例如，向客户发送订单确认邮件、在数据库中记录订单，或启动配送流程。

侦听这些事件，而不是等待客户端回调。在客户端，客户可能会在执行回调之前关闭浏览器窗口或退出应用程序，并且恶意客户端可能会操纵响应。设置您的集成来侦听异步事件，这样才能用单一集成用用接受[不同类型的支付方式](https://stripe.com/payments/payment-methods-guide)。

除了处理 `payment_intent.succeeded` 事件外，建议在使用 Payment Element 收款时也处理其他的这些事件：

| 事件                                                                                                                              | 描述                                                                                                            | 操作                                                                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded)           | 客户成功完成付款时发送。                                                                                                  | 向客户发送订单确认通知，并*履行* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected)他们的订单。 |
| [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing)         | 当客户成功发起付款但并未完成时发送。当客户发起银行借记时，通常会发送此事件。之后将会出现 `payment_intent.succeeded` 或 `payment_intent.payment_failed` 事件。 | 向客户发送订单确认，告知他们的付款正等待处理。对于数字商品，您可能想先履行订单，然后再等付款完成。                                                                                                     |
| [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | 在客户尝试付款但付款失败时发送。                                                                                              | 如果一笔付款从 `processing` 变为 `payment_failed`，则让客户再尝试一次。                                                                                                   |

## 测试集成

#### 银行卡

| 卡号                  | 场景                                                                                                                                                                                                                                                             | 如何测试                            |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| 4242424242424242    | 该卡付款成功，不需要验证。                                                                                                                                                                                                                                                  | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 |
| 4000002500003155    | 该卡付款时需要*验证* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase)。 | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 |
| 4000000000009995    | 该卡被拒绝，显示拒付代码，例如 `insufficient_funds`。                                                                                                                                                                                                                          | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 |
| 6205500000000000004 | 银联卡的长度为 13-19 位。                                                                                                                                                                                                                                               | 使用信用卡号以及有效期和 CVC 和邮编填写我们的信用卡表单。 |

#### 银行重定向

| 支付方式              | 场景                                                                                                      | 如何测试                                                                                              |
| ----------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Bancontact, iDEAL | 您的客户在基于重定向和立即通知型的支付方式的重定向页面验证失败。                                                                        | 选择基于重定向的任意支付方式，填写必要的信息，并确认付款。然后在重定向页面上点击**让测试付款失败**。                                              |
| 通过银行支付            | 您的客户通过基于重定向和[延迟通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)的支付方式成功付款。 | 选择支付方式，填写必要的信息，并确认付款。然后在重定向页面上点击**测试付款成功**。                                                       |
| 通过银行支付            | 您的客户在基于重定向和延迟通知型的支付方式的重定向页面验证失败。                                                                        | 选择支付方式，填写必要的信息，并确认付款。然后在重定向页面上点击**让测试付款失败**。                                                      |
| BLIK              | 有多个 BLIK 支付失败的情况——立即失败（例如，代码已过期或无效）、延迟的错误（银行拒付）或超时（客户未及时响应）。                                            | 使用电子邮件模式[模拟不同的失败情况](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures)。 |

#### 银行借记

| 支付方式      | 场景                                                      | 如何测试                                                                  |
| --------- | ------------------------------------------------------- | --------------------------------------------------------------------- |
| SEPA 直接借记 | 您的客户成功用 SEPA 直接借记完成付款。                                  | 用账号 `AT321904300235473204` 填写表单。确认的 PaymentIntent 最初变为处理中，三分钟后变为成功状态。 |
| SEPA 直接借记 | 您的客户的付款意图状态从 `processing` 变为 `requires_payment_method`。 | 用账号 `AT861904300235473202` 填写表单。                                      |

有关测试您的集成的更多信息，请参阅[测试](https://docs.stripe.com/testing.md)部分。

## Optional: Enable Link

在您的[支付方式设置](https://dashboard.stripe.com/settings/payment_methods)中启用 Link，让客户可以通过 Link 的一键快速结账按钮，安全地保存并重复使用其支付信息。

### 将客户的邮件地址传递到 Mobile Payment Element

Link 通过客户的电子邮件地址进行身份验证。Stripe 建议尽可能预填信息，以简化结账流程。

要预先填充客户的姓名、邮件地址和电话号码，请在初始化 `PaymentSheet.Configuration` 时提供包含客户信息的 `defaultBillingDetails`。

#### Kotlin

```kotlin
val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Example, Inc.")
  .defaultBillingDetails(
    PaymentSheet.BillingDetails(
        name = "Jenny Rosen",
        email = "jenny.rosen@example.com",
        phone = "888-888-8888"
    )
  )
  .build()
```

### 处理用户登出

`PaymentSheet` 会在本地存储一些信息，用于记住用户是否在应用中使用过 Link。当用户退出登录时，请调用 `PaymentSheet.resetCustomer()` 方法以清除 `PaymentSheet` 的内部状态。

#### Kotlin

```kotlin
class MyActivity: Activity {

  fun onLogoutButtonClicked() {
    PaymentSheet.resetCustomer(this)
    // Other logout logic required by your app
  }
}
```

## Optional: 启用 Google Pay

### 设置您的集成

要使用 Google Pay，先将以下内容添加到您的 **AndroidManifest.xml** 的 `<application>`标签，来启用 Google Pay API：

```xml
<application>
  ...
  <meta-data
    android:name="com.google.android.gms.wallet.api.enabled"
    android:value="true" />
</application>
```

更多详情，请参见 Google Pay 针对 Android 设备编写的[设置 Google Pay API](https://developers.google.com/pay/api/android/guides/setup) 指南。

### 添加 Google Pay

要向您的集成添加 Google Pay，初始化 [PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html) 时，传递您的 Google Pay 环境（生产或测试）下的 [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) 和[贵公司的国家/地区代码](https://dashboard.stripe.com/settings/account)。

#### Kotlin

```kotlin
val googlePayConfiguration = PaymentSheet.GooglePayConfiguration(
  environment = PaymentSheet.GooglePayConfiguration.Environment.Test,
  countryCode = "US",
  currencyCode = "USD" // Required for Setup Intents, optional for Payment Intents
)
val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "My merchant name")
  .googlePay(googlePayConfiguration)
  .build()
```

### 测试 Google Pay

Google 允许您通过其[测试卡套件](https://developers.google.com/pay/api/android/guides/resources/test-card-suite)进行测试付款。该测试套件支持使用 Stripe [测试卡](https://docs.stripe.com/testing.md)。

您必须在支持 Google Pay 的国家/地区使用 Android 实体设备（而不是模拟设备）测试 Google Pay。使用保存到 Google 钱包的真实银行卡登录测试设备上的 Google 账户。

## Optional: 启用银行卡扫描

若要启用银行卡扫描支持，需在 [Google Pay & Wallet Console](https://pay.google.com/business/console?utm_source=devsite&utm_medium=devsite&utm_campaign=devsite) 中请求 Google Pay API 的[生产访问权限](https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access)。

- 如果您已启用 Google Pay，在符合条件的设备上，我们的 UI 会自动提供卡片扫描功能。如需进一步了解符合条件的设备，请参阅 [Google Pay API 限制](https://developers.google.com/android/reference/com/google/android/gms/wallet/PaymentsClient#getPaymentCardRecognitionIntent%28com.google.android.gms.wallet.PaymentCardRecognitionIntentRequest%29)
- **重要提示：**银行卡扫描功能仅在与 [Google Pay & Wallet Console](https://pay.google.com/business/console) 中注册的签名密钥相同的构建中显示。使用不同签名密钥进行测试或调试的构建（例如通过Firebase App Tester 分发的构建）不会显示**扫描银行卡**选项。要在预发布构建中测试银行卡扫描功能，您必须采取以下措施之一：
  - 使用生产签名密钥对您的测试构建进行签名
  - 将您的测试签名密钥指纹添加到 Google Pay & Wallet Console

如果您的应用不支持 Google Pay，您可以使用 Stripe 卡片扫描功能。

> Stripe 卡片扫描功能目前处于公开预览阶段。

为了启用卡片扫描功能，请将 `stripecardscan` 添加到您的 [app/build.gradle](https://developer.android.com/studio/build/dependencies) 文件的 `dependencies` 代码块中：

#### Groovy

```groovy
implementation 'com.stripe:stripecardscan:23.26.0'
```

## Optional: 启用 ACH 付款

要启用 ACH 借记付款，请将 Financial Connections 作为您的应用的依赖项。

[Stripe Android SDK](https://github.com/stripe/stripe-android) 是开源的，且[有完整的文档](https://stripe.dev/stripe-android/)。

安装 SDK 时，将 `financial-connections` 添加到您的 [app/build.gradle](https://developer.android.com/studio/build/dependencies) 文件的 `dependencies` 块中：

#### Kotlin

```kotlin
plugins {
    id("com.android.application")
}

android { ... }

dependencies {
  // ...

  // Financial Connections Android SDK
  implementation("com.stripe:financial-connections:23.26.0")
}
```

> 有关最新 SDK 发布及过往版本的详细信息，请查看 GitHub 上的[发布](https://github.com/stripe/stripe-android/releases)页面。要想在新版本发布时接收通知，请[查看仓库的发布情况](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository)。

## Optional: 自定义表单

所有自定义操作均用 [PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html) 对象来配置。

### 外观

使用 [Appearance API](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=android) 自定义颜色、字体等，使其与应用程序的视觉风格相匹配。

### 支付方式布局

使用 [paymentMethodLayout](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/-builder/index.html#2123253356%2FFunctions%2F2002900378) 配置表单中支付方式的布局。可以水平、垂直显示，也可以让 Stripe 自动优化布局。
![](https://b.stripecdn.com/docs-statics-srv/assets/android-mpe-payment-method-layouts.3bcfe828ceaad1a94e0572a22d91733f.png)

#### Kotlin

```kotlin
PaymentSheet.Configuration.Builder("Example, Inc.")
  .paymentMethodLayout(PaymentSheet.PaymentMethodLayout.Automatic)
  .build()
```

### 收集用户地址

用 [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android) 收集客户的本地和国际收货地址或账单地址。

### 商家显示名称

通过设置 [merchantDisplayName](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html#-191101533%2FProperties%2F2002900378) 来指定一个向客户显示的商家名称。默认情况下，使用的是您的应用的名称。

#### Kotlin

```kotlin
PaymentSheet.Configuration.Builder(
  merchantDisplayName = "My app, Inc."
).build()
```

### 暗色模式

默认情况下，`PaymentSheet` 自动适应用户的整个系统的外观设置（明暗模式）。可通过在您的应用上设置亮色或暗色模式来更改：

#### Kotlin

```kotlin
// force dark
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
// force light
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
```

### 默认账单详情

要为支付表单中收集的账单详情设置默认值，请配置 `defaultBillingDetails` 属性。`paymentSheet` 会用您提供的值预先填充其字段。

#### Kotlin

```kotlin
val address = PaymentSheet.Address(country = "US")
val billingDetails = PaymentSheet.BillingDetails(
  address = address,
  email = "foo@bar.com"
)
val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Merchant, Inc.")
  .defaultBillingDetails(billingDetails)
  .build()
```

### 配置账单详情的收集

使用 `BillingDetailsCollectionConfiguration` 指定您希望在 PaymentSheet 中收集账单详情的方式。

可以收集客户的姓名、邮件地址、电话号码和地址。

完整的地址收集功能包含 Stripe 针对受支持国家/地区提供的自动完成功能，无需额外设置。

> 使用自动完成功能即表示您同意遵守 [Google Maps 平台可接受的使用政策](https://cloud.google.com/maps-platform/terms/aup)。如果您违反该政策，Stripe 可能会停用自动完成功能，或采取其他必要措施。

如果希望将默认账单详情关联到 PaymentMethod 对象（即使 UI 中未收集这些字段），请将 `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` 设置为 `true`。

#### Kotlin

```kotlin
val billingDetails = PaymentSheet.BillingDetails(
  email = "foo@bar.com"
)
val billingDetailsCollectionConfiguration = BillingDetailsCollectionConfiguration(
  attachDefaultsToPaymentMethod = true,
  name = BillingDetailsCollectionConfiguration.CollectionMode.Always,
  email = BillingDetailsCollectionConfiguration.CollectionMode.Never,
  address = BillingDetailsCollectionConfiguration.AddressCollectionMode.Full,
)
val configuration = PaymentSheet.Configuration.Builder(merchantDisplayName = "Merchant, Inc.")
  .defaultBillingDetails(billingDetails)
  .billingDetailsCollectionConfiguration(billingDetailsCollectionConfiguration)
  .build()
```

> 请咨询律师，了解与收集信息有关的法律。仅在需要收集号码来完成交易时，才收集手机号码。

## Optional: 在您的用户界面完成付款

您可以在出示支付表单时仅收集支付方式详情，然后再在您的应用的用户界面上完成付款。如果您使用的是自定义购买按钮或在收集了付款详情后要求额外的步骤，这会非常有用。
![](https://b.stripecdn.com/docs-statics-srv/assets/android-multi-step.84d8a0a44b1baa596bda491322b6d9fd.png)

> 集成示例参见 [GitHub](https://github.com/stripe/stripe-android/blob/master/paymentsheet-example/src/main/java/com/stripe/android/paymentsheet/example/samples/ui/paymentsheet/custom_flow/CustomFlowActivity.kt)。

1. 首先，用某个 [Builder](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/-builder/index.html) 方法初始化 [PaymentSheet.FlowController](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html)，而非 `PaymentSheet`。

#### Android (Kotlin)

```kotlin
class CheckoutActivity : AppCompatActivity() {
  private lateinit var flowController: PaymentSheet.FlowController

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val flowController = PaymentSheet.FlowController.Builder(
      resultCallback = ::onPaymentSheetResult,
      paymentOptionResultCallback = ::onPaymentOption,
    ).build(this)
  }
}
```

1. 接下来，使用从您的后端获取的 Stripe 对象密钥调用 `configureWithPaymentIntent`，并在回调中使用 [getPaymentOption()](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#-2091462043%2FFunctions%2F2002900378) 更新 UI，该支付方式选项包含代表客户当前所选支付方式的图片和标签。

#### Android (Kotlin)

```kotlin
flowController.configureWithPaymentIntent(
  paymentIntentClientSecret = paymentIntentClientSecret,
  configuration = PaymentSheet.Configuration.Builder("Example, Inc.")
    .customer(PaymentSheet.CustomerConfiguration(
      id = customerId,
      ephemeralKeySecret = ephemeralKeySecret
    ))
    .build()
) { isReady, error ->
  if (isReady) {
    // Update your UI using `flowController.getPaymentOption()`
  } else {
    // handle FlowController configuration failure
  }
}
```

1. 然后，调用 [presentPaymentOptions](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#449924733%2FFunctions%2F2002900378) 来收集付款详情。客户完成后，表单被丢弃，并调用之前在 `create` 中传入的 [paymentOptionCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-option-callback/index.html)。实施该方法，用返回的 `paymentOption` 更新您的 UI。

#### Android (Kotlin)

```kotlin
// ...
  flowController.presentPaymentOptions()
// ...
  private fun onPaymentOption(paymentOptionResult: PaymentOptionResult) {
    val paymentOption = paymentOptionResult.paymentOption
    if (paymentOption != null) {
      paymentMethodButton.text = paymentOption.label
      paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
        paymentOption.drawableResourceId,
        0,
        0,
        0
      )
    } else {
      paymentMethodButton.text = "Select"
      paymentMethodButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
        null,
        null,
        null,
        null
      )
    }
  }
```

1. 最后，调用 [confirm](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#-479056656%2FFunctions%2F2002900378)，完成付款。客户完成后，表单被丢弃，并调用之前在 `create` 中创建的 [paymentResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html#237248767%2FFunctions%2F2002900378)。

#### Android (Kotlin)

```kotlin
  // ...
    flowController.confirmPayment()
  // ...

  private fun onPaymentSheetResult(
    paymentSheetResult: PaymentSheetResult
  ) {
    when (paymentSheetResult) {
      is PaymentSheetResult.Canceled -> {
        // Payment canceled
      }
      is PaymentSheetResult.Failed -> {
        // Payment Failed. See logcat for details or inspect paymentSheetResult.error
      }
      is PaymentSheetResult.Completed -> {
        // Payment Complete
      }
    }
  }
```

将 `allowsDelayedPaymentMethods` 设置为 true，以允许[延迟通知型](https://docs.stripe.com/payments/payment-methods.md#payment-notification)支付方式，例如美国银行账户。对于这些支付方式，只有当 `PaymentSheet` 完成后才能知道最终的付款状态是成功还是失败。如果您支持这些类型的支付方式，请告知客户他们的订单已被确认，并且仅在付款成功时履行订单（例如，为他们安排发货）。

## Optional: 启用确认时的 CVC 重新收集流程

以下有关在确认 PaymentIntent 的过程中重新收集已保存卡的 CVC 的说明假定的是您的集成包含以下内容：

- 在收集支付详情之前创建 PaymentIntent

### 更新意图创建参数

要在确认付款时重新收集 CVC，请在创建 PaymentIntent 的过程中包含 `require_cvc_recollection`。

#### curl

```bash
# Create a Customer (use an existing Customer ID if this is a returning customer)
curl https://api.stripe.com/v1/customers \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -H "Stripe-Account: {{CONNECTED_ACCOUNT_ID}}"

# Create an Ephemeral Key for the Customer
curl https://api.stripe.com/v1/ephemeral_keys \
  -u <<YOUR_SECRET_KEY>>: \
  -H "Stripe-Version: 2026-10-28.endive" \
  -H "Stripe-Account: 2026-10-28.endive" \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \

# Create a PaymentIntent
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer"="{{CUSTOMER_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "payment_method_options[card][require_cvc_recollection]"=true \

  -d "automatic_payment_methods[enabled]"=true \
```

