# Guarda datos de pago durante un pago en la aplicación

Guarda los datos de pago durante un pago en tu aplicación móvil.

# iOS

> This is a iOS for when platform is ios and mobile-ui is payment-element. View the full page at https://docs.stripe.com/payments/mobile/save-during-payment?platform=ios&mobile-ui=payment-element.

Utiliza la [API Payment Intents](https://docs.stripe.com/api/payment_intents.md) para guardar los datos de pago de una compra. Tiene varios casos de uso:

- Cobrarle al cliente por un pedido de e-commerce y almacenar los datos para compras futuras.
- Iniciar el primer pago de una serie de pagos recurrentes.
- Cobrar un depósito y almacenar los datos para cobrar el importe total más tarde.

> #### Transacciones con tarjeta presente
> 
> Las transacciones con tarjeta presente, como los pagos a través de Stripe Terminal, utilizan un proceso diferente para guardar el método de pago. Para obtener más información, consulta [la documentación de Terminal](https://docs.stripe.com/terminal/features/saving-payment-details/save-after-payment.md).

## Cumplimiento de la normativa

Cuando guardes los datos de pago de un cliente para usarlos en el futuro, como mostrarle su método de pago en el flujo del proceso de compra para una compra futura o cobrarle cuando no esté usando activamente tu sitio web o aplicación, eres responsable de cumplir con todas las leyes, regulaciones y reglas de red que se apliquen. Antes de guardar o cobrar el método de pago de un cliente, asegúrate de:

- añadir a tu sitio web o aplicación condiciones que indiquen cómo piensas guardar los datos del método de pago, por ejemplo:
  - el consentimiento del cliente que te permite iniciar un pago o una serie de pagos en su nombre para transacciones específicas.
  - El momento y la frecuencia previstos de los pagos (por ejemplo, si los cargos son por cuotas programadas, pagos de suscripción o recargas no programadas).
  - Cómo determinas el importe del pago.
  - Tu política de cancelación, si el método de pago es para un servicio de suscripción.
- Usa un método de pago que guardado solo para lo que figura en tus condiciones.
- Consigue el consentimiento explícito del cliente para este uso específico. Por ejemplo, incluye una casilla de verificación «Guardar mi método de pago para futuras compras».
- Guarda un registro de la aceptación por escrito de estas condiciones por parte de tu cliente.

## Configura Stripe [Lado del servidor] [Lado del cliente]

Primero, necesitas una cuenta de Stripe. [Regístrate ahora](https://dashboard.stripe.com/register).

### Lado del servidor

Esta integración necesita puntos de conexión de tu servidor que se comuniquen con la API de Stripe. Usa nuestras bibliotecas oficiales para acceder a la API de Stripe desde tu servidor:

#### 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'
```

### Lado del cliente

El [SDK para iOS de Stripe](https://github.com/stripe/stripe-ios) es de código abierto, está [plenamente documentado](https://stripe.dev/stripe-ios/index.html) y es compatible con aplicaciones que admiten iOS 13 o posterior.

#### Administrador de paquetes Swift

Para instalar el SDK, sigue estos pasos:

1. En Xcode, elige **Archivo** > **Añadir dependencias de paquetes…** e introduce `https://github.com/stripe/stripe-ios-spm` como la URL del repositorio.
1. Selecciona el número de versión más reciente en nuestra [página de versiones](https://github.com/stripe/stripe-ios/releases).
1. Añade el producto **StripePaymentSheet** al [objetivo de tu aplicación](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app).

#### CocoaPods

1. Si aún no lo has hecho, instala la última versión de [CocoaPods](https://guides.cocoapods.org/using/getting-started.html).
1. Si no tienes un [Podfile](https://guides.cocoapods.org/syntax/podfile.html), ejecuta el siguiente comando para crear uno:
   ```bash
   pod init
   ```
1. Añade esta línea a tu `Podfile`:
   ```podfile
   pod 'StripePaymentSheet'
   ```
1. Ejecuta el siguiente comando:
   ```bash
   pod install
   ```
1. De ahora en adelante, no olvides usar el archivo `.xcworkspace` en lugar del archivo `.xcodeproj` para abrir tu proyecto en Xcode.
1. En el futuro, para actualizar a la última versión del SDK, ejecuta lo siguiente:
   ```bash
   pod update StripePaymentSheet
   ```

#### Carthage

1. Si aún no lo has hecho, instala la última versión de [Carthage](https://github.com/Carthage/Carthage#installing-carthage).
1. Añade esta línea a tu `Cartfile`:
   ```cartfile
   github "stripe/stripe-ios"
   ```
1. Sigue las [instrucciones de instalación de Carthage](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos). Asegúrate de incrustar todos los frameworks obligatorios enumerados [aquí](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking).
1. En el futuro, para actualizar a la última versión del SDK, ejecuta el siguiente comando:
   ```bash
   carthage update stripe-ios --platform ios
   ```

#### Plataforma manual

1. Ve a nuestra [página de versiones de GitHub](https://github.com/stripe/stripe-ios/releases/latest) y descarga y descomprime **Stripe.xcframework.zip**.
1. Arrastra **StripePaymentSheet.xcframework** a la sección **Binarios incrustados** de la configuración **General** de tu proyecto en Xcode. Asegúrate de seleccionar **Copiar elementos si es necesario**.
1. Repite el paso 2 para todos los frameworks obligatorios enumerados [here](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking).
1. En el futuro, para actualizar a la última versión de nuestro SDK, repite los pasos 1 a 3.

> Para obtener más información sobre la versión más reciente y sobre versiones anteriores del SDK, consulta la página [Versiones](https://github.com/stripe/stripe-ios/releases) en GitHub. Para recibir notificaciones cuando se publica una nueva versión, [consulta las versiones](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository) del repositorio.

## Habilitar los métodos de pago

Los pagos con tarjeta se habilitan de forma predeterminada. Consulta la [configuración de tus métodos de pago](https://dashboard.stripe.com/settings/payment_methods) para habilitar otros métodos de pago que quieras aceptar.

## Añadir un punto de conexión [Lado del servidor]

> #### Nota
> 
> Para mostrar la PaymentSheet antes de crear un PaymentIntent, consulta [Recolectar datos de pago antes de crear un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment).

Esta integración usa tres objetos de la API de Stripe:

1. [PaymentIntent](https://docs.stripe.com/api/payment_intents.md): Stripe usa este dato para representar tu intención de cobrarle a un cliente y hacer el seguimiento de los intentos de cobro y de los cambios en el estado del pago a lo largo del proceso.

1. (Opcional) Una [cuenta configurada por cliente](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-applied_configurations) o un [Cliente](https://docs.stripe.com/api/customers.md): para configurar un método de pago para futuros pagos, debes vincularlo a un cliente. Crea un objeto que represente a tu cliente cuando cree una cuenta en tu empresa. Si tu cliente hace un pago como invitado, puedes crear una `Cuenta` o `Cliente` antes del pago y asociarlo con tu propia representación interna de la cuenta del cliente más tarde.

1. (Opcional) {% /if %[CustomerSession](https://docs.stripe.com/api/customer_sessions.md): la información sobre el objeto que representa a tu cliente es confidencial y no se puede recuperar directamente desde una aplicación. Una `CustomerSession` otorga al SDK acceso temporal al alcance de la `Cuenta` o `Cliente` y proporciona opciones de configuración adicionales. Consulta una lista completa de [opciones de configuración](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components).

Por motivos de seguridad, tu aplicación no puede crear estos objetos. En su lugar, añade un punto de conexión en tu servidor que:

1. Recupera la `Cuenta` o `Cliente` o crea uno nuevo.
1. Crea una [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) para la `Cuenta` o `Cliente`.
1. Crea un `PaymentIntent` con el [importe](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount), [divisa](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-currency), [setup_future_usage](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-setup_future_usage), y la [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) o el [cliente](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer).
1. Devuelve el `PaymentIntent`*secreto de cliente* (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)), la `CustomerSession`, el `client_secret`, el ID de la `Cuenta` o `Cliente` y tu [clave publicable](https://dashboard.stripe.com/apikeys) en tu aplicación.

> El Payment Element móvil solo acepta `setup_future_usage` con tarjetas y cuentas bancarias de EE. UU.

Los métodos de pago que se muestran a los clientes durante el proceso de compra también se incluyen en el PaymentIntent. Puedes permitir que Stripe extraiga automáticamente los métodos de pago de la configuración de tu Dashboard o puedes enumerarlos de forma manual. Independientemente de la opción que elijas, debes saber que la divisa especificada en el PaymentIntent filtra los métodos de pago que se muestran al cliente. Por ejemplo, si especificas `eur` en el PaymentIntent y tienes habilitado OXXO en el Dashboard, OXXO no se mostrará al cliente porque no acepta pagos en `eur`.

A menos que tu integración requiera una opción basada en código para ofrecer métodos de pago, Stripe recomienda usar la opción automatizada. Esto se debe a que Stripe evalúa la divisa, las restricciones en cuanto a los métodos de pago y otros parámetros para determinar la lista de métodos de pago aceptados. Se da prioridad a los métodos de pago que aumentan la conversión y guardan mayor relación con la divisa y la ubicación del cliente.

#### Gestiona los métodos de pago desde el Dashboard

Puedes administrar los métodos de pago desde el [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe gestiona la devolución de métodos de pago que cumplen los requisitos según factores como el importe de la transacción, la divisa y el flujo de pago. El PaymentIntent se crea según los métodos de pago que configuraste en el Dashboard. Si no quieres usar el Dashboard o si quieres especificar métodos de pago manualmente, puedes enumerarlos usando el atributo `payment_method_types`.

#### Cuentas v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_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_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

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

#### Clientes v1

#### 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 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 "setup_future_usage"="off_session" \

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

#### Cómo enumerar métodos de pago manualmente

#### Cuentas v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_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_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

#### Clientes v1

#### 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 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 "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

> Cada método de pago debe aceptar la divisa especificada en el PaymentIntent, y tu empresa tiene que estar establecida en uno de los países que acepta cada método de pago. Consulta la página de [Opciones de integración de los métodos de pago](https://docs.stripe.com/payments/payment-methods/integration-options.md) para obtener más información sobre lo que se acepta.

## Recopilar los datos de pago [Lado del cliente]

Para mostrar el Mobile Payment Element en la pantalla del proceso de compra, asegúrate de lo siguiente:

- Muestra los productos que compra el cliente junto con el importe total.
- Usa el [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios) para recolectar la información de envío necesaria del cliente
- Añade un botón de finalización de compra para mostrar la interfaz de usuario de Stripe

#### UIKit

En la pantalla proceso de compra de tu aplicación, obtén el secreto de cliente Intent, el secreto de cliente CustomerSession, el ID de cliente y la clave publicable del punto de conexión que creaste en el paso anterior. Usa `STPAPIClient.shared` para establecer tu clave publicable e inicializar la [PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html).

#### iOS (Swift)

```swift
import UIKit@_spi(CustomerSessionBetaAccess) import StripePaymentSheet

class CheckoutViewController: UIViewController {
  @IBOutlet weak var checkoutButton: UIButton!
  var paymentSheet: PaymentSheet?
  let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint

  override func viewDidLoad() {
    super.viewDidLoad()

    checkoutButton.addTarget(self, action: #selector(didTapCheckoutButton), for: .touchUpInside)
    checkoutButton.isEnabled = false

    // MARK: Fetch the PaymentIntent client secret, CustomerSession client secret, Customer ID, and publishable key
    var request = URLRequest(url: backendCheckoutUrl)
    request.httpMethod = "POST"
    let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
      guard let data = data,
            let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any],
            let customerId = json["customer"] as? String,
            let customerSessionClientSecret = json["customerSessionClientSecret"] as? String,
            let paymentIntentClientSecret = json["paymentIntent"] as? String,
            let publishableKey = json["publishableKey"] as? String,
            let self = self else {
        // Handle error
        return
      }
STPAPIClient.shared.publishableKey = publishableKey// MARK: Create a PaymentSheet instance
      var configuration = PaymentSheet.Configuration()
      configuration.merchantDisplayName = "Example, Inc."
      configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret)
      // Set `allowsDelayedPaymentMethods` to true if your business handles
      // delayed notification payment methods like US bank accounts.
      configuration.allowsDelayedPaymentMethods = true
      self.paymentSheet = PaymentSheet(paymentIntentClientSecret:paymentIntentClientSecret, configuration: configuration)

      DispatchQueue.main.async {
        self.checkoutButton.isEnabled = true
      }
    })
    task.resume()
  }

}
```

Cuando el cliente toque el botón **Checkout**, llama a `present` para presentar la PaymentSheet. Después de que el cliente efectiviza el pago, Stripe cierra la PaymentSheet y llama al bloque de finalización con [PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html).

#### iOS (Swift)

```swift
@objc
func didTapCheckoutButton() {
  // MARK: Start the checkout process
  paymentSheet?.present(from: self) { paymentResult in
    // MARK: Handle the payment result
    switch paymentResult {
    case .completed:
      print("Your order is confirmed")
    case .canceled:
      print("Canceled!")
    case .failed(let error):
      print("Payment failed: \(error)")
    }
  }
}
```

#### SwiftUI

Crea un modelo de `ObservableObject` para tu pantalla del proceso de compra. Este modelo publica un [PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html) y un [PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html).

```swift
import StripePaymentSheet
import SwiftUI

class CheckoutViewModel: ObservableObject {
  let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint
  @Published var paymentSheet: PaymentSheet?
  @Published var paymentResult: PaymentSheetResult?
}
```

Obtén el secreto de cliente Intent, el secreto de cliente CustomerSession, el ID de cliente y la clave publicable del punto de conexión que creaste en el paso anterior. Utiliza `STPAPIClient.shared` para establecer tu clave publicable e inicializar la [PaymentSheet](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet.html).

```swift
@_spi(CustomerSessionBetaAccess) import StripePaymentSheet
import SwiftUI

class CheckoutViewModel: ObservableObject {
  let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint
  @Published var paymentSheet: PaymentSheet?
  @Published var paymentResult: PaymentSheetResult?
func preparePaymentSheet() {
    // MARK: Fetch thePaymentIntent and Customer information from the backend
    var request = URLRequest(url: backendCheckoutUrl)
    request.httpMethod = "POST"
    let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
      guard let data = data,
            let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any],
            let customerId = json["customer"] as? String,
            let customerSessionClientSecret = json["customerSessionClientSecret"] as? String,
            letpaymentIntentClientSecret = json["paymentIntent"] as? String,
            let publishableKey = json["publishableKey"] as? String,
            let self = self else {
        // Handle error
        return
      }

      STPAPIClient.shared.publishableKey = publishableKey// MARK: Create a PaymentSheet instance
      var configuration = PaymentSheet.Configuration()
      configuration.merchantDisplayName = "Example, Inc."
      configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret)
      // Set `allowsDelayedPaymentMethods` to true if your business handles
      // delayed notification payment methods like US bank accounts.
      configuration.allowsDelayedPaymentMethods = true

      DispatchQueue.main.async {
        self.paymentSheet = PaymentSheet(paymentIntentClientSecret:paymentIntentClientSecret, configuration: configuration)
      }
    })
    task.resume()
  }
}
struct CheckoutView: View {
  @ObservedObject var model = CheckoutViewModel()

  var body: some View {
    VStack {
      if model.paymentSheet != nil {
        Text("Ready to pay.")
      } else {
        Text("Loading…")
      }
    }.onAppear { model.preparePaymentSheet() }
  }
}
```

Añade un [PaymentSheet.PaymentButton](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/PaymentButton.html) a tu `View`. Esto se comporta de manera similar a un `Button` de SwiftUI, que te permite personalizarlo añadiendo una `View`. Al pulsar el botón, se muestra la PaymentSheet. Después de efectivizar el pago, Stripe cierra la PaymentSheet y llama al controlador `onCompletion` con un objeto [PaymentSheetResult](https://stripe.dev/stripe-ios/stripe-paymentsheet/Enums/PaymentSheetResult.html).

```swift
@_spi(CustomerSessionBetaAccess) import StripePaymentSheet
import SwiftUI

class CheckoutViewModel: ObservableObject {
  let backendCheckoutUrl = URL(string: "Your backend endpoint/payment-sheet")! // Your backend endpoint
  @Published var paymentSheet: PaymentSheet?
  @Published var paymentResult: PaymentSheetResult?

  func preparePaymentSheet() {
    // MARK: Fetch the PaymentIntent and Customer information from the backend
    var request = URLRequest(url: backendCheckoutUrl)
    request.httpMethod = "POST"
    let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
      guard let data = data,
            let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any],
            let customerId = json["customer"] as? String,
            let customerSessionClientSecret = json["customerSessionClientSecret"] as? String,
            let paymentIntentClientSecret = json["paymentIntent"] as? String,
            let publishableKey = json["publishableKey"] as? String,
            let self = self else {
        // Handle error
        return
      }

      STPAPIClient.shared.publishableKey = publishableKey
      // MARK: Create a PaymentSheet instance
      var configuration = PaymentSheet.Configuration()
      configuration.merchantDisplayName = "Example, Inc."
      configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret)
      // Set `allowsDelayedPaymentMethods` to true if your business can handle payment methods
      // that complete payment after a delay, like SEPA Debit and Sofort.
      configuration.allowsDelayedPaymentMethods = true

      DispatchQueue.main.async {
        self.paymentSheet = PaymentSheet(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration)
      }
    })
    task.resume()
  }
func onPaymentCompletion(result: PaymentSheetResult) {
    self.paymentResult = result
  }
}

struct CheckoutView: View {
  @ObservedObject var model = CheckoutViewModel()

  var body: some View {
    VStack {if let paymentSheet = model.paymentSheet {
        PaymentSheet.PaymentButton(
          paymentSheet: paymentSheet,
          onCompletion: model.onPaymentCompletion
        ) {
          Text("Buy")
        }
      } else {
        Text("Loading…")
      }if let result = model.paymentResult {
        switch result {
        case .completed:
          Text("Payment complete")
        case .failed(let error):
          Text("Payment failed: \(error.localizedDescription)")
        case .canceled:
          Text("Payment canceled.")
        }
      }
    }.onAppear { model.preparePaymentSheet() }
  }
}
```

Si el `PaymentSheetResult` es `.completed`, comunícaselo al usuario (por ejemplo, mostrándole una pantalla de confirmación del pedido).

Establecer `allowsDelayedPaymentMethods` en true permite utilizar métodos de pago de [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification) como cuentas bancarias de EE.&nbsp;UU. Para estos métodos de pago, el estado final del pago no se conoce cuando se completa la `PaymentSheet`, sino que se efectúa correctamente o con errores más tarde. Si aceptas este tipo de métodos de pago, infórmale al cliente de que su pedido está confirmado y solo complétalo (por ejemplo, envía el producto) cuando el pago se haya realizado correctamente.

## Configura una URL de retorno [Lado del cliente]

Es posible que el cliente salga de tu aplicación para autenticarse (por ejemplo, en Safari o en su aplicación bancaria). Para permitirles volver automáticamente a tu aplicación después de la autenticación, [configura un esquema de URL personalizado](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) y configura el delegado de la aplicación para que envíe la URL al SDK. Stripe no admite [enlaces universales](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content).

#### SceneDelegate

#### Swift

```swift
// This method handles opening custom URL schemes (for example, "your-app://stripe-redirect")
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    guard let url = URLContexts.first?.url else {
        return
    }
    let stripeHandled = StripeAPI.handleURLCallback(with: url)
    if (!stripeHandled) {
        // This was not a Stripe url – handle the URL normally as you would
    }
}

```

#### AppDelegate

#### Swift

```swift
// This method handles opening custom URL schemes (for example, "your-app://stripe-redirect")
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    let stripeHandled = StripeAPI.handleURLCallback(with: url)
    if (stripeHandled) {
        return true
    } else {
        // This was not a Stripe url – handle the URL normally as you would
    }
    return false
}
```

#### SwiftUI

#### Swift

```swift

@main
struct MyApp: App {
  var body: some Scene {
    WindowGroup {
      Text("Hello, world!").onOpenURL { incomingURL in
          let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL)
          if (!stripeHandled) {
            // This was not a Stripe url – handle the URL normally as you would
          }
        }
    }
  }
}
```

Además, establece la [returnURL](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV9returnURLSSSgvp) en tu objeto [PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html) en la URL de tu aplicación.

```swift
var configuration = PaymentSheet.Configuration()
configuration.returnURL = "your-app://stripe-redirect"
```

## Gestionar eventos posteriores al pago [Lado del servidor]

Stripe envía un evento [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) cuando se efectiviza el pago. Usa la [herramienta webhook del Dashboard](https://dashboard.stripe.com/webhooks) o sigue las indicaciones de la [guía de webhooks](https://docs.stripe.com/webhooks/quickstart.md) para recibir estos eventos y acciones de ejecución, como enviar a tu cliente un correo electrónico de confirmación del pedido, registrar la venta en una base de datos o iniciar el flujo de trabajo de los envíos.

Escucha estos eventos en lugar de esperar una devolución de llamada del cliente. Por su parte, el cliente puede cerrar la ventana del navegador o salir de la aplicación antes de que se ejecute la devolución de llamada. Si configuras tu integración para escuchar eventos asincrónicos, podrás aceptar [diferentes tipos de métodos de pago](https://stripe.com/payments/payment-methods-guide) con una sola integración.

Además de administrar el evento `payment_intent.succeeded`, recomendamos administrar estos otros eventos si se cobran pagos con el Payment Element:

| Evento                                                                                                                          | Descripción                                                                                                                                                                                                                                                                                  | Acción                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded)           | Se envía cuando un cliente completa correctamente un pago.                                                                                                                                                                                                                                   | Envía al cliente una confirmación del pedido y *completa* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) el pedido.         |
| [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing)         | Se envía cuando el cliente inicia el pago correctamente, pero este aún no se ha efectivizado. En la mayoría de los casos, este evento se envía cuando el cliente inicia un adeudo bancario. Más adelante, le seguirá el evento `payment_intent.succeeded` o `payment_intent.payment_failed`. | Envía al cliente una confirmación del pedido que indique que su pago está pendiente. Para los productos digitales, es posible que desees completar el pedido antes de esperar a que se efectivice el pago. |
| [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Se envía cuando el cliente intenta realizar un pago, pero este falla.                                                                                                                                                                                                                        | Si un pago pasa de `processing` a `payment_failed`, ofrécele al cliente otro intento de pago.                                                                                                              |

## Cobra al PaymentMethod guardado más tarde [Lado del servidor]

> #### Cumplimiento de la normativa
> 
> Al guardar los datos de pago de un cliente, eres responsable de cumplir con todas las leyes, normativas y reglas de red aplicables. Al mostrar métodos de pago anteriores a tu cliente final para compras futuras, asegúrate de incluir solo aquellos para los que hayas obtenido su consentimiento para guardar los detalles del método de pago con ese fin específico. Para diferenciar entre los métodos de pago adjuntos a los clientes que pueden y no pueden presentarse a tu cliente final como un método de pago guardado para futuras compras, utiliza el parámetro [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay).

Para encontrar un método para pagar para cobrar, enumera los métodos de pago asociados a tu cliente. En este ejemplo se enumeran las tarjetas, pero puedes enumerar cualquier [tipo](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) aceptado.

> #### Usa la API Accounts v2 para representar a los clientes
> 
> La API Accounts v2 suele estar disponible para los usuarios de Connect y en vista previa pública para otros usuarios de Stripe. Si tienes acceso a la vista previa de Accounts v2, debes especificar [vista previa](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) en tu código.
> 
> Para solicitar acceso a la vista previa de Accounts v2, 
> 
> En la mayoría de los casos de uso, recomendamos [modelar a tus clientes como objetos Cuenta](https://docs.stripe.com/connect/use-accounts-as-customers.md) configurados por el cliente en lugar de usar objetos [Cliente](https://docs.stripe.com/api/customers.md).

#### Cuentas v2

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d type=card
```

#### Clientes v1

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d type=card
```

Cuando estés listo para cobrar a tu cliente *fuera de la sesión* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information), usa el ID del cliente y el ID del `PaymentMethod` para crear un `PymentIntent` con el importe y divisas del pago. Establece otros parámetros para efectuar el pago fuera de la sesión:

- Define [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) como `true` para indicar que el cliente no está en tu flujo del proceso de compra durante un intento de pago y no puede completar una petición de autenticación realizada por un socio, como un emisor de tarjeta, un banco u otra institución de pago. Si, durante tu flujo del proceso de compra, un socio solicita autenticación, Stripe solicita exenciones utilizando información del cliente de una transacción anterior de *durante la sesión* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method). Si no se cumplen las condiciones de exención, el `PaymentIntent` podría generar un error.
- Establece el valor de la propiedad [confirmar](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) del `PaymentIntent` como verdadero, lo que hace que la confirmación se produzca inmediatamente al crear el `PaymentIntent`.
- Establece [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) en el ID del `PaymentMethod`.
- Dependiendo de cómo representes a los clientes en tu integración, establece [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) en el ID de la `cuenta` configurada por el cliente o [cliente](https://docs.stripe.com/api.md#create_payment_intent-customer) en el ID del `cliente`.

#### Cuentas v2

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

#### Clientes v1

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer={{CUSTOMER_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

## Prueba la integración

#### Tarjetas

| Método de pago     | Situación                                                                                                                                                                                                                                                                                                                                | Cómo hacer la prueba                                                                                                                                 |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tarjeta de crédito | La configuración de la tarjeta se realiza correctamente y no requiere *autenticación* (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). | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta requiere autenticación para la configuración inicial, pero no para los pagos posteriores.                                                                                                                                                                                                                                     | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta requiere autenticación para la configuración inicial y también para los pagos posteriores.                                                                                                                                                                                                                                    | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0027 6000 3184` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta se ha rechazado durante la configuración.                                                                                                                                                                                                                                                                                     | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de caducidad, CVC y código postal. |

## Optional: Habilita Apple Pay

> Si tu pantalla del proceso de compra tiene un **botón de Apple Pay** específico, sigue la [guía de Apple Pay](https://docs.stripe.com/apple-pay.md#present-payment-sheet) y utiliza `ApplePayContext` para cobrar el pago desde tu botón de Apple Pay. Puedes usar `PaymentSheet` para gestionar otros tipos de métodos de pago.

### Regístrate para obtener un ID de comerciante de Apple

Obtén un ID de comerciante Apple [registrándote para obtener un nuevo identificador](https://developer.apple.com/account/resources/identifiers/add/merchant) en el sitio web de Apple para desarrolladores.

Rellena el formulario incluyendo una descripción y el identificador. La descripción es solo para ti y podrás modificarla después. Stripe te recomienda que uses como identificador el nombre de tu aplicación (por ejemplo, `merchant.com.{{YOUR_APP_NAME}}`).

### Crear un nuevo certificado de Apple Pay

Crea un certificado para que tu aplicación cifre los datos de pago.

Ve a [Configuración de certificados de iOS](https://dashboard.stripe.com/settings/ios_certificates) en el Dashboard, haz clic en **Añadir aplicación nueva** y sigue las indicaciones.

Descarga un archivo de petición de firma de certificado (CSR) para obtener un certificado seguro de Apple que te permita utilizar Apple Pay.

Se debe usar un archivo CSR para emitir un certificado de manera exacta. Si cambias tu ID de comerciante de Apple, debes ir a la [Configuración de certificados de iOS](https://dashboard.stripe.com/settings/ios_certificates) en el Dashboard para obtener un CSR y un certificado nuevos.

### Integrar con Xcode

Añade la funcionalidad Apple Pay a tu aplicación. En Xcode, abre la configuración del proyecto, selecciona la pestaña **Firma y funcionalidades** y añade la funcionalidad **Apple Pay**. Aquí, es posible que se te pida que inicies sesión en tu cuenta de desarrollador. Selecciona el ID de comerciante que creaste antes, y tu aplicación estará lista para aceptar Apple Pay.
![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png)

Habilita la funcionalidad Apple Pay en Xcode

### Añadir Apple Pay

#### Pago único

Para añadir Apple Pay a PaymentSheet, establece [applePay](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV8applePayAC05ApplefD0VSgvp) después de iniciar `PaymentSheet.Configuration` con tu ID de comerciante de Apple y el [código de país de tu empresa](https://dashboard.stripe.com/settings/account).

#### iOS (Swift)

```swift
var configuration = PaymentSheet.Configuration()
configuration.applePay = .init(
  merchantId: "merchant.com.your_app_name",
  merchantCountryCode: "US"
)
```

#### Pagos recurrentes

Para añadir Apple Pay a PaymentSheet, establece [applePay](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV8applePayAC05ApplefD0VSgvp) después de iniciar `PaymentSheet.Configuration` con tu ID de comerciante de Apple y el [código de país de tu empresa](https://dashboard.stripe.com/settings/account).

De acuerdo con [las directrices de Apple](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) para pagos recurrentes, también debes establecer más atributos en `PKPaymentRequest`. Añade un controlador en [ApplePayConfiguration.paymentRequestHandlers](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/paymentrequesthandler) para configurar [PKPaymentRequest.paymentSummaryItems](https://developer.apple.com/documentation/passkit/pkpaymentrequest/1619231-paymentsummaryitems) con el importe que quieres cobrar (por ejemplo, 9,95&nbsp;USD al mes).

También puedes adoptar [tokens de comerciante](https://developer.apple.com/apple-pay/merchant-tokens/) estableciendo las propiedades `recurringPaymentRequest` o `automaticReloadPaymentRequest` en la `PKPaymentRequest`.

Para obtener más información sobre cómo usar los pagos recurrentes con Apple Pay, consulta [Documentación de Apple sobre PassKit](https://developer.apple.com/documentation/passkit/pkpaymentrequest).

#### iOS (Swift)

```swift
let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers(
    paymentRequestHandler: { request in
        // PKRecurringPaymentSummaryItem is available on iOS 15 or later
        if #available(iOS 15.0, *) {
            let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99"))

            // Payment starts today
            billing.startDate = Date()

            // Payment ends in one year
            billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365)

            // Pay once a month.
            billing.intervalUnit = .month
            billing.intervalCount = 1

            // recurringPaymentRequest is only available on iOS 16 or later
            if #available(iOS 16.0, *) {
                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]
            request.currencyCode = "USD"
        } else {
            // On older iOS versions, set alternative summary items.
            request.paymentSummaryItems = [PKPaymentSummaryItem(label: "Monthly plan starting July 1, 2022", amount: NSDecimalNumber(string: "59.99"), type: .final)]
        }
        return request
    }
)
var configuration = PaymentSheet.Configuration()
configuration.applePay = .init(merchantId: "merchant.com.your_app_name",
                                merchantCountryCode: "US",
                                customHandlers: customHandlers)
```

### Seguimiento de pedidos

Para añadir información de [seguimiento de pedidos](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) en iOS&nbsp;16 o versiones posteriores, configura un [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) en tu `PaymentSheet.ApplePayConfiguration.Handlers`. Stripe llama a tu implementación después de que se haya efectivizado el pago, pero antes de que iOS descarte la hoja de Apple Pay.

En la implementación de `authorizationResultHandler`, obtén los detalles del pedido del servidor para el pedido completado. Añade los datos al [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult) y devuelve el resultado modificado.

Para obtener más información sobre el seguimiento de pedidos, consulta [Documentación de Apple sobre los pedidos por monedero](https://developer.apple.com/documentation/walletorders).

#### iOS (Swift)

```swift
let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers(
    authorizationResultHandler: { result in
      do {
        // Fetch the order details from your service
        let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: orderID)
        result.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 result
      } catch {
        return PKPaymentAuthorizationResult(status: .failure, errors: [error])
      }
    }
)
var configuration = PaymentSheet.Configuration()
configuration.applePay = .init(merchantId: "merchant.com.your_app_name",
                               merchantCountryCode: "US",
                               customHandlers: customHandlers)
```

## Habilita el escaneo de tarjetas

Para habilitar la compatibilidad con el escaneo de tarjetas en iOS, establece la `NSCameraUsageDescription` (**Privacidad - Descripción del uso de la cámara**) en la `Info.plist` de tu aplicación, y proporciona un motivo para acceder a la cámara (por ejemplo, “Escanear tarjetas”).

## Optional: Personaliza la hoja

Todo lo que se quieras personalizar se configura mediante el objeto [PaymentSheet.Configuration](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html).

### Aspecto

Personaliza los colores, las fuentes, etc. para que coincidan con el aspecto de tu aplicación mediante la [API de apariencia](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios).

### Diseño del método de pago

Configura el diseño de los métodos de pago en la hoja usando [paymentMethodLayout](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/configuration-swift.struct/paymentmethodlayout). Puedes mostrarlos horizontalmente, verticalmente o dejar que Stripe optimice el diseño automáticamente.
![](https://b.stripecdn.com/docs-statics-srv/assets/ios-mpe-payment-method-layouts.9d0513e2fcec5660378ba1824d952054.png)

#### Swift

```swift
var configuration = PaymentSheet.Configuration()
configuration.paymentMethodLayout = .automatic
```

### Recopilar direcciones de usuarios

Recolecta las direcciones de envío o facturación locales e internacionales de tus clientes usando el [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios).

### Nombre con el que aparecerá el comerciante

Configura [merchantDisplayName](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:18StripePaymentSheet0bC0C13ConfigurationV19merchantDisplayNameSSvp) para especificar el nombre de empresa que quieres que vea el cliente. De forma predeterminada, este es el nombre de tu aplicación.

#### Swift

```swift
var configuration = PaymentSheet.Configuration()
configuration.merchantDisplayName = "My app, Inc."
```

### Modo oscuro

`PaymentSheet` se adapta automáticamente a la configuración de aspecto de todo el sistema del usuario (modo claro y modo oscuro). Si tu aplicación no acepta el modo oscuro, puedes establecer el [estilo](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:18StripePaymentSheet0bC0C13ConfigurationV5styleAC18UserInterfaceStyleOvp) en modo `alwaysLight` o `alwaysDark`.

```swift
var configuration = PaymentSheet.Configuration()
configuration.style = .alwaysLight
```

### Datos de facturación predeterminados

Para establecer los valores predeterminados para los datos de facturación recopilados en la hoja de pago, configura la propiedad `defaultBillingDetails`. Los campos de la `PaymentSheet` se rellenan automáticamente con los valores que proporcionas.

```swift
var configuration = PaymentSheet.Configuration()
configuration.defaultBillingDetails.address.country = "US"
configuration.defaultBillingDetails.email = "foo@bar.com"
```

### Recopilación de los datos de facturación

Utiliza `billingDetailsCollectionConfiguration` para especificar cómo deseas recopilar los detalles de facturación en la hoja de pago.

Puedes recopilar el nombre, el correo electrónico, el número de teléfono y la dirección del cliente.

Si solo quieres los datos de facturación requeridos por el método de pago, establece `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` como verdadero. En ese caso, los `PaymentSheet.Configuration.defaultBillingDetails` se establecen como los [detalles de facturación](https://docs.stripe.com/api/payment_methods/object.md?lang=node#payment_method_object-billing_details) del método de pago.

Si quieres recolectar detalles de facturación adicionales que no son necesariamente requeridos por el método de pago, establece `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` como falso. En ese caso, los detalles de facturación recolectados a través de la `PaymentSheet` se establecen como los detalles de facturación del método de pago.

```swift
var configuration = PaymentSheet.Configuration()
configuration.defaultBillingDetails.email = "foo@bar.com"
configuration.billingDetailsCollectionConfiguration.name = .always
configuration.billingDetailsCollectionConfiguration.email = .never
configuration.billingDetailsCollectionConfiguration.address = .full
configuration.billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod = true
```

> Consulta a tu asesor legal sobre las leyes que se aplican a la recopilación de información. Recopila los números de teléfono solo si los necesitas para la transacción.

## Optional: Efectiviza el pago en tu interfaz de usuario

Puedes presentar la hoja de pago para recopilar solo los datos del método de pago y después llamar al método `confirm` para completar el pago en la interfaz de usuario de tu aplicación. Esto resulta útil si tienes un botón de compra personalizado o solicitas pasos adicionales después de que se recopilen los datos de pago.
![](https://b.stripecdn.com/docs-statics-srv/assets/ios-multi-step.cd631ea4f1cd8cf3f39b6b9e1e92b6c5.png)

Efectiviza el pago en la interfaz de usuario de tu aplicación

#### UIKit

Los siguientes pasos te guían a través del proceso para efectivizar el pago en la interfaz de usuario de tu aplicación. Consulta nuestro ejemplo de integración en [GitHub](https://github.com/stripe/stripe-ios/blob/master/Example/PaymentSheet%20Example/PaymentSheet%20Example/ExampleCustomCheckoutViewController.swift).

1. Primero, inicializa [PaymentSheet.FlowController](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller) en lugar de `PaymentSheet` y actualiza tu interfaz de usuario con su propiedad `paymentOption`. Esta propiedad contiene una imagen y una etiqueta que representan el método de pago predeterminado seleccionado inicialmente por el cliente.

```swift
PaymentSheet.FlowController.create(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) { [weak self] result in
  switch result {
  case .failure(let error):
    print(error)
  case .success(let paymentSheetFlowController):
    self?.paymentSheetFlowController = paymentSheetFlowController
    // Update your UI using paymentSheetFlowController.paymentOption
  }
}
```

1. A continuación, llama a `presentPaymentOptions` para recopilar los datos del pago. Cuando se complete, actualiza nuevamente tu interfaz de usuario con la propiedad `paymentOption`.

```swift
paymentSheetFlowController.presentPaymentOptions(from: self) {
  // Update your UI using paymentSheetFlowController.paymentOption
}
```

1. Por último, llama a `confirm`.

```swift
paymentSheetFlowController.confirm(from: self) { paymentResult in
  // MARK: Handle the payment result
  switch paymentResult {
  case .completed:
    print("Payment complete!")
  case .canceled:
    print("Canceled!")
  case .failed(let error):
    print(error)
  }
}
```

#### SwiftUI

Los siguientes pasos te guían a través del proceso para efectivizar el pago en la interfaz de usuario de tu aplicación. Consulta nuestro ejemplo de integración en [GitHub](https://github.com/stripe/stripe-ios/blob/master/Example/PaymentSheet%20Example/PaymentSheet%20Example/ExampleSwiftUICustomPaymentFlow.swift).

1. Primero, inicializa [PaymentSheet.FlowController](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller) en lugar de `PaymentSheet`. Su propiedad `paymentOption` contiene una imagen y una etiqueta que representa el método de pago actualmente seleccionado por el cliente y que puedes utilizar en tu interfaz de usuario.

```swift
PaymentSheet.FlowController.create(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration) { [weak self] result in
  switch result {
  case .failure(let error):
    print(error)
  case .success(let paymentSheetFlowController):
    self?.paymentSheetFlowController = paymentSheetFlowController
    // Use the paymentSheetFlowController.paymentOption properties in your UI
    myPaymentMethodLabel = paymentSheetFlowController.paymentOption?.label ?? "Select a payment method"
    myPaymentMethodImage = paymentSheetFlowController.paymentOption?.image ?? UIImage(systemName: "square.and.pencil")!
  }
}
```

1. Usa [PaymentSheet.FlowController.PaymentOptionsButton](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/paymentoptionsbutton) para integrar el botón que presenta la hoja para recoger los datos de pago. Cuando `PaymentSheet.FlowController` llama al argumento `onSheetDismissed`, el `paymentOption` de la instancia `PaymentSheet.FlowController` refleja el método de pago seleccionado en ese momento.

```swift
PaymentSheet.FlowController.PaymentOptionsButton(
  paymentSheetFlowController: paymentSheetFlowController,
  onSheetDismissed: {
    myPaymentMethodLabel = paymentSheetFlowController.paymentOption?.label ?? "Select a payment method"
    myPaymentMethodImage = paymentSheetFlowController.paymentOption?.image ?? UIImage(systemName: "square.and.pencil")!
  },
  content: {
    /* An example button */
    HStack {
      Text(myPaymentMethodLabel)
      Image(uiImage: myPaymentMethodImage)
    }
  }
)
```

1. Usa [PaymentSheet.FlowController.PaymentOptionsButton](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/flowcontroller/paymentoptionsbutton) para ajustar el botón que confirma el pago.

```swift
PaymentSheet.FlowController.ConfirmButton(
  paymentSheetFlowController: paymentSheetFlowController,
  onCompletion: { result in
    // MARK: Handle the payment result
    switch result {
    case .completed:
      print("Payment complete!")
    case .canceled:
      print("Canceled!")
    case .failed(let error):
      print(error)
    }
  },
  content: {
    /* An example button */
    Text("Pay")
  }
)
```

Establecer `allowsDelayedPaymentMethods` en true permite utilizar métodos de pago de [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification) como cuentas bancarias de EE.&nbsp;UU. Para estos métodos de pago, el estado final del pago no se conoce cuando se completa la `PaymentSheet`, sino que se efectúa correctamente o con errores más tarde. Si aceptas este tipo de métodos de pago, infórmale al cliente de que su pedido está confirmado y solo complétalo (por ejemplo, envía el producto) cuando el pago se haya realizado correctamente.


# Android

> This is a Android for when platform is android and mobile-ui is payment-element. View the full page at https://docs.stripe.com/payments/mobile/save-during-payment?platform=android&mobile-ui=payment-element.

Utiliza la [API Payment Intents](https://docs.stripe.com/api/payment_intents.md) para guardar los datos de pago de una compra. Tiene varios casos de uso:

- Cobrarle al cliente por un pedido de e-commerce y almacenar los datos para compras futuras.
- Iniciar el primer pago de una serie de pagos recurrentes.
- Cobrar un depósito y almacenar los datos para cobrar el importe total más tarde.

> #### Transacciones con tarjeta presente
> 
> Las transacciones con tarjeta presente, como los pagos a través de Stripe Terminal, utilizan un proceso diferente para guardar el método de pago. Para obtener más información, consulta [la documentación de Terminal](https://docs.stripe.com/terminal/features/saving-payment-details/save-after-payment.md).

## Cumplimiento de la normativa

Cuando guardes los datos de pago de un cliente para usarlos en el futuro, como mostrarle su método de pago en el flujo del proceso de compra para una compra futura o cobrarle cuando no esté usando activamente tu sitio web o aplicación, eres responsable de cumplir con todas las leyes, regulaciones y reglas de red que se apliquen. Antes de guardar o cobrar el método de pago de un cliente, asegúrate de:

- añadir a tu sitio web o aplicación condiciones que indiquen cómo piensas guardar los datos del método de pago, por ejemplo:
  - el consentimiento del cliente que te permite iniciar un pago o una serie de pagos en su nombre para transacciones específicas.
  - El momento y la frecuencia previstos de los pagos (por ejemplo, si los cargos son por cuotas programadas, pagos de suscripción o recargas no programadas).
  - Cómo determinas el importe del pago.
  - Tu política de cancelación, si el método de pago es para un servicio de suscripción.
- Usa un método de pago que guardado solo para lo que figura en tus condiciones.
- Consigue el consentimiento explícito del cliente para este uso específico. Por ejemplo, incluye una casilla de verificación «Guardar mi método de pago para futuras compras».
- Guarda un registro de la aceptación por escrito de estas condiciones por parte de tu cliente.

## Configura Stripe [Lado del servidor] [Lado del cliente]

Primero, necesitas una cuenta de Stripe. [Regístrate ahora](https://dashboard.stripe.com/register).

### Lado del servidor

Esta integración necesita puntos de conexión en tu servidor que se comuniquen con la API de Stripe. Utiliza las bibliotecas oficiales para acceder a la API de Stripe desde tu servidor:

#### 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'
```

### Lado del cliente

El [SDK para Android de Stripe](https://github.com/stripe/stripe-android) es de código abierto y está [completamente documentado](https://stripe.dev/stripe-android/).

Para instalar el SDK, añade `stripe-android` al bloque `dependencies` de tu archivo [app/build.gradle](https://developer.android.com/studio/build/dependencies):

#### Kotlin

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

android { ... }

dependencies {
  // ...

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

> Para conocer detalles de la última versión y de versiones anteriores del SDK, consulta la página [Versiones](https://github.com/stripe/stripe-android/releases) de GitHub. Para recibir una notificación cuando se publique una nueva versión, [mira las versiones del repositorio](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository).

## Habilitar los métodos de pago

Los pagos con tarjeta se habilitan de forma predeterminada. Consulta la [configuración de tus métodos de pago](https://dashboard.stripe.com/settings/payment_methods) para habilitar otros métodos de pago que quieras aceptar.

## Añadir un punto de conexión [Lado del servidor]

> #### Nota
> 
> Para mostrar la PaymentSheet antes de crear un PaymentIntent, consulta [Recolectar datos de pago antes de crear un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment).

Esta integración usa tres objetos de la API de Stripe:

1. [PaymentIntent](https://docs.stripe.com/api/payment_intents.md): Stripe usa este dato para representar tu intención de cobrarle a un cliente y hacer el seguimiento de los intentos de cobro y de los cambios en el estado del pago a lo largo del proceso.

1. (Opcional) Una [cuenta configurada por cliente](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-applied_configurations) o un [Cliente](https://docs.stripe.com/api/customers.md): para configurar un método de pago para futuros pagos, debes vincularlo a un cliente. Crea un objeto que represente a tu cliente cuando cree una cuenta en tu empresa. Si tu cliente hace un pago como invitado, puedes crear una `Cuenta` o `Cliente` antes del pago y asociarlo con tu propia representación interna de la cuenta del cliente más tarde.

1. (Opcional) {% /if %[CustomerSession](https://docs.stripe.com/api/customer_sessions.md): la información sobre el objeto que representa a tu cliente es confidencial y no se puede recuperar directamente desde una aplicación. Una `CustomerSession` otorga al SDK acceso temporal al alcance de la `Cuenta` o `Cliente` y proporciona opciones de configuración adicionales. Consulta una lista completa de [opciones de configuración](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components).

Por motivos de seguridad, tu aplicación no puede crear estos objetos. En su lugar, añade un punto de conexión en tu servidor que:

1. Recupera la `Cuenta` o `Cliente` o crea uno nuevo.
1. Crea una [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) para la `Cuenta` o `Cliente`.
1. Crea un `PaymentIntent` con el [importe](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount), [divisa](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-currency), [setup_future_usage](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-setup_future_usage), y la [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) o el [cliente](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer).
1. Devuelve el `PaymentIntent`*secreto de cliente* (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)), la `CustomerSession`, el `client_secret`, el ID de la `Cuenta` o `Cliente` y tu [clave publicable](https://dashboard.stripe.com/apikeys) en tu aplicación.

> El Payment Element móvil solo acepta `setup_future_usage` con tarjetas y cuentas bancarias de EE. UU.

Los métodos de pago que se muestran a los clientes durante el proceso de compra también se incluyen en el PaymentIntent. Puedes permitir que Stripe extraiga automáticamente los métodos de pago de la configuración de tu Dashboard o puedes enumerarlos de forma manual. Independientemente de la opción que elijas, debes saber que la divisa especificada en el PaymentIntent filtra los métodos de pago que se muestran al cliente. Por ejemplo, si especificas `eur` en el PaymentIntent y tienes habilitado OXXO en el Dashboard, OXXO no se mostrará al cliente porque no acepta pagos en `eur`.

A menos que tu integración requiera una opción basada en código para ofrecer métodos de pago, Stripe recomienda usar la opción automatizada. Esto se debe a que Stripe evalúa la divisa, las restricciones en cuanto a los métodos de pago y otros parámetros para determinar la lista de métodos de pago aceptados. Se da prioridad a los métodos de pago que aumentan la conversión y guardan mayor relación con la divisa y la ubicación del cliente.

#### Gestiona los métodos de pago desde el Dashboard

Puedes administrar los métodos de pago desde el [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe gestiona la devolución de métodos de pago que cumplen los requisitos según factores como el importe de la transacción, la divisa y el flujo de pago. El PaymentIntent se crea según los métodos de pago que configuraste en el Dashboard. Si no quieres usar el Dashboard o si quieres especificar métodos de pago manualmente, puedes enumerarlos usando el atributo `payment_method_types`.

#### Cuentas v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_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_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

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

#### Clientes v1

#### 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 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 "setup_future_usage"="off_session" \

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

#### Cómo enumerar métodos de pago manualmente

#### Cuentas v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_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_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

#### Clientes v1

#### 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 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 "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

> Cada método de pago debe aceptar la divisa especificada en el PaymentIntent, y tu empresa tiene que estar establecida en uno de los países que acepta cada método de pago. Consulta la página de [Opciones de integración de los métodos de pago](https://docs.stripe.com/payments/payment-methods/integration-options.md) para obtener más información sobre lo que se acepta.

## Recopilar los datos de pago [Lado del cliente]

Antes de mostrar el Payment Element móvil, tu página de proceso de compra debe:

- Mostrar los productos comprados y el importe total
- Recopila la información de envío requerida usando el [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android)
- Incluir un botón de checkout para presentar la interfaz de usuario de Stripe

#### Jetpack Compose

[Inicializa](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-builder/index.html) una instancia `PaymentSheet` dentro de `onCreate` de tu Actividad de proceso de compra, pasando un método para gestionar el resultado.

```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
}
```

A continuación, obtén el secreto de cliente del PaymentIntent, el secreto del cliente de la sesión del cliente, el ID del cliente y la clave publicable del punto de conexión que creaste en el paso anterior. Establece la clave publicable mediante `PaymentConfiguration` y guarda las otras para usarlas cuando presentes la PaymentSheet.

```kotlin
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberimport 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
}
```

Cuando el cliente pulse el botón de checkout, llama a [presentWithPaymentIntent](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#1814490530%2FFunctions%2F2002900378) para presentar la hoja de pago. Una vez que el cliente completa el pago, la hoja se cierra y se llama a [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html) con un [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/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")
    }
  }
}
```

#### Vistas (clásico)

[Inicializa](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#-394860221%2FConstructors%2F2002900378) una instancia `PaymentSheet` dentro de `onCreate` de tu Actividad de proceso de compra, lo que especifica un método para gestionar el resultado.

#### 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
  }
}
```

A continuación, obtén el secreto de cliente del PaymentIntent, el secreto del cliente de la sesión del cliente, el ID del cliente y la clave publicable del punto de conexión que creaste en el paso anterior. Establece la clave publicable mediante `PaymentConfiguration` y guarda las otras para usarlas cuando presentes la PaymentSheet.

#### Kotlin

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

class CheckoutActivity : AppCompatActivity() {
  lateinit var paymentSheet: PaymentSheetlateinit 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
  }
}
```

Cuando el cliente pulse el botón de checkout, llama a [presentWithPaymentIntent](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/index.html#1814490530%2FFunctions%2F2002900378) para presentar la hoja de pago. Una vez que el cliente completa el pago, la hoja se cierra y se llama a [PaymentSheetResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html) con un [PaymentSheetResult](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result/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")
      }
    }
  }
}
```

Establecer `allowsDelayedPaymentMethods` en true permite utilizar métodos de pago de [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification) como cuentas bancarias de EE.&nbsp;UU. Para estos métodos de pago, el estado final del pago no se conoce cuando se completa la `PaymentSheet`, sino que se efectúa correctamente o con errores más tarde. Si aceptas este tipo de métodos de pago, infórmale al cliente de que su pedido está confirmado y solo complétalo (por ejemplo, envía el producto) cuando el pago se haya realizado correctamente.

## Gestionar eventos posteriores al pago [Lado del servidor]

Stripe envía un evento [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) cuando se efectiviza el pago. Usa la [herramienta webhook del Dashboard](https://dashboard.stripe.com/webhooks) o sigue las indicaciones de la [guía de webhooks](https://docs.stripe.com/webhooks/quickstart.md) para recibir estos eventos y acciones de ejecución, como enviar a tu cliente un correo electrónico de confirmación del pedido, registrar la venta en una base de datos o iniciar el flujo de trabajo de los envíos.

Escucha estos eventos en lugar de esperar una devolución de llamada del cliente. Por su parte, el cliente puede cerrar la ventana del navegador o salir de la aplicación antes de que se ejecute la devolución de llamada. Si configuras tu integración para escuchar eventos asincrónicos, podrás aceptar [diferentes tipos de métodos de pago](https://stripe.com/payments/payment-methods-guide) con una sola integración.

Además de administrar el evento `payment_intent.succeeded`, recomendamos administrar estos otros eventos si se cobran pagos con el Payment Element:

| Evento                                                                                                                          | Descripción                                                                                                                                                                                                                                                                                  | Acción                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded)           | Se envía cuando un cliente completa correctamente un pago.                                                                                                                                                                                                                                   | Envía al cliente una confirmación del pedido y *completa* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) el pedido.         |
| [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing)         | Se envía cuando el cliente inicia el pago correctamente, pero este aún no se ha efectivizado. En la mayoría de los casos, este evento se envía cuando el cliente inicia un adeudo bancario. Más adelante, le seguirá el evento `payment_intent.succeeded` o `payment_intent.payment_failed`. | Envía al cliente una confirmación del pedido que indique que su pago está pendiente. Para los productos digitales, es posible que desees completar el pedido antes de esperar a que se efectivice el pago. |
| [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Se envía cuando el cliente intenta realizar un pago, pero este falla.                                                                                                                                                                                                                        | Si un pago pasa de `processing` a `payment_failed`, ofrécele al cliente otro intento de pago.                                                                                                              |

## Cobra al PaymentMethod guardado más tarde [Lado del servidor]

> #### Cumplimiento de la normativa
> 
> Al guardar los datos de pago de un cliente, eres responsable de cumplir con todas las leyes, normativas y reglas de red aplicables. Al mostrar métodos de pago anteriores a tu cliente final para compras futuras, asegúrate de incluir solo aquellos para los que hayas obtenido su consentimiento para guardar los detalles del método de pago con ese fin específico. Para diferenciar entre los métodos de pago adjuntos a los clientes que pueden y no pueden presentarse a tu cliente final como un método de pago guardado para futuras compras, utiliza el parámetro [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay).

Para encontrar un método para pagar para cobrar, enumera los métodos de pago asociados a tu cliente. En este ejemplo se enumeran las tarjetas, pero puedes enumerar cualquier [tipo](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) aceptado.

> #### Usa la API Accounts v2 para representar a los clientes
> 
> La API Accounts v2 suele estar disponible para los usuarios de Connect y en vista previa pública para otros usuarios de Stripe. Si tienes acceso a la vista previa de Accounts v2, debes especificar [vista previa](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) en tu código.
> 
> Para solicitar acceso a la vista previa de Accounts v2, 
> 
> En la mayoría de los casos de uso, recomendamos [modelar a tus clientes como objetos Cuenta](https://docs.stripe.com/connect/use-accounts-as-customers.md) configurados por el cliente en lugar de usar objetos [Cliente](https://docs.stripe.com/api/customers.md).

#### Cuentas v2

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d type=card
```

#### Clientes v1

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d type=card
```

Cuando estés listo para cobrar a tu cliente *fuera de la sesión* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information), usa el ID del cliente y el ID del `PaymentMethod` para crear un `PymentIntent` con el importe y divisas del pago. Establece otros parámetros para efectuar el pago fuera de la sesión:

- Define [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) como `true` para indicar que el cliente no está en tu flujo del proceso de compra durante un intento de pago y no puede completar una petición de autenticación realizada por un socio, como un emisor de tarjeta, un banco u otra institución de pago. Si, durante tu flujo del proceso de compra, un socio solicita autenticación, Stripe solicita exenciones utilizando información del cliente de una transacción anterior de *durante la sesión* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method). Si no se cumplen las condiciones de exención, el `PaymentIntent` podría generar un error.
- Establece el valor de la propiedad [confirmar](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) del `PaymentIntent` como verdadero, lo que hace que la confirmación se produzca inmediatamente al crear el `PaymentIntent`.
- Establece [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) en el ID del `PaymentMethod`.
- Dependiendo de cómo representes a los clientes en tu integración, establece [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) en el ID de la `cuenta` configurada por el cliente o [cliente](https://docs.stripe.com/api.md#create_payment_intent-customer) en el ID del `cliente`.

#### Cuentas v2

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

#### Clientes v1

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer={{CUSTOMER_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

## Prueba la integración

#### Tarjetas

| Método de pago     | Situación                                                                                                                                                                                                                                                                                                                                | Cómo hacer la prueba                                                                                                                                 |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tarjeta de crédito | La configuración de la tarjeta se realiza correctamente y no requiere *autenticación* (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). | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta requiere autenticación para la configuración inicial, pero no para los pagos posteriores.                                                                                                                                                                                                                                     | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta requiere autenticación para la configuración inicial y también para los pagos posteriores.                                                                                                                                                                                                                                    | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0027 6000 3184` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta se ha rechazado durante la configuración.                                                                                                                                                                                                                                                                                     | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de caducidad, CVC y código postal. |

## Optional: Habilita Google Pay

### Configura tu integración

Para usar Google Pay, debes añadir lo siguiente a la etiqueta `<application>` de tu **AndroidManifest.xml** para habilitar la API de Google Pay:

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

Para obtener más detalles, consulta la documentación de Google Pay sobre cómo [configurar la API de Google Pay](https://developers.google.com/pay/api/android/guides/setup) para Android.

### Añadir Google Pay

Para añadir Google Pay a tu integración, especifica una [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) con tu entorno (de producción o de pruebas) de Google Pay y el [código de país de tu empresa](https://dashboard.stripe.com/settings/account) cuando inicies [PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html).

#### 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()
```

### Prueba Google Pay

Google te permite realizar pagos de prueba a través de su [paquete de tarjetas de prueba](https://developers.google.com/pay/api/android/guides/resources/test-card-suite). El paquete de pruebas es compatible con el uso de [tarjetas de prueba](https://docs.stripe.com/testing.md) de Stripe.

Para probar Google Pay, debes utilizar un dispositivo Android físico en lugar de un dispositivo simulado, en un país donde Google Pay sea compatible. Inicia sesión en una cuenta de Google en tu dispositivo de prueba con una tarjeta real guardada en Google Wallet.

## Optional: Personaliza la hoja

Todo lo que se quiera personalizar se configura usando el objeto [PaymentSheet.Configuration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html).

### Aspecto

Personaliza los colores, las fuentes y más para que coincidan con el aspecto de tu aplicación mediante la [API de apariencia](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=android).

### Diseño del método de pago

Configura el diseño de los métodos de pago en la hoja usando [paymentMethodLayout](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/-builder/index.html#2123253356%2FFunctions%2F2002900378). Puedes mostrarlos horizontalmente, verticalmente o dejar que Stripe optimice el diseño automáticamente.
![](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()
```

### Recopilar direcciones de usuarios

Recolecta las direcciones de envío o facturación locales e internacionales de tus clientes usando el [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android).

### Nombre que se muestra de la empresa

Configura [merchantDisplayName](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-configuration/index.html#-191101533%2FProperties%2F2002900378) para especificar el nombre de empresa que quieres que vea el cliente. De forma predeterminada, este es el nombre de tu aplicación.

#### Kotlin

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

### Modo oscuro

De forma predeterminada, `PaymentSheet` se adapta automáticamente a la configuración de aspecto de todo el sistema del usuario (modo claro y modo oscuro). Esto se puede cambiar si estableces el modo claro o el modo oscuro en tu aplicación:

#### Kotlin

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

### Datos de facturación predeterminados

Para establecer los valores predeterminados para los datos de facturación recopilados en la hoja de pago, configura la propiedad `defaultBillingDetails`. Los campos de la `PaymentSheet` se rellenan automáticamente con los valores que proporcionas.

#### 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()
```

### Configura la recopilación de los datos de facturación

Utiliza `BillingDetailsCollectionConfiguration` para especificar cómo quieres recoger los detalles de facturación en el PaymentSheet.

Puedes recopilar el nombre, el correo electrónico, el número de teléfono y la dirección del cliente.

Si quieres adjuntar datos de facturación predeterminados al objeto PaymentMethod aun cuando esos campos no se recopilen en la interfaz de usuario, establece `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` en `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()
```

> Consulta a tu asesor legal sobre las leyes que se aplican a la recopilación de información. Recopila los números de teléfono solo si los necesitas para la transacción.

## Optional: Efectiviza el pago en tu interfaz de usuario

Puedes presentar una hoja de pago para recopilar solo los datos del método de pago y completar el pago en la interfaz de usuario de tu aplicación. Esto resulta útil si tienes un botón de compra personalizado o solicitas pasos adicionales después de que se recopilen los datos de pago.
![](https://b.stripecdn.com/docs-statics-srv/assets/android-multi-step.84d8a0a44b1baa596bda491322b6d9fd.png)

> Una integración de ejemplo está [disponible en nuestro 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. Primero, inicializa [PaymentSheet.FlowController](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html) en lugar de `PaymentSheet`usando uno de los métodos del [Builder](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/-builder/index.html).

#### 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. A continuación, llama a `configureWithPaymentIntent` con las claves del objeto Stripe recuperadas del back-end y actualiza tu interfaz de usuario en la devolución de llamada mediante [getPaymentOption()](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#-2091462043%2FFunctions%2F2002900378). Contiene una imagen y una etiqueta que representan el método de pago seleccionado actualmente por el cliente.

#### 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. A continuación, llama a [presentPaymentOptions](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#449924733%2FFunctions%2F2002900378) para recopilar los datos del pago. Cuando el cliente termina, la hoja se cierra y llama a [paymentOptionCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-option-callback/index.html) especificado anteriormente en `create`. Implementa este método para actualizar tu interfaz de usuario con la `paymentOption` devuelta.

#### 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. Finalmente, llama a [confirm](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-flow-controller/index.html#-479056656%2FFunctions%2F2002900378) para completar el pago. Cuando el cliente termina, la hoja se cierra y llama al [paymentResultCallback](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet-result-callback/index.html#237248767%2FFunctions%2F2002900378) especificado anteriormente en `create`.

#### 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
      }
    }
  }
```

Establecer `allowsDelayedPaymentMethods` en true permite utilizar métodos de pago de [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification) como cuentas bancarias de EE.&nbsp;UU. Para estos métodos de pago, el estado final del pago no se conoce cuando se completa la `PaymentSheet`, sino que se efectúa correctamente o con errores más tarde. Si aceptas este tipo de métodos de pago, infórmale al cliente de que su pedido está confirmado y solo complétalo (por ejemplo, envía el producto) cuando el pago se haya realizado correctamente.


# React Native

> This is a React Native for when platform is react-native and mobile-ui is payment-element. View the full page at https://docs.stripe.com/payments/mobile/save-during-payment?platform=react-native&mobile-ui=payment-element.

Utiliza la [API Payment Intents](https://docs.stripe.com/api/payment_intents.md) para guardar los datos de pago de una compra. Tiene varios casos de uso:

- Cobrarle al cliente por un pedido de e-commerce y almacenar los datos para compras futuras.
- Iniciar el primer pago de una serie de pagos recurrentes.
- Cobrar un depósito y almacenar los datos para cobrar el importe total más tarde.

> #### Transacciones con tarjeta presente
> 
> Las transacciones con tarjeta presente, como los pagos a través de Stripe Terminal, utilizan un proceso diferente para guardar el método de pago. Para obtener más información, consulta [la documentación de Terminal](https://docs.stripe.com/terminal/features/saving-payment-details/save-after-payment.md).

## Cumplimiento de la normativa

Cuando guardes los datos de pago de un cliente para usarlos en el futuro, como mostrarle su método de pago en el flujo del proceso de compra para una compra futura o cobrarle cuando no esté usando activamente tu sitio web o aplicación, eres responsable de cumplir con todas las leyes, regulaciones y reglas de red que se apliquen. Antes de guardar o cobrar el método de pago de un cliente, asegúrate de:

- añadir a tu sitio web o aplicación condiciones que indiquen cómo piensas guardar los datos del método de pago, por ejemplo:
  - el consentimiento del cliente que te permite iniciar un pago o una serie de pagos en su nombre para transacciones específicas.
  - El momento y la frecuencia previstos de los pagos (por ejemplo, si los cargos son por cuotas programadas, pagos de suscripción o recargas no programadas).
  - Cómo determinas el importe del pago.
  - Tu política de cancelación, si el método de pago es para un servicio de suscripción.
- Usa un método de pago que guardado solo para lo que figura en tus condiciones.
- Consigue el consentimiento explícito del cliente para este uso específico. Por ejemplo, incluye una casilla de verificación «Guardar mi método de pago para futuras compras».
- Guarda un registro de la aceptación por escrito de estas condiciones por parte de tu cliente.

## Configura Stripe [Lado del servidor] [Lado del cliente]

Primero, necesitas una cuenta de Stripe. [Regístrate ahora](https://dashboard.stripe.com/register).

### Lado del servidor

Esta integración necesita puntos de conexión en tu servidor que se comuniquen con la API de Stripe. Utiliza las bibliotecas oficiales para acceder a la API de Stripe desde tu servidor:

#### 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'
```

### Lado del cliente

El [SDK para React Native](https://github.com/stripe/stripe-react-native) es de código abierto y está plenamente documentado. Internamente, utiliza el SDK de [iOS nativo](https://github.com/stripe/stripe-ios) y [Android](https://github.com/stripe/stripe-android). Para instalar el SDK para React Native de Stripe, ejecuta uno de los siguientes comandos en el directorio del proyecto (en función del administrador de paquetes que utilices):

#### hilado

```bash
yarn add @stripe/stripe-react-native
```

#### npm

```bash
npm install @stripe/stripe-react-native
```

A continuación, instala otras dependencias necesarias:

- Para iOS, navega hasta el directorio de **ios** y ejecuta `pod install` para asegurarte de instalar también las dependencias nativas necesarias.
- Para Android, no hay más dependencias para instalar.

> Recomendamos seguir la [guía oficial de TypeScript](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project) para añadir compatibilidad con TypeScript.

### Inicialización de Stripe

Para inicializar Stripe en tu aplicación React Native, ajusta tu pantalla de pago con el componente `StripeProvider` o usa el método de inicialización `initStripe`. Solo se requiere la [clave publicable](https://docs.stripe.com/keys.md#obtain-api-keys) de la API en `publishableKey`. El siguiente ejemplo muestra cómo inicializar Stripe mediante el componente `StripeProvider`.

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

function App() {
  const [publishableKey, setPublishableKey] = useState('');

  const fetchPublishableKey = async () => {
    const key = await fetchKey(); // fetch key from your server here
    setPublishableKey(key);
  };

  useEffect(() => {
    fetchPublishableKey();
  }, []);

  return (
    <StripeProvider
      publishableKey={publishableKey}
      merchantIdentifier="merchant.identifier" // required for Apple Pay
      urlScheme="your-url-scheme" // required for 3D Secure and bank redirects
    >
      {/* Your app code here */}
    </StripeProvider>
  );
}
```

> Usa las [claves de prueba](https://docs.stripe.com/keys.md#obtain-api-keys) de la API durante las pruebas y las tareas de desarrollo, y las claves del [modo activo](https://docs.stripe.com/keys.md#test-live-modes) cuando publiques tu aplicación.

## Habilitar los métodos de pago

Los pagos con tarjeta se habilitan de forma predeterminada. Consulta la [configuración de tus métodos de pago](https://dashboard.stripe.com/settings/payment_methods) para habilitar otros métodos de pago que quieras aceptar.

## Añadir un punto de conexión [Lado del servidor]

> #### Nota
> 
> Para mostrar la PaymentSheet antes de crear un PaymentIntent, consulta [Recolectar datos de pago antes de crear un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=payment).

Esta integración usa tres objetos de la API de Stripe:

1. [PaymentIntent](https://docs.stripe.com/api/payment_intents.md): Stripe usa este dato para representar tu intención de cobrarle a un cliente y hacer el seguimiento de los intentos de cobro y de los cambios en el estado del pago a lo largo del proceso.

1. (Opcional) Una [cuenta configurada por cliente](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-applied_configurations) o un [Cliente](https://docs.stripe.com/api/customers.md): para configurar un método de pago para futuros pagos, debes vincularlo a un cliente. Crea un objeto que represente a tu cliente cuando cree una cuenta en tu empresa. Si tu cliente hace un pago como invitado, puedes crear una `Cuenta` o `Cliente` antes del pago y asociarlo con tu propia representación interna de la cuenta del cliente más tarde.

1. (Opcional) {% /if %[CustomerSession](https://docs.stripe.com/api/customer_sessions.md): la información sobre el objeto que representa a tu cliente es confidencial y no se puede recuperar directamente desde una aplicación. Una `CustomerSession` otorga al SDK acceso temporal al alcance de la `Cuenta` o `Cliente` y proporciona opciones de configuración adicionales. Consulta una lista completa de [opciones de configuración](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components).

Por motivos de seguridad, tu aplicación no puede crear estos objetos. En su lugar, añade un punto de conexión en tu servidor que:

1. Recupera la `Cuenta` o `Cliente` o crea uno nuevo.
1. Crea una [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) para la `Cuenta` o `Cliente`.
1. Crea un `PaymentIntent` con el [importe](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-amount), [divisa](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-currency), [setup_future_usage](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-setup_future_usage), y la [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) o el [cliente](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer).
1. Devuelve el `PaymentIntent`*secreto de cliente* (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)), la `CustomerSession`, el `client_secret`, el ID de la `Cuenta` o `Cliente` y tu [clave publicable](https://dashboard.stripe.com/apikeys) en tu aplicación.

> El Payment Element móvil solo acepta `setup_future_usage` con tarjetas y cuentas bancarias de EE. UU.

Los métodos de pago que se muestran a los clientes durante el proceso de compra también se incluyen en el PaymentIntent. Puedes permitir que Stripe extraiga automáticamente los métodos de pago de la configuración de tu Dashboard o puedes enumerarlos de forma manual. Independientemente de la opción que elijas, debes saber que la divisa especificada en el PaymentIntent filtra los métodos de pago que se muestran al cliente. Por ejemplo, si especificas `eur` en el PaymentIntent y tienes habilitado OXXO en el Dashboard, OXXO no se mostrará al cliente porque no acepta pagos en `eur`.

A menos que tu integración requiera una opción basada en código para ofrecer métodos de pago, Stripe recomienda usar la opción automatizada. Esto se debe a que Stripe evalúa la divisa, las restricciones en cuanto a los métodos de pago y otros parámetros para determinar la lista de métodos de pago aceptados. Se da prioridad a los métodos de pago que aumentan la conversión y guardan mayor relación con la divisa y la ubicación del cliente.

#### Gestiona los métodos de pago desde el Dashboard

Puedes administrar los métodos de pago desde el [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe gestiona la devolución de métodos de pago que cumplen los requisitos según factores como el importe de la transacción, la divisa y el flujo de pago. El PaymentIntent se crea según los métodos de pago que configuraste en el Dashboard. Si no quieres usar el Dashboard o si quieres especificar métodos de pago manualmente, puedes enumerarlos usando el atributo `payment_method_types`.

#### Cuentas v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_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_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \

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

#### Clientes v1

#### 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 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 "setup_future_usage"="off_session" \

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

#### Cómo enumerar métodos de pago manualmente

#### Cuentas v2

#### curl

```bash
# Create an Account with the customer configuration (use an existing Account ID if this is a returning customer)
curl https://api.stripe.com/v2/core/accounts \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "configuration[customer]"

# Create a CustomerSession for the Account
curl https://api.stripe.com/v1/customer_sessions \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST" \
  -d "customer_account"="{{CUSTOMER_ACCOUNT_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_account"="{{CUSTOMER_ACCOUNT_ID}}" \
  -d "amount"=1099 \
  -d "currency"="eur" \
  -d "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

#### Clientes v1

#### 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 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 "setup_future_usage"="off_session" \
  -d "payment_method_types[]"="card" \
```

> Cada método de pago debe aceptar la divisa especificada en el PaymentIntent, y tu empresa tiene que estar establecida en uno de los países que acepta cada método de pago. Consulta la página de [Opciones de integración de los métodos de pago](https://docs.stripe.com/payments/payment-methods/integration-options.md) para obtener más información sobre lo que se acepta.

## Recopilar los datos de pago [Lado del cliente]

Antes de mostrar el Payment Element móvil, tu página de finalización de compra debe:

- Mostrar los productos de la compra y el importe total
- Recopilar la información de envío necesaria
- Incluir un botón de pago para presentar la interfaz de usuario de Stripe

En la finalización de compra de tu aplicación, haz una solicitud de red al punto de conexión de back-end que creaste en el paso anterior y llama a `initPaymentSheet` desde el hook `useStripe`.

#### Cuentas v2

```javascript
export default function CheckoutScreen() {
  const { initPaymentSheet, presentPaymentSheet } = useStripe();
  const [loading, setLoading] = useState(false);

  const fetchPaymentSheetParams = async () => {
    const response = await fetch(`${API_URL}/payment-sheet`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    const { paymentIntent, ephemeralKey, customer_account } = await response.json();

    return {
      paymentIntent,
      ephemeralKey,
      customer_account,
    };
  };

  const initializePaymentSheet = async () => {
    const {
      paymentIntent,
      ephemeralKey,
      customer_account,
    } = await fetchPaymentSheetParams();

    const { error } = await initPaymentSheet({
      merchantDisplayName: "Example, Inc.",
      customerAccountId: customer_account,
      customerEphemeralKeySecret: ephemeralKey,
      paymentIntentClientSecret: paymentIntent,
      // Set `allowsDelayedPaymentMethods` to true if your business accepts payment
      // methods that complete payment after a delay, like SEPA Debit and Sofort.
      allowsDelayedPaymentMethods: true,
      defaultBillingDetails: {
        name: 'Jane Doe',
      }
    });
    if (!error) {
      setLoading(true);
    }
  };

  const openPaymentSheet = async () => {
    // see below
  };

  useEffect(() => {
    initializePaymentSheet();
  }, []);

  return (
    <Screen>
      <Button
        variant="primary"
        disabled={!loading}
        title="Checkout"
        onPress={openPaymentSheet}
      />
    </Screen>
  );
}
```

#### Clientes v1

```javascript

export default function CheckoutScreen() {
  const { initPaymentSheet, presentPaymentSheet } = useStripe();
  const [loading, setLoading] = useState(false);

  const fetchPaymentSheetParams = async () => {
    const response = await fetch(`${API_URL}/payment-sheet`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    const { paymentIntent, ephemeralKey, customer } = await response.json();

    return {
      paymentIntent,
      ephemeralKey,
      customer,
    };
  };

  const initializePaymentSheet = async () => {
    const {
      paymentIntent,
      ephemeralKey,
      customer,
    } = await fetchPaymentSheetParams();

    const { error } = await initPaymentSheet({
      merchantDisplayName: "Example, Inc.",
      customerId: customer,
      customerEphemeralKeySecret: ephemeralKey,
      paymentIntentClientSecret: paymentIntent,
      // Set `allowsDelayedPaymentMethods` to true if your business can handle payment
      //methods that complete payment after a delay, like SEPA Debit and Sofort.
      allowsDelayedPaymentMethods: true,
      defaultBillingDetails: {
        name: 'Jane Doe',
      }
    });
    if (!error) {
      setLoading(true);
    }
  };

  const openPaymentSheet = async () => {
    // see below
  };

  useEffect(() => {
    initializePaymentSheet();
  }, []);

  return (
    <Screen>
      <Button
        variant="primary"
        disabled={!loading}
        title="Checkout"
        onPress={openPaymentSheet}
      />
    </Screen>
  );
}
```

Cuando el cliente toca el botón **Pagar**, llama a `presentPaymentSheet()` para abrir la hoja. Después de que complete el pago, la hoja se cerrará y la promesa se resolverá con un `StripeError<PaymentSheetError>` opcional.

```javascript
export default function CheckoutScreen() {
  // continued from above

  const openPaymentSheet = async () => {
    const { error } = await presentPaymentSheet();

    if (error) {
      Alert.alert(`Error code: ${error.code}`, error.message);
    } else {
      Alert.alert('Success', 'Your order is confirmed!');
    }
  };

  return (
    <Screen>
      <Button
        variant="primary"
        disabled={!loading}
        title="Checkout"
        onPress={openPaymentSheet}
      />
    </Screen>
  );
}
```

Si no se ha producido ningún error, comunícale al usuario que el proceso ya ha terminado (por ejemplo, mostrándole una pantalla de confirmación del pedido).

Establecer `allowsDelayedPaymentMethods` en true permite utilizar métodos de pago de [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification) como cuentas bancarias de EE.&nbsp;UU. Para estos métodos de pago, el estado final del pago no se conoce cuando se completa la `PaymentSheet`, sino que se efectúa correctamente o con errores más tarde. Si aceptas este tipo de métodos de pago, infórmale al cliente de que su pedido está confirmado y solo complétalo (por ejemplo, envía el producto) cuando el pago se haya realizado correctamente.

## Configura una URL de retorno (solo para iOS) [Lado del cliente]

Cuando un cliente sale de tu aplicación (por ejemplo, para autenticarse en Safari o en su aplicación bancaria), proporciónale una forma de volver automáticamente a tu aplicación. Muchos tipos de métodos de pago *requieren* una URL de retorno. Si no proporcionas una, no podremos presentar a tus usuarios métodos de pago que requieran una URL de retorno, aunque los hayas habilitado.

Para proporcionar una URL de retorno:

1. [Registrar](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app#Register-your-URL-scheme) una URL personalizada. No se admiten enlaces universales.
1. [Configurar](https://reactnative.dev/docs/linking) tu URL personalizada.
1. Configura tu componente raíz para reenviar la URL al SDK de Stripe como se muestra a continuación.

> Si utilizas Expo, [configura tu esquema](https://docs.expo.io/guides/linking/#in-a-standalone-app) en el archivo `app.json`.

```jsx
import { useEffect, useCallback } from 'react';
import { Linking } from 'react-native';
import { useStripe } from '@stripe/stripe-react-native';

export default function MyApp() {
  const { handleURLCallback } = useStripe();

  const handleDeepLink = useCallback(
    async (url: string | null) => {
      if (url) {
        const stripeHandled = await handleURLCallback(url);
        if (stripeHandled) {
          // This was a Stripe URL - you can return or add extra handling here as you see fit
        } else {
          // This was NOT a Stripe URL – handle as you normally would
        }
      }
    },
    [handleURLCallback]
  );

  useEffect(() => {
    const getUrlAsync = async () => {
      const initialUrl = await Linking.getInitialURL();
      handleDeepLink(initialUrl);
    };

    getUrlAsync();

    const deepLinkListener = Linking.addEventListener(
      'url',
      (event: { url: string }) => {
        handleDeepLink(event.url);
      }
    );

    return () => deepLinkListener.remove();
  }, [handleDeepLink]);

  return (
    <View>
      <AwesomeAppComponent />
    </View>
  );
}
```

Además, debes especificar `returnURL` cuando invoques el método `initPaymentSheet`:

```js
await initPaymentSheet({
  ...
  returnURL: 'your-app://stripe-redirect',
  ...
});
```

Para obtener más información sobre los esquemas de URL nativos, consulta la documentación para [Android](https://developer.android.com/training/app-links/deep-linking) e [iOS](https://developer.apple.com/documentation/xcode/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app).

## Gestionar eventos posteriores al pago

Stripe envía un evento [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) cuando se efectiviza el pago. Usa la [herramienta webhook del Dashboard](https://dashboard.stripe.com/webhooks) o sigue las indicaciones de la [guía de webhooks](https://docs.stripe.com/webhooks/quickstart.md) para recibir estos eventos y acciones de ejecución, como enviar a tu cliente un correo electrónico de confirmación del pedido, registrar la venta en una base de datos o iniciar el flujo de trabajo de los envíos.

Escucha estos eventos en lugar de esperar una devolución de llamada del cliente. Por su parte, el cliente puede cerrar la ventana del navegador o salir de la aplicación antes de que se ejecute la devolución de llamada. Si configuras tu integración para escuchar eventos asincrónicos, podrás aceptar [diferentes tipos de métodos de pago](https://stripe.com/payments/payment-methods-guide) con una sola integración.

Además de administrar el evento `payment_intent.succeeded`, recomendamos administrar estos otros eventos si se cobran pagos con el Payment Element:

| Evento                                                                                                                          | Descripción                                                                                                                                                                                                                                                                                  | Acción                                                                                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded)           | Se envía cuando un cliente completa correctamente un pago.                                                                                                                                                                                                                                   | Envía al cliente una confirmación del pedido y *completa* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) el pedido.         |
| [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing)         | Se envía cuando el cliente inicia el pago correctamente, pero este aún no se ha efectivizado. En la mayoría de los casos, este evento se envía cuando el cliente inicia un adeudo bancario. Más adelante, le seguirá el evento `payment_intent.succeeded` o `payment_intent.payment_failed`. | Envía al cliente una confirmación del pedido que indique que su pago está pendiente. Para los productos digitales, es posible que desees completar el pedido antes de esperar a que se efectivice el pago. |
| [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Se envía cuando el cliente intenta realizar un pago, pero este falla.                                                                                                                                                                                                                        | Si un pago pasa de `processing` a `payment_failed`, ofrécele al cliente otro intento de pago.                                                                                                              |

## Cobra al PaymentMethod guardado más tarde [Lado del servidor]

> #### Cumplimiento de la normativa
> 
> Al guardar los datos de pago de un cliente, eres responsable de cumplir con todas las leyes, normativas y reglas de red aplicables. Al mostrar métodos de pago anteriores a tu cliente final para compras futuras, asegúrate de incluir solo aquellos para los que hayas obtenido su consentimiento para guardar los detalles del método de pago con ese fin específico. Para diferenciar entre los métodos de pago adjuntos a los clientes que pueden y no pueden presentarse a tu cliente final como un método de pago guardado para futuras compras, utiliza el parámetro [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay).

Para encontrar un método para pagar para cobrar, enumera los métodos de pago asociados a tu cliente. En este ejemplo se enumeran las tarjetas, pero puedes enumerar cualquier [tipo](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) aceptado.

> #### Usa la API Accounts v2 para representar a los clientes
> 
> La API Accounts v2 suele estar disponible para los usuarios de Connect y en vista previa pública para otros usuarios de Stripe. Si tienes acceso a la vista previa de Accounts v2, debes especificar [vista previa](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) en tu código.
> 
> Para solicitar acceso a la vista previa de Accounts v2, 
> 
> En la mayoría de los casos de uso, recomendamos [modelar a tus clientes como objetos Cuenta](https://docs.stripe.com/connect/use-accounts-as-customers.md) configurados por el cliente en lugar de usar objetos [Cliente](https://docs.stripe.com/api/customers.md).

#### Cuentas v2

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d type=card
```

#### Clientes v1

```curl
curl -G https://api.stripe.com/v1/payment_methods \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d type=card
```

Cuando estés listo para cobrar a tu cliente *fuera de la sesión* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information), usa el ID del cliente y el ID del `PaymentMethod` para crear un `PymentIntent` con el importe y divisas del pago. Establece otros parámetros para efectuar el pago fuera de la sesión:

- Define [off_session](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-off_session) como `true` para indicar que el cliente no está en tu flujo del proceso de compra durante un intento de pago y no puede completar una petición de autenticación realizada por un socio, como un emisor de tarjeta, un banco u otra institución de pago. Si, durante tu flujo del proceso de compra, un socio solicita autenticación, Stripe solicita exenciones utilizando información del cliente de una transacción anterior de *durante la sesión* (A payment is described as on-session if it occurs while the customer is actively in your checkout flow and able to authenticate the payment method). Si no se cumplen las condiciones de exención, el `PaymentIntent` podría generar un error.
- Establece el valor de la propiedad [confirmar](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) del `PaymentIntent` como verdadero, lo que hace que la confirmación se produzca inmediatamente al crear el `PaymentIntent`.
- Establece [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) en el ID del `PaymentMethod`.
- Dependiendo de cómo representes a los clientes en tu integración, establece [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) en el ID de la `cuenta` configurada por el cliente o [cliente](https://docs.stripe.com/api.md#create_payment_intent-customer) en el ID del `cliente`.

#### Cuentas v2

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

#### Clientes v1

```curl
curl https://api.stripe.com/v1/payment_intents \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d amount=1099 \
  -d currency=usd \
  -d "automatic_payment_methods[enabled]=true" \
  -d "customer={{CUSTOMER_ID}}" \
  -d payment_method={{PAYMENT_METHOD_ID}} \
  --data-urlencode "return_url=https://example.com/order/123/complete" \
  -d off_session=true \
  -d confirm=true
```

## Prueba la integración

#### Tarjetas

| Método de pago     | Situación                                                                                                                                                                                                                                                                                                                                | Cómo hacer la prueba                                                                                                                                 |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tarjeta de crédito | La configuración de la tarjeta se realiza correctamente y no requiere *autenticación* (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). | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta requiere autenticación para la configuración inicial, pero no para los pagos posteriores.                                                                                                                                                                                                                                     | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta requiere autenticación para la configuración inicial y también para los pagos posteriores.                                                                                                                                                                                                                                    | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0027 6000 3184` y cualquier fecha de caducidad, CVC y código postal. |
| Tarjeta de crédito | La tarjeta se ha rechazado durante la configuración.                                                                                                                                                                                                                                                                                     | Rellena nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de caducidad, CVC y código postal. |

## Optional: Habilita Apple Pay

### Regístrate para obtener un ID de comerciante de Apple

Obtén un ID de comerciante Apple [registrándote para obtener un nuevo identificador](https://developer.apple.com/account/resources/identifiers/add/merchant) en el sitio web de Apple para desarrolladores.

Rellena el formulario incluyendo una descripción y el identificador. La descripción es solo para ti y podrás modificarla después. Stripe te recomienda que uses como identificador el nombre de tu aplicación (por ejemplo, `merchant.com.{{YOUR_APP_NAME}}`).

### Crear un nuevo certificado de Apple Pay

Crea un certificado para que tu aplicación cifre los datos de pago.

Ve a [Configuración de certificados de iOS](https://dashboard.stripe.com/settings/ios_certificates) en el Dashboard, haz clic en **Añadir aplicación nueva** y sigue las indicaciones.

Descarga un archivo de petición de firma de certificado (CSR) para obtener un certificado seguro de Apple que te permita utilizar Apple Pay.

Se debe usar un archivo CSR para emitir un certificado de manera exacta. Si cambias tu ID de comerciante de Apple, debes ir a la [Configuración de certificados de iOS](https://dashboard.stripe.com/settings/ios_certificates) en el Dashboard para obtener un CSR y un certificado nuevos.

### Integrar con Xcode

Añade la funcionalidad Apple Pay a tu aplicación. En Xcode, abre la configuración del proyecto, selecciona la pestaña **Firma y funcionalidades** y añade la funcionalidad **Apple Pay**. Aquí, es posible que se te pida que inicies sesión en tu cuenta de desarrollador. Selecciona el ID de comerciante que creaste antes, y tu aplicación estará lista para aceptar Apple Pay.
![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png)

Habilita la funcionalidad Apple Pay en Xcode

### Añadir Apple Pay

#### Pago único

Especifica tu ID de comerciante cuando creas `StripeProvider`:

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

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

Cuando llamas a `initPaymentSheet`, pasa tus [ApplePayParams](https://stripe.dev/stripe-react-native/api-reference/modules/PaymentSheet.html#ApplePayParams):

```javascript
await initPaymentSheet({
  // ...
  applePay: {
    merchantCountryCode: 'US',
  },
});
```

#### Pagos recurrentes

Cuando llames a `initPaymentSheet`, introduce un [ApplePayParams](https://stripe.dev/stripe-react-native/api-reference/modules/PaymentSheet.html#ApplePayParams) con `merchantCountryCode` configurado en el código de país de tu empresa.

De acuerdo con las [directrices de Apple](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) para pagos recurrentes, también debes establecer un`cardItems` que incluye un[RecurringCartSummaryItem](https://stripe.dev/stripe-react-native/api-reference/modules/ApplePay.html#RecurringCartSummaryItem) con la cantidad que pretendes cobrar (por ejemplo, “59,95 USD al mes”).

También puedes adoptar [tokens comerciales](https://developer.apple.com/apple-pay/merchant-tokens/) estableciendo la `request` con su `type` establecido en `PaymentRequestType.Recurring`

Para obtener más información sobre cómo usar pagos recurrentes con Apple Pay, consulta la [documentación de Apple sobre PassKit](https://developer.apple.com/documentation/passkit/pkpaymentrequest).

#### iOS (React Native)

```javascript
const initializePaymentSheet = async () => {
  const recurringSummaryItem = {
    label: 'My Subscription',
    amount: '59.99',
    paymentType: 'Recurring',
    intervalCount: 1,
    intervalUnit: 'month',
    // Payment starts today
    startDate: new Date().getTime() / 1000,

    // Payment ends in one year
    endDate: new Date().getTime() / 1000 + 60 * 60 * 24 * 365,
  };

  const {error} = await initPaymentSheet({
    // ...
    applePay: {
      merchantCountryCode: 'US',
      cartItems: [recurringSummaryItem],
      request: {
        type: PaymentRequestType.Recurring,
        description: 'Recurring',
        managementUrl: 'https://my-backend.example.com/customer-portal',
        billing: recurringSummaryItem,
        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.'",
      },
    },
  });
};
```

### Seguimiento de pedidos

Para añadir información de [seguimiento de pedidos](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) en iOS 16 o en una versión posterior, configura una función de devolución de llamada `setOrderTracking`. Stripe llama a tu implementación después de que se haya completado el pago, pero antes de que iOS descarte la hoja de Apple Pay.

Al implementar la función de devolución de llamada `setOrderTracking`setOrderTracking’, obtén los detalles del pedido de tu servidor para el pedido completado y transfiere los detalles a la función de `completion` proporcionada.

Para obtener más información sobre el seguimiento de pedidos, consulta la [documentación de Apple sobre los pedidos por monedero](https://developer.apple.com/documentation/walletorders).

#### iOS (React Native)

```javascript
await initPaymentSheet({
  // ...
  applePay: {
    // ...
    setOrderTracking: async complete => {
      const apiEndpoint =
        Platform.OS === 'ios'
          ? 'http://localhost:4242'
          : 'http://10.0.2.2:4567';
      const response = await fetch(
        `${apiEndpoint}/retrieve-order?orderId=${orderId}`,
        {
          method: 'GET',
          headers: {
            'Content-Type': 'application/json',
          },
        },
      );
      if (response.status === 200) {
        const orderDetails = await response.json();
        // orderDetails should include orderIdentifier, orderTypeIdentifier,
        // authenticationToken and webServiceUrl
        complete(orderDetails);
      }
    },
  },
});
```

## Optional: Habilita Google Pay

### Configura tu integración

Para usar Google Pay, debes añadir lo siguiente a la etiqueta `<application>` de tu **AndroidManifest.xml** para habilitar la API de Google Pay:

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

Para obtener más detalles, consulta la documentación de Google Pay sobre cómo [configurar la API de Google Pay](https://developers.google.com/pay/api/android/guides/setup) para Android.

### Añadir Google Pay

Al iniciar `PaymentSheet`, establece `merchantCountryCode` en el código de país de tu empresa  y establece `googlePay` en verdadero.

También puedes usar el entorno de prueba estableciendo el parámetro `testEnv`. Solo puedes probar Google&nbsp;Pay en un dispositivo físico Android. Consulta la [documentación de React Native](https://reactnative.dev/docs/running-on-device) para probar tu aplicación en un dispositivo físico.

```javascript
const { error, paymentOption } = await initPaymentSheet({
  // ...
  googlePay: {
    merchantCountryCode: 'US',
    testEnv: true, // use test environment
  },
});
```

## Habilita el escaneo de tarjetas [Lado del cliente]

> Es necesario habilitar el escaneo de tarjetas para el proceso de revisión de aplicaciones iOS de Apple. El escaneo de tarjetas no es necesario para el proceso de revisión de aplicaciones Android, pero recomendamos habilitarlo.

### iOS

Para habilitar la compatibilidad con el escaneo de tarjetas en iOS, establece la `NSCameraUsageDescription` (**Privacidad - Descripción del uso de la cámara**) en la `Info.plist` de tu aplicación, y proporciona un motivo para acceder a la cámara (por ejemplo, “Escanear tarjetas”).

### (Optional) Android

Para habilitar la compatibilidad con el escaneo de tarjetas, [solicita acceso de producción](https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access) a la API de Google Pay desde la [Consola de Google Pay y Monedero](https://pay.google.com/business/console?utm_source=devsite&utm_medium=devsite&utm_campaign=devsite).

- Si has habilitado Google Pay, la función de escaneo de tarjetas estará disponible automáticamente en nuestra interfaz de usuario en los dispositivos compatibles. Para obtener más información sobre los dispositivos compatibles, consulta las [restricciones de la API de Google Pay](https://developers.google.com/pay/payment-card-recognition/debit-credit-card-recognition)
- **Importante:** La función de escaneo de tarjetas solo aparece en compilaciones firmadas con la misma clave de firma registrada en la [Consola de Google Pay y Monedero](https://pay.google.com/business/console). Las compilaciones de prueba o depuración que utilicen claves de firma diferentes (por ejemplo, las compilaciones distribuidas a través de Firebase App Tester) no mostrarán la opción **Escanear tarjeta**. Para probar el escaneo de tarjetas en compilaciones previas al lanzamiento, debes:
  - Firma tus compilaciones de prueba con tu clave de firma de producción
  - Añade la huella digital de tu clave de firma de prueba a la Consola de Google Pay y Monedero

## Optional: Personaliza la hoja [Lado del cliente]

Todo lo que se quiera personalizar se configura con `initPaymentSheet`.

### Aspecto

Personaliza los colores, las fuentes, etc. para que coincidan con el aspecto de tu aplicación mediante la [API de apariencia](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=react-native).

### Nombre con el que aparecerá el comerciante

Configura `merchantDisplayName` para especificar el nombre de empresa que quieres que vea el cliente; de forma predeterminada, será el nombre de tu aplicación.

```javascript
await initPaymentSheet({
  // ...
  merchantDisplayName: 'Example Inc.',
});
```

### Modo oscuro

De forma predeterminada, `PaymentSheet` se adapta automáticamente a la configuración de aspecto de todo el sistema del usuario (modo claro y modo oscuro). Esto se puede cambiar si estableces la propiedad `style`en `alwaysLight` o `alwaysDark` en iOS.

```javascript
await initPaymentSheet({
  // ...
  style: 'alwaysDark',
});
```

En Android, debes establecer el modo claro u oscuro en tu aplicación:

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

### Datos de facturación predeterminados

Para establecer los valores predeterminados para los datos de facturación recolectados en la PaymentSheet, configura la propiedad `defaultBillingDetails`. Los campos de la `PaymentSheet` se rellenaron automáticamente con los valores que proporcionas.

```javascript
await initPaymentSheet({
  // ...
  defaultBillingDetails: {
      email: 'foo@bar.com',
      address: {
        country: 'US',
      },
  },
});
```

### Recopilar datos de facturación

Usa `billingDetailsCollectionConfiguration` para especificar cómo deseas recolectar los datos de facturación en la PaymentSheet.

Puedes recopilar el nombre, el correo electrónico, el número de teléfono y la dirección del cliente.

Si no tienes intención de recopilar los valores que requiere el método de pago, debes hacer lo siguiente:

1. Adjunta los valores no recopilados por `PaymentSheet` a la propiedad `defaultBillingDetails`.
1. Establece `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` en `true`.

```javascript
await initPaymentSheet({
  // ...
  defaultBillingDetails: {
    email: 'foo@bar.com',
  },
  billingDetailsCollectionConfiguration: {
    name: PaymentSheet.CollectionMode.ALWAYS,
    email: PaymentSheet.CollectionMode.NEVER,
    address: PaymentSheet.AddressCollectionMode.FULL,
    attachDefaultsToPaymentMethod: true
  },
});
```

> Consulta a tu asesor legal sobre las leyes que se aplican a la recopilación de información. Recopila los números de teléfono solo si los necesitas para la transacción.

## Optional: Efectiviza el pago en tu interfaz de usuario

Puedes presentar una hoja de pago para recopilar solo los datos del método de pago y a continuación llamar al método `confirm` para completar el pago en la interfaz de usuario de tu aplicación. Esto resulta útil si tienes un botón de compra personalizado o solicitas pasos adicionales después de recopilar los datos del pago.
![](https://b.stripecdn.com/docs-statics-srv/assets/react-native-multi-step.84d8a0a44b1baa596bda491322b6d9fd.png)

> Tienes un ejemplo de integración [disponible en nuestro GitHub](https://github.com/stripe/stripe-react-native/blob/master/example/src/screens/PaymentsUICustomScreen.tsx).

1. Primero, llama a `initPaymentSheet` y especifica `customFlow: true`. `initPaymentSheet` se resuelve con una opción de pago inicial que contiene una imagen y una etiqueta que representan el método de pago del cliente. Actualiza tu interfaz de usuario con estos datos.

```javascript
const {
  initPaymentSheet,
  presentPaymentSheet,
  confirmPaymentSheetPayment,
} = useStripe()

const { error, paymentOption } = await initPaymentSheet({
  customerId: customer,
  customerEphemeralKeySecret: ephemeralKey,
  paymentIntentClientSecret: paymentIntent,
  customFlow: true,
  merchantDisplayName: 'Example Inc.',
});
// Update your UI with paymentOption
```

1. Usa `presentPaymentSheet` para recopilar datos del pago. Una vez que el cliente termina, la hoja se cierra y se resuelve la promesa. Actualiza la interfaz de usuario con los datos del método de pago seleccionado.

```javascript
const { error, paymentOption } = await presentPaymentSheet();
```

1. Usa `confirmPaymentSheetPayment` para confirmar el pago. Esto se resuelve con el resultado del pago.

```javascript
const { error } = await confirmPaymentSheetPayment();

if (error) {
  Alert.alert(`Error code: ${error.code}`, error.message);
} else {
  Alert.alert(
    'Success',
    'Your order is confirmed!'
  );
}
```

Establecer `allowsDelayedPaymentMethods` en true permite utilizar métodos de pago de [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification) como cuentas bancarias de EE.&nbsp;UU. Para estos métodos de pago, el estado final del pago no se conoce cuando se completa la `PaymentSheet`, sino que se efectúa correctamente o con errores más tarde. Si aceptas este tipo de métodos de pago, infórmale al cliente de que su pedido está confirmado y solo complétalo (por ejemplo, envía el producto) cuando el pago se haya realizado correctamente.

