# Crear una integración de suscripciones

Crear y administrar las suscripciones para aceptar pagos recurrentes.

## Empieza aquí: instala las habilidades de agente

Stripe aconseja usar las habilidades oficiales para la integración en la API con las prácticas recomendadas. Sigue las instrucciones que se incluyen a continuación para aprender cómo.

**Consejo: Usa cURL, en lugar de herramientas de Fetch.** Las habilidades se detallan en archivos de marcado de&nbsp;10&nbsp;a&nbsp;20&nbsp;KB. Las herramientas de Fetch las resumen. `curl -sL` garantiza el contenido completo.

**Uso de `npx skills`**: comprueba si `npx` está instalado en el sistema. Si `npx` está disponible, ejecuta `npx skills add https://docs.stripe.com --list` para enumerar las habilidades disponibles y, a continuación, ejecuta `npx skills add https://docs.stripe.com --yes --skill <skill-name> <--skill other-skills>` para instalar habilidades individuales.

**En el caso de que `npx skills` no esté disponible**: puedes usar cURL para obtener el índice de las habilidades disponibles, lo que hacen y sus archivos de `https://docs.stripe.com/.well-known/skills/index.json`. Para obtener una habilidad y sus archivos relacionados, usa cURL y descárgalos de `https://docs.stripe.com/.well-known/skills/<filepath>`.

Para este artículo, recomendamos usar estas habilidades: `stripe-best-practices`

#### Checkout

#### Página alojada en Stripe

# Página alojada

> This is a Página alojada for when platform is web and ui is stripe-hosted. View the full page at https://docs.stripe.com/billing/subscriptions/build-subscriptions?platform=web&ui=stripe-hosted.

#### Esfuerzo de integración
Complexity: 2/5
#### Personalización de la interfaz de usuario (IU)
Personalización limitada
- 20 fuentes preestablecidas
- 3 radios de borde preestablecidos
- Fondo y color de borde personalizados
- Logotipo personalizado

#### Tipo de integración

Utiliza las páginas alojadas prediseñadas para cobrar los pagos y gestionar tus *suscripciones* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis).

[Pruébalo](https://checkout.stripe.dev/)

## Tu próximo desarrollo

Esta guía describe cómo vender suscripciones mensuales de precio fijo utilizando [Stripe Checkout](https://docs.stripe.com/payments/checkout.md).

Esta guía te explica cómo:

- Modelar tu empresa creando un catálogo de productos.
- Agregar una Checkout Session a tu sitio, incluidos un botón y las páginas de confirmación y cancelación de transacciones.
- Monitorear los eventos de suscripción y brindar acceso a tu servicio.
- Configura el [portal de clientes](https://docs.stripe.com/customer-management.md) .
- Agregar una sesión del portal de clientes a tu sitio, incluidos un botón y el redireccionamiento.
- Permitir que tus clientes administren sus suscripciones a través del portal.
- Aprende a utilizar el [modo de facturación flexible](https://docs.stripe.com/billing/subscriptions/billing-mode.md) para acceder a un comportamiento de facturación mejorado y a funcionalidades adicionales.

Si no estás preparado para codificar una integración, puedes configurar las suscripciones básicas [manualmente en el Dashboard](https://docs.stripe.com/no-code/subscriptions.md) o utilizar [Payment Links](https://docs.stripe.com/payment-links.md) para configurar las suscripciones sin escribir ningún código.

Obtén más información sobre [cómo diseñar una integración](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) para comprender las decisiones y los recursos necesarios para una integración completa.

Después de completar la integración, puedes ampliarla a lo siguiente:

- Muestra [impuestos](https://docs.stripe.com/payments/checkout/taxes.md)
- Aplica [descuentos](https://docs.stripe.com/billing/subscriptions/coupons.md#using-coupons-in-checkout)
- Ofrece a los clientes un [periodo de prueba gratuito](https://docs.stripe.com/billing/subscriptions/trials.md)
- Agrega [métodos de pago](https://docs.stripe.com/payments/payment-methods/integration-options.md)
- Integre la [página de facturas alojadas](https://docs.stripe.com/invoicing/hosted-invoice-page.md)
- Utiliza Checkout en el [modo de configuración](https://docs.stripe.com/payments/save-and-reuse.md)
- Establece [facturación por consumo](https://docs.stripe.com/products-prices/pricing-models.md#usage-based-pricing), [niveles de precios](https://docs.stripe.com/products-prices/pricing-models.md#tiered-pricing), y [precios por consumo](https://docs.stripe.com/products-prices/pricing-models.md#usage-based-pricing)
- Administra los [prorrateos](https://docs.stripe.com/billing/subscriptions/prorations.md)
- Permite que los clientes se [suscriban a varios productos](https://docs.stripe.com/billing/subscriptions/quantities.md#multiple-product-sub)
- Integra [entitlements](https://docs.stripe.com/billing/entitlements.md) para gestionar el acceso a las funcionalidades de tu producto.

## Configura Stripe

Instala el cliente de Stripe que prefieras:

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

Opcionalmente, instala la CLI de Stripe. La CLI proporciona pruebas de [webhook](https://docs.stripe.com/webhooks.md#test-webhook), y puedes ejecutarla para crear tus productos y precios.
Para obtener más opciones de instalación, consulta [Empezar a usar la CLI de Stripe](https://docs.stripe.com/stripe-cli.md).
## Crear el modelo de tarifas [Dashboard o CLI de Stripe]

Los [modelos de precios recurrentes](https://docs.stripe.com/products-prices/pricing-models.md) representan los productos o servicios que vendes, cuánto cuestan, qué monedas aceptas para los pagos y el período de servicio para las suscripciones. Para crear el modelo de precios, crea [productos](https://docs.stripe.com/api/products.md) (lo que vendes) y [precios](https://docs.stripe.com/api/prices.md) (cuánto cuestan y con qué frecuencia cobrar por los productos).

En este ejemplo, se utiliza una tarifa con tasa fija con dos opciones de niveles de servicio diferentes: básico y premium. Para cada opción de nivel de servicio, debes crear un producto y un precio recurrente. Si quieres agregar un cargo por única vez, como el costo de instalación, crea un tercer producto con un precio por única vez.

Cada producto se factura de forma mensual. El precio del producto básico es de 5 USD. El precio del producto premium es de 15 USD. Consulta la guía de [tarifas con tasa fija](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md) para ver un ejemplo con tres niveles.

#### Dashboard

Ve a la página [Agregar un producto](https://dashboard.stripe.com/test/products/create) y crea dos productos. Agrega un precio a cada producto, cada uno con un período de facturación mensual recurrente:

- Producto prémium: servicio prémium con más funcionalidades

  - Precio: Tarifa plana | 15 USD

- Producto básico: servicio básico con las funcionalidades mínimas

  - Precio: Tarifa plana | 5 USD

Después de crear los precios, registra los ID de precio para usarlos en otros pasos. Los ID de precio se ven así: `price_G0FvDp6vZvdwRZ`.

Cuando esté todo listo, usa el botón **Copiar en modo activo**, en la parte superior derecha de la página, para clonar el producto y pasarlo de [entorno de prueba a modo activo](https://docs.stripe.com/keys.md#test-live-modes).

#### API

Puedes usar la API para crear los [productos](https://docs.stripe.com/api/products.md) y los [precios](https://docs.stripe.com/api/prices.md).

Crear el producto premium:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

Crear el producto básico:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Basic Service" \
  -d "description=Basic service with minimum features"
```

Registra el ID de cada producto. Se ve así:

```json
{
  "id": "prod_H94k5odtwJXMtQ",
  "object": "product",
  "active": true,
  "attributes": [

  ],
  "created": 1587577341,
  "description": "Premium service with extra features",
  "images": [

  ],
  "livemode": false,
  "metadata": {
  },
  "name": "Billing Guide: Premium Service",
  "statement_descriptor": null,
  "type": "service",
  "unit_label": null,
  "updated": 1587577341
}
```

Usa los ID de producto para crear el precio de cada producto. El número [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) está en centavos. Por ejemplo, `1500` = 15 USD.

Crear el precio superior:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{PREMIUM_PRODUCT_ID}} \
  -d unit_amount=1500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Crear el precio básico:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{BASIC_PRODUCT_ID}} \
  -d unit_amount=500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Registra el ID de cada precio para poder utilizarlo en los pasos siguientes. Se ve así:

```json
{
  "id": "price_HGd7M3DV3IMXkC",
  "object": "price",
  "product": "prod_HGd6W1VUqqXGvr",
  "type": "recurring",
  "currency": "usd",
  "recurring": {
    "interval": "month",
    "interval_count": 1,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "active": true,
  "billing_scheme": "per_unit",
  "created": 1589319695,
  "livemode": false,
  "lookup_key": null,
  "metadata": {},
  "nickname": null,
  "unit_amount": 1500,
  "unit_amount_decimal": "1500",
  "tiers": null,
  "tiers_mode": null,
  "transform_quantity": null
}
```

Si ofreces varios períodos de facturación, usa el proceso de compra para las [ventas adicionales](https://docs.stripe.com/payments/checkout/upsells.md) a los clientes en períodos de facturación más largos y cobra más ingresos por adelantado.

Para conocer otros modelos de precios, consulta [Ejemplos de Billing](https://docs.stripe.com/products-prices/pricing-models.md).

## Crea una Checkout Session [Cliente y servidor]

Agrega un botón de pago en tu sitio web que llame a un punto de conexión del lado del servidor para crear una Checkout Session.

```html
<html>
  <head>
    <title>Checkout</title>
  </head>
  <body>
    <form action="/create-checkout-session" method="POST">
      <!-- Note: If using PHP set the action to /create-checkout-session.php -->

      <input type="hidden" name="priceId" value="price_G0FvDp6vZvdwRZ" />
      <button type="submit">Checkout</button>
    </form>
  </body>
</html>
```

En el back-end de tu solicitud, define un punto de conexión que [cree la sesión](https://docs.stripe.com/api/checkout/sessions/create.md) para que tu front-end la llame. Necesitará estos valores:

- El ID de precio de la suscripción por la que el cliente ha creado la cuenta (tu front-end especifica este valor).
- Tu `success_url`, que es una página de su sitio web a la que Checkout devuelve a tu cliente después de completar el pago.

Opcionalmente, puedes:

- Configura un [ciclo de facturación anclado](https://docs.stripe.com/billing/subscriptions/billing-cycle.md) a tu suscripción en esta llamada.
- Usa [el texto personalizado](https://docs.stripe.com/payments/checkout/custom-components.md?platform=web&payment-ui=stripe-hosted#customize-text) a fin de incluir tus Condiciones de suscripción y cancelación, además de un enlace que permita a tus clientes actualizar o cancelar su suscripción. Te recomendamos configurar [los recordatorios y las notificaciones por correo electrónico](https://docs.stripe.com/invoicing/send-email.md#email-configuration) para tus suscriptores.

Si creaste un precio único en el [paso 2](https://docs.stripe.com/billing/subscriptions/build-subscriptions.md#create-pricing-model), pasa también ese ID de precio. Tras crear una Checkout&nbsp;Session, redirige a tu cliente a la [URL](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-url) que se devolvió en la respuesta.

Puedes habilitar un comportamiento de suscripción más preciso y predecible cuando crees una Checkout Session configurando el tipo de [modo de facturación](https://docs.stripe.com/billing/subscriptions/billing-mode.md) como `flexible`. Debes utilizar la versión de la API de Stripe [2025-06-30.basil](https://docs.stripe.com/changelog/basil.md#2025-06-30.basil) o posterior.

> Puedes utilizar [lookup_keys](https://docs.stripe.com/products-prices/manage-prices.md#lookup-keys) a fin de obtener precios en lugar de ID de precios. Para ver un ejemplo, consulta el [modelo de solicitud](https://github.com/stripe-samples/subscription-use-cases/tree/main/fixed-price-subscriptions).

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

# The price ID passed from the front end.
#   price_id = params['priceId']
price_id = '{{PRICE_ID}}'

session = client.v1.checkout.sessions.create({
  success_url: 'https://example.com/success.html?session_id={CHECKOUT_SESSION_ID}',
  mode: 'subscription',
  line_items: [{
    # For usage-based billing, don't pass quantity
    quantity: 1,
    price: price_id
  }],
  subscription_data: {
    billing_mode: { type: 'flexible' }
  }
})

# Redirect to the URL returned on the session
#   redirect session.url, 303
```

Este ejemplo personaliza la `success_url` añadiendo el identificador de sesión. Más información sobre [personalización de la página de éxito](https://docs.stripe.com/payments/checkout/custom-success-page.md).

Desde tu [Dashboard](https://dashboard.stripe.com/settings/payment_methods), activa los métodos de pago que deseas aceptar de tus clientes. Checkout admite [varios métodos de pago](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support).

## Dar acceso a las suscripciones y monitorearlas [Servidor]

Una vez que la suscripción se ha completado con éxito, el cliente regresa a su sitio web en la dirección `success_url`, que inicia un evento `checkout.session.completed` *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests). Cuando recibas un evento `checkout.session.completed`, utiliza [entitlements](https://docs.stripe.com/billing/entitlements.md) para aprovisionar la suscripción. Continúa aprovisionando cada mes (si facturas mensualmente) a medida que recibas eventos `invoice.paid`. Si recibes un evento `invoice.payment_failed`, notifícalo a tu cliente y envíalo al portal de clientes para que actualice su método de pago.

Para determinar el siguiente paso para la lógica de tu sistema, comprueba el tipo de evento y analiza la carga útil de cada [objeto de evento](https://docs.stripe.com/api/events/object.md), como `invoice.paid`. Almacena los objetos de evento `subscription.id` y `customer.id` en tu base de datos para su verificación.

Para realizar pruebas, puedes supervisar los eventos en la [pestaña Eventos](https://dashboard.stripe.com/workbench/events) de [Workbench](https://docs.stripe.com/workbench.md). Para producción, configura un punto de conexión webhook y suscríbete a los tipos de eventos apropiados. Si no conoces tu clave `STRIPE_WEBHOOK_SECRET`, ve a la vista de detalles del destino de la [pestaña Webhooks](https://dashboard.stripe.com/workbench/webhooks) de Workbench para consultarla.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/webhook' do
  webhook_secret = '{{STRIPE_WEBHOOK_SECRET}}' # Ejemplo: whsec_c7681Dm
  payload = request.body.read
  if !webhook_secret.empty?
    # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, webhook_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts '⚠️  Webhook signature verification failed.'
      status 400
      return
    end
  else
    data = JSON.parse(payload, symbolize_names: true)
    event = Stripe::Event.construct_from(data)
  end
  # Get the type of webhook event sent
  event_type = event['type']
  data = event['data']
  data_object = data['object']

  case event_type
  when 'checkout.session.completed'
    # Payment is successful and the subscription is created.
    # You should provision the subscription and save the customer ID to your database.
  when 'invoice.paid'
    # Continue to provision the subscription as payments continue to be made.
    # Store the status in your database and check when a user accesses your service.
    # This approach helps you avoid hitting rate limits.
  when 'invoice.payment_failed'
    # The payment failed or the customer doesn't have a valid payment method.
    # The subscription becomes past_due. Notify your customer and send them to the
    # customer portal to update their payment information.
  else
    puts "Unhandled event type: \#{event.type}"
  end

  status 200
end
```

Como mínimo, debes monitorear estos tipos de eventos:

| Nombre del evento            | Descripción                                                                                        |
| ---------------------------- | -------------------------------------------------------------------------------------------------- |
| `checkout.session.completed` | Se envía cuando un cliente completa con éxito la sesión de pago, para informarle una nueva compra. |
| `invoice.paid`               | Se envía en cada período de facturación cuando se realiza correctamente un pago.                   |
| `invoice.payment_failed`     | Se envía en cada período de facturación si hay un problema con el método de pago del cliente.      |

Para conocer aún más eventos que supervisar, consulta [Webhooks de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md).

## Configurar el portal de clientes [Dashboard]

El [portal de clientes](https://docs.stripe.com/customer-management.md) les permite a tus clientes gestionar directamente sus suscripciones y facturas existentes.

Utiliza el [Dashboard](https://dashboard.stripe.com/test/settings/billing/portal) para configurar el portal. Como mínimo, asegúrate de [configurar el portal](https://docs.stripe.com/customer-management.md) para que los clientes puedan actualizar sus métodos de pago.

## Crear una sesión del portal [Servidor]

Definir un punto de conexión que [cree la sesión del portal de clientes](https://docs.stripe.com/api/customer_portal/sessions/create.md) para que tu front-end la llame. El `CUSTOMER_ID` se refiere al ID de cliente creado por una Checkout Session que guardaste mientras procesabas el evento `checkout.session.completed`. También puedes establecer un enlace de redirección predeterminado para el portal en el Dashboard.

Pasa un valor opcional `return_url` para la página de tu sitio a la que redirigir a tu cliente cuando termine de gestionar tu suscripción:

#### Accounts&nbsp;v2

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

# This is the URL that users are redirected to after they're done
# managing their billing.
return_url = '{{DOMAIN_URL}}' # Ejemplo: http://example.com
customer_account_id = '{{CUSTOMER_ACCOUNT_ID}}' # Ejemplo: acct_GBV60HKsE0mb5v

session = Stripe::BillingPortal::Session.create({
  customer_account: customer_account_id,
  return_url: return_url,
})

# Redirect to the URL for the session
#   redirect session.url, 303
```

#### Customers&nbsp;v1

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

# This is the URL that users are redirected to after they're done
# managing their billing.
return_url = '{{DOMAIN_URL}}' # Ejemplo: http://example.com
customer_id = '{{CUSTOMER_ID}}' # Ejemplo: cus_GBV60HKsE0mb5v

session = client.v1.billing_portal.sessions.create({
  customer: customer_id,
  return_url: return_url,
})

# Redirect to the URL for the session
#   redirect session.url, 303
```

## Dirigir a los clientes al portal de clientes [Cliente]

En el front-end, agrega un botón a la página de la dirección `success_url` que proporcione un enlace al portal de clientes:

```html
<html>
  <head>
    <title>Manage Billing</title>
  </head>
  <body>
    <form action="/customer-portal" method="POST">
      <!-- Note: If using PHP set the action to /customer-portal.php -->
      <button type="submit">Manage Billing</button>
    </form>
  </body>
</html>
```

Después de salir del portal de clientes, el cliente vuelve a tu sitio web en la `return_url`. Sigue [monitoreando los eventos](https://docs.stripe.com/billing/subscriptions/webhooks.md) para hacer el seguimiento del estado de la suscripción del cliente.

Si configuras el portal de clientes para permitir acciones como la cancelación de una suscripción, [supervisa eventos adicionales](https://docs.stripe.com/customer-management/integrate-customer-portal.md#webhooks).

## Prueba la integración

### Prueba métodos de pago

Usa la siguiente tabla para probar diferentes métodos y escenarios de pago.

| Método de pago      | Escenario                                                                                                                                                                                                                                                                                       | Cómo hacer la prueba                                                                                                                                                                         |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Débito directo BECS | Tu cliente paga correctamente con débito directo BECS.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `900123456` y BSB `000000`. El PaymentIntent confirmado pasa en un principio al estado `processing` y, tres minutos más tarde, a `succeeded`. |
| Débito directo BECS | El pago de tu cliente falla con un código de error `account_closed`.                                                                                                                                                                                                                            | Completa el formulario con el número de cuenta `111111113` y BSB `000000`.                                                                                                                   |
| Tarjeta de crédito  | El pago con tarjeta se efectúa correctamente y no requiere autenticación.                                                                                                                                                                                                                       | Completa el formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | El pago con tarjeta 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). | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | La tarjeta es rechazada con el código `insufficient_funds`.                                                                                                                                                                                                                                     | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Débito directo SEPA | Tu cliente paga correctamente con débito directo SEPA.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `AT321904300235473204`. El PaymentIntent confirmado pasa inicialmente al estado “en proceso” y, tres minutos más tarde, a “completado”.       |
| Débito directo SEPA | El estado de PaymentIntent de tu cliente pasa de `processing` a `requires_payment_method`.                                                                                                                                                                                                      | Completa el formulario con el número de cuenta `AT861904300235473202`.                                                                                                                       |

### Supervisa los acontecimientos

Configura webhooks para escuchar los eventos de cambio de suscripción, como actualizaciones y cancelaciones. Puedes ver [eventos de webhook de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md) en el [Dashboard](https://dashboard.stripe.com/test/events) o con el [Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook).

Obtén más información sobre [Comprobación de la integración con Billing](https://docs.stripe.com/billing/testing.md).

## See also

- [Ofrece a los clientes un periodo de prueba gratuito](https://docs.stripe.com/billing/subscriptions/trials.md)
- [Aplica descuentos](https://docs.stripe.com/billing/subscriptions/coupons.md#using-coupons-in-checkout)
- [Administra los prorrateos](https://docs.stripe.com/billing/subscriptions/prorations.md)
- [Integra los derechos para gestionar el acceso a las funcionalidades de tu producto](https://docs.stripe.com/billing/entitlements.md)


#### Formulario integrado

# Página integrada

> This is a Página integrada for when platform is web and ui is embedded-form. View the full page at https://docs.stripe.com/billing/subscriptions/build-subscriptions?platform=web&ui=embedded-form.

#### Esfuerzo de integración
Complexity: 2/5
#### Personalización de la interfaz de usuario

Personalizar el aspecto

#### Tipo de integración

Utiliza formularios integrados preintegrados para cobrar los pagos y gestionar *suscripciones* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis).

## Configurar el servidor

### Configura Stripe

Instala el cliente de Stripe que prefieras:

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

### Crear un producto y un precio

Los [modelos de precios recurrentes](https://docs.stripe.com/products-prices/pricing-models.md) representan los productos o servicios que vendes, cuánto cuestan, qué monedas aceptas para los pagos y el período de servicio para las suscripciones. Para crear el modelo de precios, crea [productos](https://docs.stripe.com/api/products.md) (lo que vendes) y [precios](https://docs.stripe.com/api/prices.md) (cuánto cuestan y con qué frecuencia cobrar por los productos).

En este ejemplo, se utiliza una tarifa con tasa fija con dos opciones de niveles de servicio diferentes: básico y premium. Para cada opción de nivel de servicio, debes crear un producto y un precio recurrente. Si quieres agregar un cargo por única vez, como el costo de instalación, crea un tercer producto con un precio por única vez.

Cada producto se factura de forma mensual. El precio del producto básico es de 5 USD. El precio del producto premium es de 15 USD. Consulta la guía de [tarifas con tasa fija](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md) para ver un ejemplo con tres niveles.

#### Dashboard

Ve a la página [Agregar un producto](https://dashboard.stripe.com/test/products/create) y crea dos productos. Agrega un precio a cada producto, cada uno con un período de facturación mensual recurrente:

- Producto prémium: servicio prémium con más funcionalidades

  - Precio: Tarifa plana | 15 USD

- Producto básico: servicio básico con las funcionalidades mínimas

  - Precio: Tarifa plana | 5 USD

Después de crear los precios, registra los ID de precio para usarlos en otros pasos. Los ID de precio se ven así: `price_G0FvDp6vZvdwRZ`.

Cuando esté todo listo, usa el botón **Copiar en modo activo**, en la parte superior derecha de la página, para clonar el producto y pasarlo de [entorno de prueba a modo activo](https://docs.stripe.com/keys.md#test-live-modes).

#### API

Puedes usar la API para crear los [productos](https://docs.stripe.com/api/products.md) y los [precios](https://docs.stripe.com/api/prices.md).

Crear el producto premium:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

Crear el producto básico:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Basic Service" \
  -d "description=Basic service with minimum features"
```

Registra el ID de cada producto. Se ve así:

```json
{
  "id": "prod_H94k5odtwJXMtQ",
  "object": "product",
  "active": true,
  "attributes": [

  ],
  "created": 1587577341,
  "description": "Premium service with extra features",
  "images": [

  ],
  "livemode": false,
  "metadata": {
  },
  "name": "Billing Guide: Premium Service",
  "statement_descriptor": null,
  "type": "service",
  "unit_label": null,
  "updated": 1587577341
}
```

Usa los ID de producto para crear el precio de cada producto. El número [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) está en centavos. Por ejemplo, `1500` = 15 USD.

Crear el precio superior:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{PREMIUM_PRODUCT_ID}} \
  -d unit_amount=1500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Crear el precio básico:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{BASIC_PRODUCT_ID}} \
  -d unit_amount=500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Registra el ID de cada precio para poder utilizarlo en los pasos siguientes. Se ve así:

```json
{
  "id": "price_HGd7M3DV3IMXkC",
  "object": "price",
  "product": "prod_HGd6W1VUqqXGvr",
  "type": "recurring",
  "currency": "usd",
  "recurring": {
    "interval": "month",
    "interval_count": 1,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "active": true,
  "billing_scheme": "per_unit",
  "created": 1589319695,
  "livemode": false,
  "lookup_key": null,
  "metadata": {},
  "nickname": null,
  "unit_amount": 1500,
  "unit_amount_decimal": "1500",
  "tiers": null,
  "tiers_mode": null,
  "transform_quantity": null
}
```

Si ofreces varios períodos de facturación, usa el proceso de compra para las [ventas adicionales](https://docs.stripe.com/payments/checkout/upsells.md) a los clientes en períodos de facturación más largos y cobra más ingresos por adelantado.

Para conocer otros modelos de precios, consulta [Ejemplos de facturación](https://docs.stripe.com/products-prices/pricing-models.md).

### Crea una Checkout Session

Añade un punto de conexión en tu servidor que cree una *Checkout Session* (A Checkout Session represents your customer's session as they pay for one-time purchases or subscriptions through Checkout. After a successful payment, the Checkout Session contains a reference to the Customer, and either the successful PaymentIntent or an active Subscription).

Cuando crees la [Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md), pasa los siguientes parámetros:

- Para usar el formulario de pago embedded_page, establece [ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) en `embedded`.
- Para crear suscripciones si tu cliente pague, configura el [modo ](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-mode) en `suscripción`.
- Para definir la página a la que volverá tu cliente después de completar o intentar el pago, especifique una [return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url). Incluye la variable de plantilla `{CHECKOUT_SESSION_ID}` en la URL. Checkout sustituye la variable por el ID de Checkout Session antes de redirigir a tu cliente. Tú creas y alojas la página de retorno en tu sitio web.
- Con el fin de incluir tus Condiciones de suscripción y cancelación, además de un enlace que permita a tus clientes actualizar o cancelar su suscripción, utiliza [el texto personalizado](https://docs.stripe.com/payments/checkout/custom-components.md?ui=embedded-form#customize-payment-method-reuse-agreement-and-subscription-terms) de manera opcional. Te recomendamos configurar los recordatorios y las notificaciones por [correo electrónico](https://docs.stripe.com/invoicing/send-email.md#email-configuration) para tus suscriptores.

Para montar Checkout, utiliza el `client_secret` de la Checkout Session devuelto en la respuesta.

```curl
curl https://api.stripe.com/v1/checkout/sessions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d mode=subscription \
  -d "line_items[0][price]={{PRICE_ID}}" \
  -d "line_items[0][quantity]=1" \
  -d ui_mode=embedded_page \
  --data-urlencode "return_url=https://example.com/checkout/return?session_id={CHECKOUT_SESSION_ID}"
```

## Crear tu página de suscripciones [Cliente]

### Montar Checkout

#### HTML + JS

#### Cargar Stripe.js

Utiliza *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) para *cumplir con la normativa PCI* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business) asegurándote de que los datos del pago se envíen directamente a Stripe sin que pasen por tu servidor. Carga siempre Stripe.js directamente desde js.stripe.com para cumplir con la normativa PCI. No incluyas el script en un paquete ni alojes una copia por tu cuenta.

#### Definir el formulario de pago

Para cobrar de forma segura la información del cliente, crea un marcador de posición vacío `div`. Stripe inserta un iframe en el `div`.

Checkout está disponible como parte de [Stripe.js](https://docs.stripe.com/js.md). Para incluir el script de Stripe.js en tu página, agrégalo al encabezado de tu archivo HTML. A continuación, crea un nodo DOM vacío (contenedor) para usarlo en el montaje.

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Accept a payment</title>
    <meta name="description" content="A demo of a payment on Stripe" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="style.css" /><!-- Add the Stripe.js script here -->
    <script src="https://js.stripe.com/dahlia/stripe.js"></script>
    <script src="checkout.js" defer></script>
  </head><body>
    <!-- Display a payment form -->
      <div id="checkout">
        <!-- Checkout inserts the payment form here -->
      </div>
  </body>
</html>
```

#### Inicializar Stripe.js

Inicializa Stripe.js con la clave publicable de tu API.

#### Obtener el secreto de cliente de una Checkout Session

Crea una función asíncrona `fetchClientSecret` que realice una solicitud a tu servidor para [crear una Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md) y recuperar el secreto de cliente.

#### Inicializar Checkout

Inicializa Checkout con tu función `fetchClientSecret` y móntala en el marcador de posición. `<div>` en tu formulario de pago. Checkout se realiza en un iframe que envía de forma segura la información de pago a Stripe a través de una conexión HTTPS.

Evita colocar Checkout en otro iframe, ya que algunos métodos de pago requieren un redireccionamiento a otra página para confirmar el pago.

```javascript
// Initialize Stripe.js
const stripe = Stripe('<<YOUR_PUBLISHABLE_KEY>>');

initialize();

// Fetch Checkout Session and retrieve the client secret
async function initialize() {
  const fetchClientSecret = async () => {
    const response = await fetch("/create-checkout-session", {
      method: "POST",
    });
    const { clientSecret } = await response.json();
    return clientSecret;
  };

  // Initialize Checkout
  const checkout = await stripe.createEmbeddedCheckoutPage({
    fetchClientSecret,
  });

  // Mount Checkout
  checkout.mount('#checkout');
}
```

#### React

#### Agregar Stripe a tu aplicación de React

Instala [React Stripe.js](https://docs.stripe.com/sdks/stripejs-react.md) para cumplir con la normativa PCI, ya que los datos de pago van directamente a Stripe y nunca llegan a tu servidor.

```bash
npm install --save @stripe/react-stripe-js @stripe/stripe-js
```

#### Cargar Stripe.js

Para configurar la biblioteca de Stripe, llama a `loadStripe()` con tu clave de API publicable de Stripe. Crea un `EmbeddedCheckoutProvider`. Pasa la `Promise` devuelta al proveedor.

#### Obtener el secreto de cliente de una Checkout Session

Crea una función asíncrona `fetchClientSecret` que realice una solicitud a tu servidor para [crear una Checkout Session](https://docs.stripe.com/api/checkout/sessions/create.md) y recuperar el secreto de cliente.

#### Inicializar Checkout

Para permitir que los componentes secundarios accedan al servicio de Stripe a través del consumidor de Checkout incrustado, pasa la promesa resultante de `loadStripe` y la función `fetchClientSecret` como una `option` al proveedor de Checkout incrustado.

```jsx
import * as React from 'react';
import {loadStripe} from '@stripe/stripe-js';
import {
  EmbeddedCheckoutProvider,
  EmbeddedCheckout
} from '@stripe/react-stripe-js';

// Make sure to call `loadStripe` outside of a component's render to avoid
// recreating the `Stripe` object on every render.
const stripePromise = loadStripe('pk_test_123', {
});

const App = ({fetchClientSecret}) => {
  const options = {fetchClientSecret};

  return (
    <EmbeddedCheckoutProvider
      stripe={stripePromise}
      options={options}
    >
      <EmbeddedCheckout />
    </EmbeddedCheckoutProvider>
  )
}
```

## Mostrar página de devolución

Después de que tu cliente intente realizar el pago, Stripe lo redirige a una página de retorno que alojas en tu sitio web. Cuando creaste la Checkout Session, especificaste la URL de la página de retorno en el parámetro [return_url](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-return_url).

> Durante el pago, algunos métodos de pago redirigen al cliente a una página intermedia, como una página de autorización bancaria. Cuando el cliente completa esa página, Stripe lo redirige a tu página de retorno.

#### Crear un punto de conexión para recuperar una Checkout Session

Añade un punto de conexión para recuperar el estado de una Checkout Session con el ID de la Checkout Session en la URL.

#### Recuperar una Checkout Session

Para utilizar los datos de la sesión de pago, envía inmediatamente una solicitud al punto final de tu servidor para [recuperar el estado de la Checkout Session](https://docs.stripe.com/api/checkout/sessions/retrieve.md) utilizando el ID de Checkout en la URL tan pronto como se cargue tu página de retorno.

#### Manejar la sesión

Maneja el resultado establecido en el estado de la sesión:

- `complete`: el pago se efectuó correctamente. Usa la información de la Checkout Session para mostrar una página que indique que el pago se realizó correctamente.
- `open`: el pago falló o se canceló. Vuelve a montar Checkout para que tu cliente pueda volver a intentarlo.

```js
// Retrieve a Checkout Session
// Use the session ID
initialize();

async function initialize() {
  const queryString = window.location.search;
  const urlParams = new URLSearchParams(queryString);
  const sessionId = urlParams.get('session_id');
  const response = await fetch(`/session-status?session_id=${sessionId}`);
  const session = await response.json();
// Handle the session according to its status
  if (session.status == 'open') {
    // Remount embedded Checkout
    window.location.replace('http://localhost:4242/checkout.html')
  } else if (session.status == 'complete') {
    document.getElementById('success').classList.remove('hidden');
    document.getElementById('customer-email').textContent = session.customer_email;
    // Show success page
    // Optionally use session.payment_status or session.customer_email
    // to customize the success page
  }
}
```

#### Accounts&nbsp;v2

```javascript
// Add an endpoint to fetch the Checkout Session status
app.get('/session_status', async (req, res) => {
  const session = await stripe.checkout.sessions.retrieve(req.query.session_id);
  const customer_account = await stripe.v2.core.accounts(session.customer_account);

  res.send({
    status: session.status,
    payment_status: session.payment_status,
    customer_email: customer_account.contact_email
  });
});
```

#### Customers&nbsp;v1

```javascript
// Add an endpoint to fetch the Checkout Session status
app.get('/session_status', async (req, res) => {
  const session = await stripe.checkout.sessions.retrieve(req.query.session_id);
  const customer = await stripe.customers.retrieve(session.customer);

  res.send({
    status: session.status,
    payment_status: session.payment_status,
    customer_email: customer.email
  });
});
```

## Optional: Configurar el portal de clientes

Puedes configurar el *portal de clientes* (The customer portal is a secure, Stripe-hosted page that lets your customers manage their subscriptions and billing details) para que tus clientes gestionen directamente sus suscripciones y facturas existentes.

Puedes configurar el portal en el Dashboard. Para reducir la pérdida de clientes, puedes configurar el portal para que les permita a los clientes actualizar sus métodos de pago en caso de pagos fallidos.

Para ayudar a los clientes a encontrarlo, añade un botón en tu sitio web que redirija al portal de clientes para que puedan gestionar su suscripción. Al hacer clic en este botón, el cliente será redirigido a la página del portal de clientes alojada en Stripe.

Obtén más información sobre el [portal de clientes](https://docs.stripe.com/customer-management.md) y otras opciones de gestión de clientes.

#### Crear una sesión del portal

Para añadir un portal de clientes, define un punto de conexión que [cree la sesión del portal de clientes](https://docs.stripe.com/api/customer_portal/sessions/create.md) para que tu front-end la llame. Incluye el ID del cliente creado por una Checkout Session que guardaste mientras procesabas el webhook `checkout.session.completed`. También puedes establecer un enlace de redirección predeterminado para el portal en el Dashboard.

Pasa un valor opcional `return_url` para la página de tu sitio a la que redirigir a tu cliente cuando termine de gestionar tu suscripción:

#### Accounts&nbsp;v2

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

# This is the URL that users are redirected to after they're done
# managing their billing.
return_url = '{{DOMAIN_URL}}' # Ejemplo: http://example.com
customer_account_id = '{{CUSTOMER_ACCOUNT_ID}}' # Ejemplo: acct_GBV60HKsE0mb5v

session = Stripe::BillingPortal::Session.create({
  customer_account: customer_account_id,
  return_url: return_url,
})

# Redirect to the URL for the session
#   redirect session.url, 303
```

#### Customers&nbsp;v1

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

# This is the URL that users are redirected to after they're done
# managing their billing.
return_url = '{{DOMAIN_URL}}' # Ejemplo: http://example.com
customer_id = '{{CUSTOMER_ID}}' # Ejemplo: cus_GBV60HKsE0mb5v

session = client.v1.billing_portal.sessions.create({
  customer: customer_id,
  return_url: return_url,
})

# Redirect to the URL for the session
#   redirect session.url, 303
```

#### Dirigir a los clientes al portal de clientes

En tu front end, añade un botón a la página en la dirección `success_url` que proporcione un enlace al portal de clientes:

```html
<html>
  <head>
    <title>Manage Billing</title>
  </head>
  <body>
    <form action="/customer-portal" method="POST">
      <!-- Note: If using PHP set the action to /customer-portal.php -->
      <button type="submit">Manage Billing</button>
    </form>
  </body>
</html>
```

Después de salir del portal de clientes, el cliente vuelve a tu sitio web en la `return_url`. Sigue [monitoreando los eventos](https://docs.stripe.com/billing/subscriptions/webhooks.md) para hacer el seguimiento del estado de la suscripción del cliente.

Si configuras el portal de clientes para permitir acciones como la cancelación de una suscripción, asegúrate de supervisar [eventos adicionales](https://docs.stripe.com/customer-management/integrate-customer-portal.md#webhooks).

## Dar acceso

Cuando la suscripción esté activa, dé a su usuario acceso a su servicio. Para ello, escucha los eventos `customer.subscription.created`, `customer.subscription.updated`, y `customer.subscription.deleted`. Estos eventos pasan un objeto `Subscription` que contiene un campo `status` que indica si la suscripción está activa, vencida o cancelada. Consulta el [ciclo de vida de la suscripción](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle) para obtener una lista completa de estados. Para gestionar el acceso a la funcionalidad de su producto, infórmate sobre [la integración de derechos](https://docs.stripe.com/billing/entitlements.md).

En tu controlador de webhook:

1. Verifica el estado de la suscripción. Si es `active`, tu usuario ha pagado por su producto.
1. Comprueba el producto al que se ha suscrito tu cliente y concédele acceso a tu servicio. Al comprobar el producto en lugar del precio, podrás cambiar el precio o el período de facturación según sea necesario.
1. Almacena el `product.id`, `subscription.id` y `subscription.status` en tu base de datos junto con el `customer_account.id` o el `customer.id` que ya guardaste. Consulta este registro cuando tengas que determinar qué funcionalidades habilitar para el usuario en tu aplicación.

El estado de la suscripción puede cambiar en cualquier momento de su ciclo de vida, incluso si tu solicitud no hace ninguna llamada directa a Stripe. Por ejemplo, se puede producir un error de renovación debido a una tarjeta de crédito vencida, lo que genera que el estado de la suscripción pase a vencido. O, si usas el [portal de clientes](https://docs.stripe.com/customer-management.md), un usuario puede optar por cancelar la suscripción sin ingresar a tu aplicación directamente. El uso correcto del controlador mantiene el estado de tu solicitud sincronizado con Stripe.

## Prueba la integración

### Prueba métodos de pago

Usa la siguiente tabla para probar diferentes métodos y escenarios de pago.

| Método de pago      | Escenario                                                                                                                                                                                                                                                                                       | Cómo hacer la prueba                                                                                                                                                                         |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Débito directo BECS | Tu cliente paga correctamente con débito directo BECS.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `900123456` y BSB `000000`. El PaymentIntent confirmado pasa en un principio al estado `processing` y, tres minutos más tarde, a `succeeded`. |
| Débito directo BECS | El pago de tu cliente falla con un código de error `account_closed`.                                                                                                                                                                                                                            | Completa el formulario con el número de cuenta `111111113` y BSB `000000`.                                                                                                                   |
| Tarjeta de crédito  | El pago con tarjeta se efectúa correctamente y no requiere autenticación.                                                                                                                                                                                                                       | Completa el formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | El pago con tarjeta 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). | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | La tarjeta es rechazada con el código `insufficient_funds`.                                                                                                                                                                                                                                     | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Débito directo SEPA | Tu cliente paga correctamente con débito directo SEPA.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `AT321904300235473204`. El PaymentIntent confirmado pasa inicialmente al estado “en proceso” y, tres minutos más tarde, a “completado”.       |
| Débito directo SEPA | El estado de PaymentIntent de tu cliente pasa de `processing` a `requires_payment_method`.                                                                                                                                                                                                      | Completa el formulario con el número de cuenta `AT861904300235473202`.                                                                                                                       |

### Supervisa los acontecimientos

Configura webhooks para escuchar los eventos de cambio de suscripción, como actualizaciones y cancelaciones. Puedes ver [eventos de webhook de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md) en el [Dashboard](https://dashboard.stripe.com/test/events) o con el [Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook).

Obtén más información sobre [Comprobación de la integración con Billing](https://docs.stripe.com/billing/testing.md).


#### Elements

#### Checkout Sessions API

#### Esfuerzo de integración
Complexity: 3/5
#### Tipo de integración

Combina componentes de la interfaz de usuario (IU) en un flujo de pago personalizado

#### Personalización de la interfaz de usuario (IU)

Personalización a nivel CSS con la [API Appearance](https://docs.stripe.com/elements/appearance-api.md)

[Pruébalo ](https://checkout.stripe.dev/)

Crea un formulario de pago personalizado con [Stripe Elements](https://docs.stripe.com/payments/elements.md) y la [API Checkout Sessions](https://docs.stripe.com/api/checkout/sessions.md) para vender *subscriptions* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) a un precio fijo. Comprueba cómo esta integración [se compara con otros tipos de integraciones de Stripe](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability).

La API Checkout Sessions ofrece soporte integrado para cálculo de impuestos, descuentos, envío y conversión de monedas, lo que reduce la cantidad de código personalizado que debes escribir. Este es el enfoque recomendado para la mayoría de las integraciones. Obtén más información sobre [cuándo usar Checkout Sessions en lugar de PaymentIntents](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md).

Si no deseas crear un formulario de pago personalizado, puedes integrarlo en la versión alojada del proceso de compra. Si deseas una versión completa de esa guía de integración, consulta la [Guía de inicio rápido](https://docs.stripe.com/billing/quickstart.md) de Billing.

Si no estás listo para programar una integración, puedes configurar suscripciones básicas [de forma manual en el Dashboard](https://docs.stripe.com/no-code/subscriptions.md). También puedes usar [Payment&nbsp;Links](https://docs.stripe.com/payment-links.md) para configurar suscripciones sin programar nada. Obtén más información sobre [cómo diseñar una integración](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) para comprender las decisiones que debes tomar y los recursos que necesitas.

## Tu próximo desarrollo

Esta guía te explica cómo:

- Modelar tu empresa creando un catálogo de productos.
- Crear un proceso de inscripción que genere un cliente.
- Crear suscripciones y recopilar información de pago.
- Comprobar y monitorear el estado de los pagos y las suscripciones.
- Permitir que los clientes cambien de plan o cancelen la suscripción.

### Definiciones de los objetos de la API

| Recurso                                                                                                                                | Definición                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Cuenta configurada como un cliente](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | Representa a un cliente en la API Accounts v2 que compra una suscripción. Configura un objeto `Cuenta` como cliente y asócialo a una suscripción para realizar cargos recurrentes y hacerles un seguimiento, y para gestionar los productos a los que se suscribe. Consulta nuestra [guía Usar cuentas como clientes](https://docs.stripe.com/connect/use-accounts-as-customers.md) para obtener más información.                                 |
| [Customer](https://docs.stripe.com/api/customers.md)                                                                                   | Representa a un cliente en la API Clientes que compra una suscripción. Usa el objeto `Cliente` asociado a una suscripción para realizar y hacer seguimiento de los cargos recurrentes y administrar los productos a los que se suscriben.                                                                                                                                                                                                         |
| [Derecho](https://docs.stripe.com/api/entitlements/active-entitlement.md)                                                              | Representa el acceso de un cliente a una funcionalidad incluida en un producto de servicio al que está suscrito. Cuando creas una suscripción para la compra recurrente de un producto por parte de un cliente, se crea automáticamente un derecho activo para cada funcionalidad asociada a ese producto. Cuando un cliente accede a tus servicios, utiliza sus derechos activos para habilitar las funcionalidades incluidas en su suscripción. |
| [Funcionalidad](https://docs.stripe.com/api/entitlements/feature.md)                                                                   | Representa una funcionalidad o capacidad a la que tus clientes pueden acceder cuando se suscriben a un producto de servicio. Puedes incluir funciones en un producto creando ProductFeatures.                                                                                                                                                                                                                                                     |
| [Factura](https://docs.stripe.com/api/invoices.md)                                                                                     | Una declaración de importes que un cliente adeuda y que rastrea los estados de pago desde el borrador hasta su pago o su finalización. Las suscripciones generan facturas automáticamente.                                                                                                                                                                                                                                                        |
| [PaymentIntent](https://docs.stripe.com/api/payment_intents.md)                                                                        | Una forma de crear flujos de pago dinámicos. Un PaymentIntent hace un seguimiento del ciclo de vida del flujo del proceso compra del cliente y activa pasos adicionales de autenticación, si así lo exigen las disposiciones normativas, las reglas antifraude personalizadas de Radar o los métodos de pago con redireccionamiento. Las facturas crean PaymentIntents de forma automática.                                                       |
| [PaymentMethod](https://docs.stripe.com/api/payment_methods.md)                                                                        | Los métodos de pago que usa un cliente para pagar tus productos. Por ejemplo, puedes guardar una tarjeta de crédito en un objeto `Cuenta` o `Cliente` configurado por el cliente y usarla para hacer pagos recurrentes para ese cliente. Por lo general, se usa con las API Payment Intents o Setup Intents.                                                                                                                                      |
| [Precio](https://docs.stripe.com/api/prices.md)                                                                                        | Define el precio por unidad, la moneda y el ciclo de facturación para un producto.                                                                                                                                                                                                                                                                                                                                                                |
| [Producto](https://docs.stripe.com/api/products.md)                                                                                    | Un bien o servicio que vende tu empresa. Un producto de servicio puede incluir una o más funciones.                                                                                                                                                                                                                                                                                                                                               |
| [ProductFeature](https://docs.stripe.com/api/product-feature.md)                                                                       | Representa la inclusión de una sola funcionalidades en un solo producto. Cada producto está asociado a una ProductFeature para cada funcionalidad que incluye, y cada funcionalidad está asociada a una ProductFeature para cada producto que la incluye.                                                                                                                                                                                         |
| [Suscripción](https://docs.stripe.com/api/subscriptions.md)                                                                            | Representa la compra recurrente programada de un producto por parte de un cliente. Usa una suscripción para cobrar pagos y proporcionar entrega repetida o acceso continuo a un producto.                                                                                                                                                                                                                                                         |

Veamos un ejemplo de cómo funcionan juntos los productos, las funcionalidades y los derechos. Imagina que quieres configurar un servicio recurrente que ofrezca dos niveles: un producto estándar con funcionalidad básica y un producto avanzado que agregue funcionalidad extendida.

1. Creas dos funcionalidades: `basic_features` y `extended_features`.
1. Creas dos productos: `standard_product` y `advanced_product`.
1. Para el producto estándar, creas una ProductFeature que asocia `basic_features` con `standard_product`.
1. Para el producto avanzado, creas dos ProductFeatures: una que asocia `basic_features` con `advanced_product` y otra que asocia `extended_features` con `advanced_product`.

Un cliente, `first_customer`, se suscribe al producto estándar. Cuando creas la suscripción, Stripe crea automáticamente un derecho que asocia `first_customer` con `basic_features`.

Otro cliente, `second_customer`, se suscribe al producto avanzado. Al crear la suscripción, Stripe crea automáticamente dos derechos: uno que asocia `second_customer` con `basic_features` y otro que asocia `second_customer` con `extended_features`.

Puedes determinar qué funcionalidades aprovisionar para un cliente [recuperando sus derechos activos o recibiendo notificaciones del evento Resumen de derechos activos](https://docs.stripe.com/billing/entitlements.md#entitlements). No tienes que recuperar sus suscripciones, productos y funcionalidades.

## Configura Stripe

Instala el cliente de Stripe que prefieras:

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

A continuación, instala la CLI de Stripe. La CLI proporciona pruebas de webhook y puedes ejecutarla para realizar llamadas API a Stripe. Esta guía muestra cómo utilizar la CLI para configurar un modelo de precios en una sección posterior.
Para obtener más opciones de instalación, consulta [Empezar a usar la CLI de Stripe](https://docs.stripe.com/stripe-cli.md).
## Crear el modelo de tarifas [CLI o Dashboard de Stripe]

Los [modelos de precios recurrentes](https://docs.stripe.com/products-prices/pricing-models.md) representan los productos o servicios que vendes, cuánto cuestan, qué monedas aceptas para los pagos y el período de servicio para las suscripciones. Para crear el modelo de precios, crea [productos](https://docs.stripe.com/api/products.md) (lo que vendes) y [precios](https://docs.stripe.com/api/prices.md) (cuánto cuestan y con qué frecuencia cobrar por los productos).

En este ejemplo, se utiliza una tarifa con tasa fija con dos opciones de niveles de servicio diferentes: básico y premium. Para cada opción de nivel de servicio, debes crear un producto y un precio recurrente. Si quieres agregar un cargo por única vez, como el costo de instalación, crea un tercer producto con un precio por única vez.

Cada producto se factura de forma mensual. El precio del producto básico es de 5 USD. El precio del producto premium es de 15 USD. Consulta la guía de [tarifas con tasa fija](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md) para ver un ejemplo con tres niveles.

#### Dashboard

Ve a la página [Agregar un producto](https://dashboard.stripe.com/test/products/create) y crea dos productos. Agrega un precio a cada producto, cada uno con un período de facturación mensual recurrente:

- Producto prémium: servicio prémium con más funcionalidades

  - Precio: Tarifa plana | 15 USD

- Producto básico: servicio básico con las funcionalidades mínimas

  - Precio: Tarifa plana | 5 USD

Después de crear los precios, registra los ID de precio para usarlos en otros pasos. Los ID de precio se ven así: `price_G0FvDp6vZvdwRZ`.

Cuando esté todo listo, usa el botón **Copiar en modo activo**, en la parte superior derecha de la página, para clonar el producto y pasarlo de [entorno de prueba a modo activo](https://docs.stripe.com/keys.md#test-live-modes).

#### API

Puedes usar la API para crear los [productos](https://docs.stripe.com/api/products.md) y los [precios](https://docs.stripe.com/api/prices.md).

Crear el producto premium:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

Crear el producto básico:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Basic Service" \
  -d "description=Basic service with minimum features"
```

Registra el ID de cada producto. Se ve así:

```json
{
  "id": "prod_H94k5odtwJXMtQ",
  "object": "product",
  "active": true,
  "attributes": [

  ],
  "created": 1587577341,
  "description": "Premium service with extra features",
  "images": [

  ],
  "livemode": false,
  "metadata": {
  },
  "name": "Billing Guide: Premium Service",
  "statement_descriptor": null,
  "type": "service",
  "unit_label": null,
  "updated": 1587577341
}
```

Usa los ID de producto para crear el precio de cada producto. El número [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) está en centavos. Por ejemplo, `1500` = 15 USD.

Crear el precio superior:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{PREMIUM_PRODUCT_ID}} \
  -d unit_amount=1500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Crear el precio básico:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{BASIC_PRODUCT_ID}} \
  -d unit_amount=500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Registra el ID de cada precio para poder utilizarlo en los pasos siguientes. Se ve así:

```json
{
  "id": "price_HGd7M3DV3IMXkC",
  "object": "price",
  "product": "prod_HGd6W1VUqqXGvr",
  "type": "recurring",
  "currency": "usd",
  "recurring": {
    "interval": "month",
    "interval_count": 1,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "active": true,
  "billing_scheme": "per_unit",
  "created": 1589319695,
  "livemode": false,
  "lookup_key": null,
  "metadata": {},
  "nickname": null,
  "unit_amount": 1500,
  "unit_amount_decimal": "1500",
  "tiers": null,
  "tiers_mode": null,
  "transform_quantity": null
}
```

## Crear el cliente [Cliente y servidor]

Stripe necesita un cliente para cada suscripción. En el front-end de tu solicitud, recopila toda la información necesaria de tus usuarios y envíala al back-end.

Si necesitas recopilar datos de la dirección, el Address Element te permite reunir una dirección de envío o facturación de tus clientes. Obtén más información sobre el Address Element en la página [Address Element](https://docs.stripe.com/elements/address-element.md).

```html
<form id="signup-form">
  <label>
    Email
    <input id="email" type="email" placeholder="Email address" value="test@example.com" required />
  </label>

  <button type="submit">
    Register
  </button>
</form>
```

```javascript
const emailInput = document.querySelector('#email');

fetch('/create-customer', {
  method: 'post',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: emailInput.value,
  }),
}).then(r => r.json());
```

En el servidor, crea un objeto que represente al cliente. Puede ser un objeto `Account` configurado por el cliente o un objeto `Customer`. Guarda el ID del objeto para usarlo en la sesión de Checkout.

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

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.preview" \
  --json '{
    "contact_email": "jenny.rosen@example.com",
    "display_name": "Jenny Rosen",
    "identity": {
        "individual": {
            "given_name": "Jenny Rosen",
            "address": {
                "city": "San Francisco",
                "country": "US",
                "line1": "123 Main Street",
                "postal_code": "94605",
                "state": "CA"
            }
        }
    },
    "configuration": {
        "customer": {
            "capabilities": {
                "automatic_indirect_tax": {
                    "requested": true
                }
            },
            "shipping": {
                "address": {
                    "city": "San Francisco",
                    "country": "US",
                    "line1": "123 Main Street",
                    "postal_code": "94605",
                    "state": "CA"
                }
            }
        }
    },
    "include": [
        "configuration.customer",
        "identity"
    ]
  }'
```

#### Customers v1

```curl
curl https://api.stripe.com/v1/customers \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "email=jenny.rosen@example.com" \
  -d "name=Jenny Rosen" \
  -d "shipping[address][city]=San Francisco" \
  -d "shipping[address][country]=US" \
  -d "shipping[address][line1]=123 Main Street" \
  -d "shipping[address][postal_code]=9460" \
  -d "shipping[address][state]=CA" \
  -d "shipping[name]=Jenny Rosen" \
  -d "address[city]=San Francisco" \
  -d "address[country]=US" \
  -d "address[line1]=123 Main Street" \
  -d "address[postal_code]=9460" \
  -d "address[state]=CA"
```

## Crea una Checkout Session [Servidor]

En el back-end de su aplicación, define un punto de conexión que [cree la sesión](https://docs.stripe.com/api/checkout/sessions/create.md) para que tu front-end la llame. Necesitarás el ID de precio de la suscripción que el cliente está contratando; tu front-end pasa este valor.

Si creaste un precio único en el [paso 2](https://docs.stripe.com/billing/subscriptions/build-subscriptions.md#create-pricing-model), pasa también ese ID de precio. Después de crear una Checkout Session, asegúrate de pasar el [secreto de cliente](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) de vuelta al cliente en la respuesta.

> Puedes utilizar [lookup_keys](https://docs.stripe.com/products-prices/manage-prices.md#lookup-keys) para obtener precios en lugar de ID de precios. Consulta la [solicitud de ejemplo](https://github.com/stripe-samples/subscription-use-cases/tree/main/fixed-price-subscriptions) para ver un ejemplo.

#### Accounts&nbsp;v2

#### Ruby

```ruby
require 'stripe'
require 'sinatra'

# This test secret API key is a placeholder. Don't include personal details in requests with this key.
# To see your test secret API key embedded in code samples, sign in to your Stripe account.
# You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys.
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
Stripe.api_key = '<<YOUR_SECRET_KEY>>'
Stripe.api_version = '2026-03-25.dahlia'

set :static, true
set :port, 4242

YOUR_DOMAIN = 'http://localhost:3000'

post '/create-checkout-session' do
  content_type 'application/json'

  session = Stripe::Checkout::Session.create({ui_mode: 'elements',
    # Provide the Account ID of the account you previously created
    customer_account: '{{CUSTOMER_ACCOUNT_ID}}',
    line_items: [{
      # Provide the exact Price ID (for example, price_1234) of the product you want to sell
      price: '{{PRICE_ID}}',
      quantity: 1,
    }],
    mode: 'subscription',
    return_url: YOUR_DOMAIN + '/return?session_id={CHECKOUT_SESSION_ID}',
  })

  { clientSecret: session.client_secret }.to_json
end

```

#### Customers&nbsp;v1

#### Ruby

```ruby
require 'stripe'
require 'sinatra'

# This test secret API key is a placeholder. Don't include personal details in requests with this key.
# To see your test secret API key embedded in code samples, sign in to your Stripe account.
# You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys.
# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>', stripe_version: '2026-03-25.dahlia')

set :static, true
set :port, 4242

YOUR_DOMAIN = 'http://localhost:3000'

post '/create-checkout-session' do
  content_type 'application/json'

  session = client.v1.checkout.sessions.create({ui_mode: 'elements',
    # Provide the customer ID of the customer you previously created
    customer: '{{CUSTOMER_ID}}',
    line_items: [{
      # Provide the exact Price ID (for example, price_1234) of the product you want to sell
      price: '{{PRICE_ID}}',
      quantity: 1,
    }],
    mode: 'subscription',
    return_url: YOUR_DOMAIN + '/return?session_id={CHECKOUT_SESSION_ID}',
  })

  { clientSecret: session.client_secret }.to_json
end

```

Desde tu [Dashboard](https://dashboard.stripe.com/settings/payment_methods), activa los métodos de pago que deseas aceptar de tus clientes. Checkout admite [varios métodos de pago](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support).

## Inicializar Checkout [Cliente]

#### HTML + JS

Llama a [initCheckoutElementsSdk](https://docs.stripe.com/js/custom_checkout/init) y pasa `clientSecret`.

`initCheckoutElementsSdk` resuelve un objeto de [Checkout](https://docs.stripe.com/js/custom_checkout) que contiene datos de la Checkout Session y métodos para actualizarla.

Lee el `total` y los `lineItems` de [actions.getSession()](https://docs.stripe.com/js/custom_checkout/session) y muéstralos en tu interfaz de usuario (IU). Esto te permite activar nuevas funcionalidades con cambios mínimos en el código. Por ejemplo, si agregas [precios manuales de monedas](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md), no es necesario hacer cambios en la interfaz de usuario (IU) si muestras el `total`.

```html
<div id="checkout-container"></div>
```

```javascript
const clientSecret = fetch('/create-checkout-session', {method: 'POST'})
  .then((response) => response.json())
  .then((json) => json.client_secret);

const checkout = stripe.initCheckoutElementsSdk({clientSecret});
const loadActionsResult = await checkout.loadActions();

if (loadActionsResult.type === 'success') {
  const session = loadActionsResult.actions.getSession();
  const checkoutContainer = document.getElementById('checkout-container');

  checkoutContainer.append(JSON.stringify(session.lineItems, null, 2));
  checkoutContainer.append(document.createElement('br'));
  checkoutContainer.append(`Total: ${session.total.total.amount}`);
}
```

#### React

Integra la solicitud con el componente [CheckoutProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider), pasa `clientSecret` y la instancia `stripe`.

```jsx
import React from 'react';
import {CheckoutElementsProvider} from '@stripe/react-stripe-js/checkout';
import CheckoutForm from './CheckoutForm';

const clientSecret = fetch('/create-checkout-session', {method: 'POST'})
  .then((response) => response.json())
  .then((json) => json.client_secret);

const App = () => {
  return (
    <CheckoutElementsProvider
      stripe={stripe}options={{clientSecret}}
    >
      <CheckoutForm />
    </CheckoutElementsProvider>
  );
};

export default App;
```

Accede al objeto [Checkout](https://docs.stripe.com/js/custom_checkout) en el componente del formulario de confirmación de compra con el hook `useCheckout()`. El objeto `Checkout` contiene datos de la sesión de confirmación de compra y métodos para actualizarla.

Lee el `total` y los `lineItems` del objeto `Checkout` y muéstralos en tu interfaz de usuario (IU). Esto te permite habilitar funcionalidades con cambios mínimos de código. Por ejemplo, agregar [precios manuales de monedas](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md) no requiere cambios en la interfaz de usuario (IU) si muestras el `total`.

```jsx
import React from 'react';
import {useCheckout} from '@stripe/react-stripe-js/checkout';

const CheckoutForm = () => {const checkoutState = useCheckout();

  if (checkoutState.type === 'loading') {
    return (
      <div>Loading...</div>
    );
  }

  if (checkoutState.type === 'error') {
    return (
      <div>Error: {checkoutState.error.message}</div>
    );
  }

  return (
    <form>{JSON.stringify(checkoutState.checkout.lineItems, null, 2)}
      {/* A formatted total amount */}
      Total: {checkoutState.checkout.total.total.amount}
    </form>
  );
};
```

## Recopila datos de pago [Cliente]

Recopila los datos de pago del cliente con el [Payment Element](https://docs.stripe.com/payments/payment-element.md). Payment Element es un componente de interfaz de usuario prediseñado que simplifica la recopilación de datos de pago para una variedad de métodos de pago.

El Payment Element contiene un iframe que envía la información de pago a Stripe de manera segura mediante una conexión HTTPS. No coloques el Payment Element dentro de otro iframe porque, para algunos métodos de pago, se requiere la redirección a otra página para la confirmación del pago.

Si optas por usar un iframe y quieres aceptar Apple Pay o Google Pay, el iframe debe tener el atributo [allow](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allowpaymentrequest) establecido en `«payment*»`.

Para que la integración funcione, la dirección de la página del proceso de compra debe empezar con `https://` rather en lugar de `http://` for. Puedes probar tu integración sin usar HTTPS, pero recuerda [habilitarla](https://docs.stripe.com/security/guide.md#tls) cuando todo esté listo para aceptar pagos activos.

#### HTML + JS

En primer lugar, crea un elemento DOM contenedor para montar el [Payment Element](https://docs.stripe.com/payments/payment-element.md). Luego, crea una instancia del `Payment Element` usando [checkout.createPaymentElement](https://docs.stripe.com/js/custom_checkout/create_payment_element) y móntala llamando a [element.mount](https://docs.stripe.com/js/element/mount), proporcionando un selector CSS o el elemento DOM contenedor.

```html
<div id="payment-element"></div>
```

```javascript
const paymentElement = checkout.createPaymentElement();
paymentElement.mount('#payment-element');
```

Consulta la [documentación Stripe.js](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) para ver las opciones admitidas.

Puedes [personalizar el aspecto](https://docs.stripe.com/payments/checkout/customization/appearance.md) de todos los Elements pasando [elementsOptions.appearance](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions-appearance) al inicializar Checkout en el front-end.

#### React

Arma el componente [Payment Element](https://docs.stripe.com/payments/payment-element.md) dentro del [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider).

```jsx
import React from 'react';import {PaymentElement, useCheckout} from '@stripe/react-stripe-js/checkout';

const CheckoutForm = () => {
  const checkoutState = useCheckout();

  if (checkoutState.type === 'loading') {
    return (
      <div>Loading...</div>
    );
  }

  if (checkoutState.type === 'error') {
    return (
      <div>Error: {checkoutState.error.message}</div>
    );
  }

  return (
    <form>

      {JSON.stringify(checkoutState.checkout.lineItems, null, 2)}
      {/* A formatted total amount */}
      Total: {checkoutState.checkout.total.total.amount}
<PaymentElement options={{layout: 'accordion'}}/>
    </form>
  );
};

export default CheckoutForm;
```

Consulta la [documentación Stripe.js](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) para ver las opciones admitidas.

Puedes [personalizar el aspecto](https://docs.stripe.com/payments/checkout/customization/appearance.md) de todos los Elements especificando [elementsOptions.appearance](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-appearance) en el [CheckoutElementsProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider).

## Envía el pago [Lado del cliente]

#### HTML + JS

Presenta un botón **Pagar** que llame a [confirmar](https://docs.stripe.com/js/custom_checkout/confirm) desde la instancia de `Checkout` para enviar el pago.

```html
<button id="pay-button">Pay</button>
<div id="confirm-errors"></div>
```

```js
const checkout = stripe.initCheckoutElementsSdk({clientSecret});

checkout.on('change', (session) => {
  document.getElementById('pay-button').disabled = !session.canConfirm;
});

const loadActionsResult = await checkout.loadActions();

if (loadActionsResult.type === 'success') {
  const {actions} = loadActionsResult;
  const button = document.getElementById('pay-button');
  const errors = document.getElementById('confirm-errors');
  button.addEventListener('click', () => {
    // Clear any validation errors
    errors.textContent = '';

    actions.confirm().then((result) => {
      if (result.type === 'error') {
        errors.textContent = result.error.message;
      }
    });
  });
}
```

#### React

Renderiza un botón **Pagar** que pase de[confirmar](https://docs.stripe.com/js/custom_checkout/confirm) a[useCheckout](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout) para enviar el pago.

```jsx
import React from 'react';
import {useCheckout} from '@stripe/react-stripe-js/checkout';

const PayButton = () => {
  const checkoutState = useCheckout();
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState(null);

  if (checkoutState.type !== "success") {
    return null;
  }

  const handleClick = () => {
    setLoading(true);checkoutState.checkout.confirm().then((result) => {
      if (result.type === 'error') {
        setError(result.error)
      }
      setLoading(false);
    })
  };

  return (
    <div>
      <button disabled={!checkoutState.checkout.canConfirm || loading} onClick={handleClick}>
        Pay
      </button>
      {error && <div>{error.message}</div>}
    </div>
  )
};

export default PayButton;
```

## Escucha webhooks [Servidor]

Para completar la integración, tienes que procesar los *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) que envió Stripe. Estos son eventos que se originan cada vez que un estado dentro de Stripe cambia, por ejemplo, cuando las suscripciones crean facturas nuevas. En tu aplicación, configura un controlador de HTTP para aceptar una solicitud POST que contenga el evento de webhook y verifica la firma del evento:

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/webhook' do
  # You can use webhooks to receive information about asynchronous payment events.
  # For more about our webhook events check out https://stripe.com/docs/webhooks.
  webhook_secret = ENV['STRIPE_WEBHOOK_SECRET']
  payload = request.body.read
  if !webhook_secret.empty?
    # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, webhook_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts '⚠️  Webhook signature verification failed.'
      status 400
      return
    end
  else
    data = JSON.parse(payload, symbolize_names: true)
    event = Stripe::Event.construct_from(data)
  end
  # Get the type of webhook event sent - used to check the status of PaymentIntents.
  event_type = event['type']
  data = event['data']
  data_object = data['object']

  if event_type == 'invoice.paid'
    # Used to provision services after the trial has ended.
    # The status of the invoice will show up as paid. Store the status in your
    # database to reference when a user accesses your service to avoid hitting rate
    # limits.
    # puts data_object
  end

  if event_type == 'invoice.payment_failed'
    # If the payment fails or the customer doesn't have a valid payment method,
    # an invoice.payment_failed event is sent, the subscription becomes past_due.
    # Use this webhook to notify your user that their payment has
    # failed and to retrieve new card details.
    # puts data_object
  end

  if event_type == 'customer.subscription.deleted'
    # handle subscription canceled automatically based
    # upon your subscription settings. Or if the user cancels it.
    # puts data_object
  end

  content_type 'application/json'
  { status: 'success' }.to_json
end
```

Durante el desarrollo, utiliza la CLI de Stripe para [observar los webhooks y reenviarlos a tu solicitud](https://docs.stripe.com/webhooks.md#test-webhook). Ejecuta lo siguiente en un terminal nuevo mientras se ejecuta tu aplicación de desarrollo:

#### curl

```bash
  stripe listen --forward-to localhost:4242/webhook
```

Para la producción, configura una URL de punto de conexión webhook en el Dashboard o utiliza la [API de puntos de conexión webhook](https://docs.stripe.com/api/webhook_endpoints.md) .

Necesitas escuchar algunos eventos para completar los pasos restantes de esta guía. Consulta [Eventos de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) para obtener más detalles sobre los webhooks específicos de suscripción.

## Brindar acceso a tu servicio [Cliente y servidor]

Ahora que la suscripción está activa, dale a tu usuario acceso a tu servicio. Para ello, escucha los eventos `customer.subscription.created`, `customer.subscription.updated`, y `customer.subscription.deleted`. Estos eventos pasan un objeto Subscription que contiene un campo `status` que indica si la suscripción está activa, vencida o cancelada. Consulta [el ciclo de vida de la suscripción](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle) para obtener una lista completa de estados.

En tu controlador de webhook:

1. Verifica el estado de la suscripción. Si es `activo`, entonces tu usuario ha pagado por su producto.
1. Revisa el producto al que se suscribió el cliente y bríndale acceso al servicio. Es mejor revisar el producto que el precio porque te da más flexibilidad en caso de que tengas que cambiar el precio o el período de facturación.
1. Almacena el estado `product.id`, `subscription.id` y `subscription.status` en tu base de datos junto con el `customer_account.id` o el `customer.id` que ya guardaste. Consulta este registro cuando tengas que determinar qué funcionalidades habilitar para el usuario en tu aplicación.

El estado de la suscripción puede cambiar en cualquier momento de su ciclo de vida, incluso si tu solicitud no hace ninguna llamada directa a Stripe. Por ejemplo, se puede producir un error de renovación debido a una tarjeta de crédito vencida, lo que genera que el estado de la suscripción pase a vencido. O, si usas el [portal de clientes](https://docs.stripe.com/customer-management.md), un usuario puede optar por cancelar la suscripción sin ingresar a tu aplicación directamente. El uso correcto del controlador mantiene el estado de tu solicitud sincronizado con Stripe.

## Cancelación de la suscripción [Cliente y servidor]

Con frecuencia, se les permite a los clientes cancelar su suscripción. En este ejemplo, se agrega la opción de cancelación en la página de configuración de la cuenta.
![Ejemplo de interfaz de cancelación de suscripción.](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png)

Configuración de la cuenta con la posibilidad de cancelar la suscripción

```javascript
function cancelSubscription(subscriptionId) {
  return fetch('/cancel-subscription', {
    method: 'post',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
    }),
  })
    .then(response => {
      return response.json();
    })
    .then(cancelSubscriptionResponse => {
      // Display to the user that the subscription has been canceled.
    });
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/cancel-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId'])

  deleted_subscription.to_json
end
```

En tu aplicación, se recibe un evento `customer.subscription.deleted`.

Una vez que se cancela la suscripción, actualiza tu base de datos para eliminar el ID de suscripción a Stripe que estaba almacenado y limitar el acceso al servicio.

Cuando se cancela una suscripción, no se puede reactivar. En su lugar, recopila la información de facturación actualizada de tu cliente, actualiza su método de pago predeterminado y crea una nueva suscripción con su registro de cliente existente.

## Prueba la integración

### Prueba métodos de pago

Usa la siguiente tabla para probar diferentes métodos y escenarios de pago.

| Método de pago      | Escenario                                                                                                                                                                                                                                                                                       | Cómo hacer la prueba                                                                                                                                                                         |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Débito directo BECS | Tu cliente paga correctamente con débito directo BECS.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `900123456` y BSB `000000`. El PaymentIntent confirmado pasa en un principio al estado `processing` y, tres minutos más tarde, a `succeeded`. |
| Débito directo BECS | El pago de tu cliente falla con un código de error `account_closed`.                                                                                                                                                                                                                            | Completa el formulario con el número de cuenta `111111113` y BSB `000000`.                                                                                                                   |
| Tarjeta de crédito  | El pago con tarjeta se efectúa correctamente y no requiere autenticación.                                                                                                                                                                                                                       | Completa el formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | El pago con tarjeta 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). | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | La tarjeta es rechazada con el código `insufficient_funds`.                                                                                                                                                                                                                                     | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Débito directo SEPA | Tu cliente paga correctamente con débito directo SEPA.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `AT321904300235473204`. El PaymentIntent confirmado pasa inicialmente al estado “en proceso” y, tres minutos más tarde, a “completado”.       |
| Débito directo SEPA | El estado de PaymentIntent de tu cliente pasa de `processing` a `requires_payment_method`.                                                                                                                                                                                                      | Completa el formulario con el número de cuenta `AT861904300235473202`.                                                                                                                       |

### Supervisa los acontecimientos

Configura webhooks para escuchar los eventos de cambio de suscripción, como actualizaciones y cancelaciones. Más información sobre [webhooks de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md). Puedes ver los eventos en el [Dashboard](https://dashboard.stripe.com/test/events) o con [Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook).

Para más detalles, consulta [Comprobación de la integración con Billing](https://docs.stripe.com/billing/testing.md).

## Optional: Permitir que los clientes cambien de plan [Cliente y servidor]

Para permitirles a los clientes cambiar de suscripción, recopila el ID de precio de la opción a la que quieren pasar. A continuación, envía el nuevo ID de precio desde el front-end a un punto de conexión del back-end. En el ejemplo, también se especifica el ID de suscripción, pero puedes recuperarlo de tu base de datos para el usuario que ha iniciado sesión.

```javascript
function updateSubscription(priceId, subscriptionId) {
  return fetch('/update-subscription', {
    method: 'post',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
      newPriceId: priceId,
    }),
  })
    .then(response => {
      return response.json();
    })
    .then(response => {
      return response;
    });
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada especificando el ID de suscripción y el nuevo ID de precio. La suscripción ahora es una suscripción prémium que cuesta USD 15 por mes en lugar de una suscripción básica de USD 5 por mes.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/update-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  updated_subscription =
    client.v1.subscriptions.update(
      data['subscriptionId'],
      cancel_at_period_end: false,
      items: [
        { id: subscription.items.data[0].id, price: data['newPriceId'] }
      ]
    )

  updated_subscription.to_json
end
```

En tu aplicación, se recibe un evento `customer.subscription.updated`.

## Optional: Previsualizar un cambio de precio [Cliente y servidor]

Cuando tu cliente cambia de suscripción, a menudo se produce un ajuste del importe que debe, conocido como [prorrateo](https://docs.stripe.com/billing/subscriptions/prorations.md). Puedes utilizar el [punto de conexión de creación de factura preliminar](https://docs.stripe.com/api/invoices/create_preview.md) para mostrar el importe ajustado a tus clientes.

En el front-end, pasa los detalles de creación de vista previa de la factura a un punto de conexión de back-end.

#### Accounts&nbsp;v2

```javascript
function createPreviewInvoice(
  customerAccountId,
  subscriptionId,
  newPriceId,
  trialEndDate
) {
  return fetch('/create-preview-invoice', {
    method: 'post',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({
      customerAccountId: customerAccountId,
      subscriptionId: subscriptionId,
      newPriceId: newPriceId,
    }),
  })
    .then(response => {
      return response.json();
    })
    .then((invoice) => {
      return invoice;
    });
}
```

#### Customers&nbsp;v1

```javascript
function createPreviewInvoice(
  customerId,
  subscriptionId,
  newPriceId,
  trialEndDate
) {
  return fetch('/create-preview-invoice', {
    method: 'post',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({
      customerId: customerId,
      subscriptionId: subscriptionId,
      newPriceId: newPriceId,
    }),
  })
    .then(response => {
      return response.json();
    })
    .then((invoice) => {
      return invoice;
    });
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Accounts&nbsp;v2

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = Stripe::Subscription.retrieve(data['subscriptionId'])

  invoice =
    Stripe::Invoice.create_preview(
      customer_account: data['customerAccountId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

#### Customers&nbsp;v1

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  invoice =
    client.v1.invoices.create_preview(
      customer: data['customerId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

## Optional: Mostrar el método de pago del cliente [Cliente y servidor]

Mostrar la marca y los últimos 4 dígitos de la tarjeta le permite saber al cliente qué tarjeta se está utilizando o si es necesario actualizar el método de pago.

En el front end, envía el identificador del método de pago a un punto de conexión que recupere los detalles del método de pago.

```javascript
function retrieveCustomerPaymentMethod(paymentMethodId) {
  return fetch('/retrieve-customer-payment-method', {
    method: 'post',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({
      paymentMethodId: paymentMethodId,
    }),
  })
    .then((response) => {
      return response.json();
    })
    .then((response) => {
      return response;
    });
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/retrieve-customer-payment-method' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId'])

  payment_method.to_json
end
```

Ejemplo de respuesta:

```json
{
  "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42",
  "object": "payment_method",
  "billing_details": {
    "address": {
      "city": null,
      "country": null,
      "line1": null,
      "line2": null,
      "postal_code": null,
      "state": null
    },
    "email": null,
    "name": null,
    "phone": null
  },
  "card": {
    "brand": "visa",
    "checks": {
      "address_line1_check": null,
      "address_postal_code_check": null,
      "cvc_check": "pass"
    },
    "country": "US",
    "exp_month": 8,
    "exp_year": 2021,
    "fingerprint": "Xt5EWLLDS7FJjR1c",
    "funding": "credit",
    "generated_from": null,
    "last4": "4242",
    "three_d_secure_usage": {
      "supported": true
    },
    "wallet": null
  },
  "created": 1588010536,
  "customer": "cus_HAxB7dVQxhoKLh",
  "livemode": false,
  "metadata": {},
  "type": "card"
}
```

> Te recomendamos guardar `paymentMethod.id` y `last4` en tu base de datos, por ejemplo, `paymentMethod.id` como `stripeCustomerPaymentMethodId` en tu colección o tabla de `users`. Si lo necesitas, también tienes la opción de guardar `exp_month`, `exp_year`, `fingerprint` y `billing_details`. Esto sirve para limitar el número de llamadas a Stripe, mejorar el rendimiento y evitar una posible limitación de la frecuencia.

## Cuéntales a tus clientes qué es Stripe

Stripe recopila información sobre las interacciones de los clientes con Elements para proporcionarte servicios, mejorarlos y prevenir el fraude. Esto incluye el uso de cookies y direcciones IP para identificar qué Elements vio un cliente durante una sola sesión de finalización de compra. Tienes la responsabilidad de divulgar y obtener todos los derechos y consentimientos necesarios para que Stripe use los datos para dichos fines. Si deseas obtener más información, visita nuestro [centro de privacidad](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe).

#### API Payment Intents

#### Esfuerzo de integración
Complexity: 4/5
#### Tipo de integración

Combina componentes de la interfaz de usuario (IU) en un flujo de pago personalizado

#### Personalización de la interfaz de usuario (IU)

Personalización a nivel CSS con la [API Appearance](https://docs.stripe.com/elements/appearance-api.md)

Crea un formulario de pago personalizado con [Stripe Elements](https://docs.stripe.com/payments/elements.md) y la [API Payment Intents](https://docs.stripe.com/api/payment_intents.md) para vender *subscriptions* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) a un precio fijo. Comprueba cómo esta integración [se compara con otros tipos de integraciones de Stripe](https://docs.stripe.com/payments/online-payments.md#compare-features-and-availability).

La API Payment Intents es una API de nivel más bajo que puedes usar para crear tu propio flujo de pago o de confirmación de compra, pero requiere significativamente más código y mantenimiento constante. Recomendamos [Payment Element con Checkout Sessions](https://docs.stripe.com/payments/quickstart-checkout-sessions.md) para la mayoría de las integraciones, ya que cubre flujos de pago similares a los de Payment Intents. Obtén más información sobre [cuándo usar Checkout Sessions en lugar de PaymentIntents](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md).

Si no deseas crear un formulario de pago personalizado, puedes integrarlo en la versión alojada del proceso de compra. Si deseas una versión completa de esa guía de integración, consulta la [Guía de inicio rápido de Billing](https://docs.stripe.com/billing/quickstart.md).

Si no estás listo para programar una integración, puedes configurar suscripciones básicas [de forma manual en el Dashboard](https://docs.stripe.com/no-code/subscriptions.md). También puedes usar [Payment&nbsp;Links](https://docs.stripe.com/payment-links.md) para configurar suscripciones sin programar nada. Obtén más información sobre [cómo diseñar una integración](https://docs.stripe.com/billing/subscriptions/design-an-integration.md) para comprender las decisiones que debes tomar y los recursos que necesitas.

## Tu próximo desarrollo

Esta guía te explica cómo:

- Crea un catálogo de productos.
- Crear un proceso de inscripción que genere un cliente.
- Crear suscripciones y recopilar información de pago.
- Comprobar y monitorear el estado de los pagos y las suscripciones.
- Permitir que los clientes cambien de plan o cancelen la suscripción.
- Aprende a utilizar el [modo de facturación flexible](https://docs.stripe.com/billing/subscriptions/billing-mode.md) para acceder a un comportamiento de facturación mejorado y a funcionalidades adicionales.

## Cómo construir en Stripe

[Subscriptions](https://docs.stripe.com/api/subscriptions.md) simplifica tu facturación creando automáticamente *facturas* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice) y [PaymentIntents](https://docs.stripe.com/api/payment_intents.md) por ti. Para crear y activar una suscripción, necesitas crear primero un *producto para definir lo que vendes, y un *precio, que determina el importe por cobrar y la frecuencia. También necesitas un objeto `Account` configurado por el cliente o un objeto `Customer` para almacenar los *PaymentMethods* utilizados para realizar cada pago recurrente.**

#### Accounts&nbsp;v2
Diagrama que muestra objetos de facturación comunes y sus relaciones (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions)
#### Customer v1
Diagrama que muestra objetos de facturación comunes y sus relaciones (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions)
### Definiciones de los objetos de la API

| Recurso                                                                                                                                | Definición                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Cuenta configurada como un cliente](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | Representa a un cliente en la API Accounts v2 que compra una suscripción. Configura un objeto `Cuenta` como cliente y asócialo a una suscripción para realizar cargos recurrentes y hacerles un seguimiento, y para gestionar los productos a los que se suscribe. Consulta nuestra [guía Usar cuentas como clientes](https://docs.stripe.com/connect/use-accounts-as-customers.md) para obtener más información.                                 |
| [Customer](https://docs.stripe.com/api/customers.md)                                                                                   | Representa a un cliente en la API Clientes que compra una suscripción. Usa el objeto `Cliente` asociado a una suscripción para realizar y hacer seguimiento de los cargos recurrentes y administrar los productos a los que se suscriben.                                                                                                                                                                                                         |
| [Derecho](https://docs.stripe.com/api/entitlements/active-entitlement.md)                                                              | Representa el acceso de un cliente a una funcionalidad incluida en un producto de servicio al que está suscrito. Cuando creas una suscripción para la compra recurrente de un producto por parte de un cliente, se crea automáticamente un derecho activo para cada funcionalidad asociada a ese producto. Cuando un cliente accede a tus servicios, utiliza sus derechos activos para habilitar las funcionalidades incluidas en su suscripción. |
| [Funcionalidad](https://docs.stripe.com/api/entitlements/feature.md)                                                                   | Representa una funcionalidad o capacidad a la que tus clientes pueden acceder cuando se suscriben a un producto de servicio. Puedes incluir funciones en un producto creando ProductFeatures.                                                                                                                                                                                                                                                     |
| [Factura](https://docs.stripe.com/api/invoices.md)                                                                                     | Una declaración de importes que un cliente adeuda y que rastrea los estados de pago desde el borrador hasta su pago o su finalización. Las suscripciones generan facturas automáticamente.                                                                                                                                                                                                                                                        |
| [PaymentIntent](https://docs.stripe.com/api/payment_intents.md)                                                                        | Una forma de crear flujos de pago dinámicos. Un PaymentIntent hace un seguimiento del ciclo de vida del flujo del proceso compra del cliente y activa pasos adicionales de autenticación, si así lo exigen las disposiciones normativas, las reglas antifraude personalizadas de Radar o los métodos de pago con redireccionamiento. Las facturas crean PaymentIntents de forma automática.                                                       |
| [PaymentMethod](https://docs.stripe.com/api/payment_methods.md)                                                                        | Los métodos de pago que usa un cliente para pagar tus productos. Por ejemplo, puedes guardar una tarjeta de crédito en un objeto `Cuenta` o `Cliente` configurado por el cliente y usarla para hacer pagos recurrentes para ese cliente. Por lo general, se usa con las API Payment Intents o Setup Intents.                                                                                                                                      |
| [Precio](https://docs.stripe.com/api/prices.md)                                                                                        | Define el precio por unidad, la moneda y el ciclo de facturación para un producto.                                                                                                                                                                                                                                                                                                                                                                |
| [Producto](https://docs.stripe.com/api/products.md)                                                                                    | Un bien o servicio que vende tu empresa. Un producto de servicio puede incluir una o más funciones.                                                                                                                                                                                                                                                                                                                                               |
| [ProductFeature](https://docs.stripe.com/api/product-feature.md)                                                                       | Representa la inclusión de una sola funcionalidades en un solo producto. Cada producto está asociado a una ProductFeature para cada funcionalidad que incluye, y cada funcionalidad está asociada a una ProductFeature para cada producto que la incluye.                                                                                                                                                                                         |
| [Suscripción](https://docs.stripe.com/api/subscriptions.md)                                                                            | Representa la compra recurrente programada de un producto por parte de un cliente. Usa una suscripción para cobrar pagos y proporcionar entrega repetida o acceso continuo a un producto.                                                                                                                                                                                                                                                         |

Veamos un ejemplo de cómo funcionan juntos los productos, las funcionalidades y los derechos. Imagina que quieres configurar un servicio recurrente que ofrezca dos niveles: un producto estándar con funcionalidad básica y un producto avanzado que agregue funcionalidad extendida.

1. Creas dos funcionalidades: `basic_features` y `extended_features`.
1. Creas dos productos: `standard_product` y `advanced_product`.
1. Para el producto estándar, creas una ProductFeature que asocia `basic_features` con `standard_product`.
1. Para el producto avanzado, creas dos ProductFeatures: una que asocia `basic_features` con `advanced_product` y otra que asocia `extended_features` con `advanced_product`.

Un cliente, `first_customer`, se suscribe al producto estándar. Cuando creas la suscripción, Stripe crea automáticamente un derecho que asocia `first_customer` con `basic_features`.

Otro cliente, `second_customer`, se suscribe al producto avanzado. Al crear la suscripción, Stripe crea automáticamente dos derechos: uno que asocia `second_customer` con `basic_features` y otro que asocia `second_customer` con `extended_features`.

Puedes determinar qué funcionalidades aprovisionar para un cliente [recuperando sus derechos activos o recibiendo notificaciones del evento Resumen de derechos activos](https://docs.stripe.com/billing/entitlements.md#entitlements). No tienes que recuperar sus suscripciones, productos y funcionalidades.

## Configura Stripe

Instala el cliente de Stripe que prefieras:

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

A continuación, instala la CLI de Stripe. La CLI proporciona pruebas de webhooks y puedes ejecutarla para realizar llamadas API a Stripe. Esta guía muestra cómo utilizar la CLI para configurar un modelo de precios en una sección posterior.
Para obtener más opciones de instalación, consulta [Empezar a usar la CLI de Stripe](https://docs.stripe.com/stripe-cli.md).
## Crear el modelo de tarifas [CLI o Dashboard de Stripe]

Los [modelos de precios recurrentes](https://docs.stripe.com/products-prices/pricing-models.md) representan los productos o servicios que vendes, cuánto cuestan, qué monedas aceptas para los pagos y el período de servicio para las suscripciones. Para crear el modelo de precios, crea [productos](https://docs.stripe.com/api/products.md) (lo que vendes) y [precios](https://docs.stripe.com/api/prices.md) (cuánto cuestan y con qué frecuencia cobrar por los productos).

En este ejemplo, se utiliza una tarifa con tasa fija con dos opciones de niveles de servicio diferentes: básico y premium. Para cada opción de nivel de servicio, debes crear un producto y un precio recurrente. Si quieres agregar un cargo por única vez, como el costo de instalación, crea un tercer producto con un precio por única vez.

Cada producto se factura de forma mensual. El precio del producto básico es de 5 USD. El precio del producto premium es de 15 USD. Consulta la guía de [tarifas con tasa fija](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md) para ver un ejemplo con tres niveles.

#### Dashboard

Ve a la página [Agregar un producto](https://dashboard.stripe.com/test/products/create) y crea dos productos. Agrega un precio a cada producto, cada uno con un período de facturación mensual recurrente:

- Producto prémium: servicio prémium con más funcionalidades

  - Precio: Tarifa plana | 15 USD

- Producto básico: servicio básico con las funcionalidades mínimas

  - Precio: Tarifa plana | 5 USD

Después de crear los precios, registra los ID de precio para usarlos en otros pasos. Los ID de precio se ven así: `price_G0FvDp6vZvdwRZ`.

Cuando esté todo listo, usa el botón **Copiar en modo activo**, en la parte superior derecha de la página, para clonar el producto y pasarlo de [entorno de prueba a modo activo](https://docs.stripe.com/keys.md#test-live-modes).

#### API

Puedes usar la API para crear los [productos](https://docs.stripe.com/api/products.md) y los [precios](https://docs.stripe.com/api/prices.md).

Crear el producto premium:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

Crear el producto básico:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Basic Service" \
  -d "description=Basic service with minimum features"
```

Registra el ID de cada producto. Se ve así:

```json
{
  "id": "prod_H94k5odtwJXMtQ",
  "object": "product",
  "active": true,
  "attributes": [

  ],
  "created": 1587577341,
  "description": "Premium service with extra features",
  "images": [

  ],
  "livemode": false,
  "metadata": {
  },
  "name": "Billing Guide: Premium Service",
  "statement_descriptor": null,
  "type": "service",
  "unit_label": null,
  "updated": 1587577341
}
```

Usa los ID de producto para crear el precio de cada producto. El número [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) está en centavos. Por ejemplo, `1500` = 15 USD.

Crear el precio superior:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{PREMIUM_PRODUCT_ID}} \
  -d unit_amount=1500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Crear el precio básico:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{BASIC_PRODUCT_ID}} \
  -d unit_amount=500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Registra el ID de cada precio para poder utilizarlo en los pasos siguientes. Se ve así:

```json
{
  "id": "price_HGd7M3DV3IMXkC",
  "object": "price",
  "product": "prod_HGd6W1VUqqXGvr",
  "type": "recurring",
  "currency": "usd",
  "recurring": {
    "interval": "month",
    "interval_count": 1,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "active": true,
  "billing_scheme": "per_unit",
  "created": 1589319695,
  "livemode": false,
  "lookup_key": null,
  "metadata": {},
  "nickname": null,
  "unit_amount": 1500,
  "unit_amount_decimal": "1500",
  "tiers": null,
  "tiers_mode": null,
  "transform_quantity": null
}
```

## Crear el cliente [Cliente y servidor]

Stripe necesita un cliente para cada suscripción. En el front-end de tu solicitud, recopila toda la información necesaria de tus usuarios y envíala al back-end.

Si necesitas recopilar datos de la dirección, el Address Element te permite reunir una dirección de envío o facturación de tus clientes. Obtén más información sobre el Address Element en la página [Address Element](https://docs.stripe.com/elements/address-element.md).

```html
<form id="signup-form">
  <label>
    Email
    <input id="email" type="email" placeholder="Email address" value="test@example.com" required />
  </label>

  <button type="submit">
    Register
  </button>
</form>
```

```javascript
const emailInput = document.querySelector('#email');

fetch('/create-customer', {
  method: 'post',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: emailInput.value,
  }),
}).then(r => r.json());
```

En el servidor, crea un objeto que represente al cliente. Puede ser un objeto `Account` configurado por el cliente o un objeto `Customer`. Guarda el ID del objeto para usarlo en la sesión de Checkout.

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

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.preview" \
  --json '{
    "contact_email": "jenny.rosen@example.com",
    "display_name": "Jenny Rosen",
    "identity": {
        "individual": {
            "given_name": "Jenny Rosen",
            "address": {
                "city": "San Francisco",
                "country": "US",
                "line1": "123 Main Street",
                "postal_code": "94605",
                "state": "CA"
            }
        }
    },
    "configuration": {
        "customer": {
            "capabilities": {
                "automatic_indirect_tax": {
                    "requested": true
                }
            },
            "shipping": {
                "address": {
                    "city": "San Francisco",
                    "country": "US",
                    "line1": "123 Main Street",
                    "postal_code": "94605",
                    "state": "CA"
                }
            }
        }
    },
    "include": [
        "configuration.customer",
        "identity"
    ]
  }'
```

#### Customers v1

```curl
curl https://api.stripe.com/v1/customers \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "email=jenny.rosen@example.com" \
  -d "name=Jenny Rosen" \
  -d "shipping[address][city]=San Francisco" \
  -d "shipping[address][country]=US" \
  -d "shipping[address][line1]=123 Main Street" \
  -d "shipping[address][postal_code]=9460" \
  -d "shipping[address][state]=CA" \
  -d "shipping[name]=Jenny Rosen" \
  -d "address[city]=San Francisco" \
  -d "address[country]=US" \
  -d "address[line1]=123 Main Street" \
  -d "address[postal_code]=9460" \
  -d "address[state]=CA"
```

## Crear la suscripción [Cliente y servidor]

> Si deseas renderizar el Payment Element sin crear primero una suscripción, consulta [Recopilación de datos de pago antes de crear una intención](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription).

Permite que tu cliente elija un plan y, a continuación, crea la suscripción. En el ejemplo de esta guía, el cliente elige entre un plan Básico o un plan Premium.

En el front end, pasa el ID del precio seleccionado y el ID del registro del cliente al back end.

#### Accounts&nbsp;v2

```javascript
fetch('/create-subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    priceId: priceId,
    customerAccountId: customerAccountId,
  }),
})
```

#### Customers&nbsp;v1

```javascript
fetch('/create-subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    priceId: priceId,
    customerId: customerId,
  }),
})
```

En el back end, cree la suscripción con un estado `incomplete` utilizando `payment_behavior=default_incomplete`. A continuación, devuelve el `client_secret` del primer [PaymentIntent](https://docs.stripe.com/payments/payment-intents.md) de la suscripción al front end para completar el pago. Para ello, expande el [confirmation_secret](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) en la última factura de la suscripción.

Para habilitar [el comportamiento de suscripción mejorado](https://docs.stripe.com/billing/subscriptions/billing-mode.md), establece `billing_mode[type]` en `flexible`. Debes utilizar la versión de la API de Stripe [2025-06-30.basil](https://docs.stripe.com/changelog/basil.md#2025-06-30.basil) o posterior.

Establece [save_default_payment_method](https://docs.stripe.com/api/subscriptions/object.md#subscription_object-payment_settings-save_default_payment_method) en `on_subscription` para guardar el método de pago como predeterminado para una suscripción cuando un pago tiene éxito. Guardar un método de pago como predeterminado aumenta la tasa de éxito de futuros pagos de suscripciones.

En el siguiente ejemplo, se crea una `Subscription` y se expande el `confirmation_secret` de su última factura en la respuesta. Esto te permite pasar el secreto al front-end para confirmar el pago.

#### Accounts&nbsp;v2

```curl
curl https://api.stripe.com/v1/subscriptions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d "items[0][price]={{PRICE_ID}}" \
  -d payment_behavior=default_incomplete \
  -d "payment_settings[save_default_payment_method]=on_subscription" \
  -d "billing_mode[type]=flexible" \
  -d "expand[0]=latest_invoice.confirmation_secret"
```

#### Customers&nbsp;v1

```curl
curl https://api.stripe.com/v1/subscriptions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d "items[0][price]={{PRICE_ID}}" \
  -d payment_behavior=default_incomplete \
  -d "payment_settings[save_default_payment_method]=on_subscription" \
  -d "billing_mode[type]=flexible" \
  -d "expand[0]=latest_invoice.confirmation_secret"
```

> Si estás utilizando un *precio en múltiples monedas* (A single Price object can support multiple currencies. Each purchase uses one of the supported currencies for the Price, depending on how you use the Price in your integration), utiliza el parámetro [moneda](https://docs.stripe.com/api/subscriptions/create.md#create_subscription-currency) para indicarle a la suscripción cuál de las monedas admitidas debe utilizar. Si omites el parámetro `currency`, la suscripción utilizará la moneda por defecto.

La suscripción ahora está `inactive` y a la espera de pago. El ejemplo de respuesta que figura a continuación destaca los campos mínimos que deben almacenarse, pero puedes almacenar los campos a los que tu solicitud accede con frecuencia.

#### Accounts&nbsp;v2

```json
{"id": "sub_JgRjFjhKbtD2qz",
  "object": "subscription",
  "application_fee_percent": null,
  "automatic_tax": {
    "disabled_reason": null,
    "enabled": false,
    "liability": "null"
  },
  "billing_cycle_anchor": 1623873347,
  "billing_cycle_anchor_config": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "cancellation_details": {
    "comment": null,
    "feedback": null,
    "reason": null
  },
  "collection_method": "charge_automatically",
  "created": 1623873347,
  "currency": "usd","customer_account": identifier("customerAccount"),
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [

  ],
  "discounts": [],
  "ended_at": null,
  "invoice_customer_balance_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_JgRjmS4Ur1khEx",
        "object": "subscription_item",
        "created": 1623873347,"current_period_end": 1626465347,
        "current_period_start": 1623873347,
        "discounts": [],
        "metadata": {
        },
        "plan": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "plan",
          "active": true,
          "amount": 2000,
          "amount_decimal": "2000",
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "price": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 2000,
          "unit_amount_decimal": "2000"
        },
        "quantity": 1,
        "subscription": "sub_JgRjFjhKbtD2qz",
        "tax_rates": [

        ]
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz"
  },
  "latest_invoice": {
    "id": "in_1J34pzGPZ1iASj5zB87qdBNZ",
    "object": "invoice",
    "account_country": "US",
    "account_name": "Angelina's Store",
    "account_tax_ids": null,
    "amount_due": 2000,
    "amount_overpaid": 0,
    "amount_paid": 0,
    "amount_remaining": 2000,
    "amount_shipping": 0,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "disabled_reason": null,
      "enabled": false,
      "liability": null,
      "status": null
    },
    "automatically_finalizes_at": null,
    "billing_reason": "subscription_update",
    "collection_method": "charge_automatically",
    "created": 1623873347,
    "currency": "usd",
    "custom_fields": null,
    "customer_account": identifier("customerAccount"),
    "customer_address": null,
    "customer_email": "angelina@stripe.com",
    "customer_name": null,
    "customer_phone": null,
    "customer_shipping": {
      "address": {
        "city": "",
        "country": "US",
        "line1": "Berry",
        "line2": "",
        "postal_code": "",
        "state": ""
      },
      "name": "",
      "phone": null
    },
    "customer_tax_exempt": "none",
    "customer_tax_ids": [

    ],
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [

    ],
    "description": null,
    "discounts": [],
    "due_date": null,
    "effective_at": "1623873347",
    "ending_balance": 0,
    "footer": null,
    "from_invoice": null,
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp",
    "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf",
    "last_finalization_error": null,
    "latest_revision": null,
    "lines": {
      "object": "list",
      "data": [
        {
          "id": "il_1N2CjMBwKQ696a5NeOawRQP2",
          "object": "line_item",
          "amount": 2000,
          "currency": "usd",
          "description": "1 × Gold Special (at $20.00 / month)",
          "discount_amounts": [

          ],
          "discountable": true,
          "discounts": [

          ],
          "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
          "livemode": false,
          "metadata": {
          },
          "parent": {
            "invoice_item_details": null,
            "subscription_item_details":
            {
              "invoice_item": null,
            "proration": false,
            "proration_details":
            {
              "credited_items": null
            },
            "subscription":
            "sub_JgRjFjhKbtD2qz",
            "subscription_item":
              "si_JgRjmS4Ur1khEx"
            },
            "type": "subscription_item_details"
          },
          "period": {
            "end": 1626465347,
            "start": 1623873347
          },
          "plan": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "plan",
            "active": true,
            "amount": 2000,
            "amount_decimal": "2000",
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "price": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "recurring": {
              "interval": "month",
              "interval_count": 1,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 2000,
            "unit_amount_decimal": "2000"
          },
          "quantity": 1,
          "taxes": []
        }
      ],
      "has_more": false,
      "total_count": 1,
      "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines"
    },
    "livemode": false,
    "metadata": {
    },
    "next_payment_attempt": null,
    "number": "C008FC2-0354",
    "on_behalf_of": null,
    "parent": {
      "quote_details": null,
      "subscription_details": {
        "metadata": {},
        "pause_collection": null,
        "subscription": "sub_JgRjFjhKbtD2qz"
      }
    },
    "payment_intent": {
      "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6"
      },
      "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu",
      "confirmation_method": "automatic",
      "created": 1623873347,
      "currency": "usd",
      "customer": "cus_CMqDWO2xODTZqt",
      "description": "Subscription creation",
      "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
      "last_payment_error": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "receipt_email": null,
      "review": null,
      "setup_future_usage": "off_session",
      "shipping": null,
      "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ",
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_confirmation",
      "transfer_data": null,
      "transfer_group": null
    },
    "payment_settings": {
      "payment_method_options": null,
      "payment_method_types": null,
      "save_default_payment_method": "on_subscription"
    },
    "period_end": 1623873347,
    "period_start": 1623873347,
    "post_payment_credit_notes_amount": 0,
    "pre_payment_credit_notes_amount": 0,
    "receipt_number": null,
    "starting_balance": 0,
    "statement_descriptor": null,
    "status": "open",
    "status_transitions": {
      "finalized_at": 1623873347,
      "marked_uncollectible_at": null,
      "paid_at": null,
      "voided_at": null
    },
    "subscription": "sub_JgRjFjhKbtD2qz",
    "subtotal": 2000,
    "tax": null,
    "tax_percent": null,
    "total": 2000,
    "total_discount_amounts": [],
    "total_tax_amounts": [],
    "transfer_data": null,
    "webhooks_delivered_at": 1623873347
  },
  "livemode": false,
  "metadata": {
  },
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "plan": {
    "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
    "object": "plan",
    "active": true,
    "amount": 2000,
    "amount_decimal": "2000",
    "billing_scheme": "per_unit",
    "created": 1623864151,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "nickname": null,
    "product": "prod_JgPF5xnq7qBun3",
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "schedule": null,
  "start": 1623873347,
  "start_date": 1623873347,
  "status": "incomplete",
  "tax_percent": null,
  "transfer_data": null,
  "trial_end": null,
  "trial_start": null
}
```

#### Customers&nbsp;v1

```json
{"id": "sub_JgRjFjhKbtD2qz",
  "object": "subscription",
  "application_fee_percent": null,
  "automatic_tax": {
    "disabled_reason": null,
    "enabled": false,
    "liability": "null"
  },
  "billing_cycle_anchor": 1623873347,
  "billing_cycle_anchor_config": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "cancellation_details": {
    "comment": null,
    "feedback": null,
    "reason": null
  },
  "collection_method": "charge_automatically",
  "created": 1623873347,
  "currency": "usd","customer": identifier("customer"),
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [

  ],
  "discounts": [],
  "ended_at": null,
  "invoice_customer_balance_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_JgRjmS4Ur1khEx",
        "object": "subscription_item",
        "created": 1623873347,"current_period_end": 1626465347,
        "current_period_start": 1623873347,
        "discounts": [],
        "metadata": {
        },
        "plan": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "plan",
          "active": true,
          "amount": 2000,
          "amount_decimal": "2000",
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "price": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 2000,
          "unit_amount_decimal": "2000"
        },
        "quantity": 1,
        "subscription": "sub_JgRjFjhKbtD2qz",
        "tax_rates": [

        ]
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz"
  },
  "latest_invoice": {
    "id": "in_1J34pzGPZ1iASj5zB87qdBNZ",
    "object": "invoice",
    "account_country": "US",
    "account_name": "Angelina's Store",
    "account_tax_ids": null,
    "amount_due": 2000,
    "amount_overpaid": 0,
    "amount_paid": 0,
    "amount_remaining": 2000,
    "amount_shipping": 0,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "disabled_reason": null,
      "enabled": false,
      "liability": null,
      "status": null
    },
    "automatically_finalizes_at": null,
    "billing_reason": "subscription_update",
    "collection_method": "charge_automatically",
    "created": 1623873347,
    "currency": "usd",
    "custom_fields": null,
    "customer": identifier("customer"),
    "customer_address": null,
    "customer_email": "angelina@stripe.com",
    "customer_name": null,
    "customer_phone": null,
    "customer_shipping": {
      "address": {
        "city": "",
        "country": "US",
        "line1": "Berry",
        "line2": "",
        "postal_code": "",
        "state": ""
      },
      "name": "",
      "phone": null
    },
    "customer_tax_exempt": "none",
    "customer_tax_ids": [

    ],
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [

    ],
    "description": null,
    "discounts": [],
    "due_date": null,
    "effective_at": "1623873347",
    "ending_balance": 0,
    "footer": null,
    "from_invoice": null,
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp",
    "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf",
    "last_finalization_error": null,
    "latest_revision": null,
    "lines": {
      "object": "list",
      "data": [
        {
          "id": "il_1N2CjMBwKQ696a5NeOawRQP2",
          "object": "line_item",
          "amount": 2000,
          "currency": "usd",
          "description": "1 × Gold Special (at $20.00 / month)",
          "discount_amounts": [

          ],
          "discountable": true,
          "discounts": [

          ],
          "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
          "livemode": false,
          "metadata": {
          },
          "parent": {
            "invoice_item_details": null,
            "subscription_item_details":
            {
              "invoice_item": null,
            "proration": false,
            "proration_details":
            {
              "credited_items": null
            },
            "subscription":
            "sub_JgRjFjhKbtD2qz",
            "subscription_item":
              "si_JgRjmS4Ur1khEx"
            },
            "type": "subscription_item_details"
          },
          "period": {
            "end": 1626465347,
            "start": 1623873347
          },
          "plan": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "plan",
            "active": true,
            "amount": 2000,
            "amount_decimal": "2000",
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "price": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "recurring": {
              "interval": "month",
              "interval_count": 1,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 2000,
            "unit_amount_decimal": "2000"
          },
          "quantity": 1,
          "taxes": []
        }
      ],
      "has_more": false,
      "total_count": 1,
      "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines"
    },
    "livemode": false,
    "metadata": {
    },
    "next_payment_attempt": null,
    "number": "C008FC2-0354",
    "on_behalf_of": null,
    "parent": {
      "quote_details": null,
      "subscription_details": {
        "metadata": {},
        "pause_collection": null,
        "subscription": "sub_JgRjFjhKbtD2qz"
      }
    },
    "payment_intent": {
      "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6"
      },
      "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu",
      "confirmation_method": "automatic",
      "created": 1623873347,
      "currency": "usd",
      "customer": "cus_CMqDWO2xODTZqt",
      "description": "Subscription creation",
      "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
      "last_payment_error": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "receipt_email": null,
      "review": null,
      "setup_future_usage": "off_session",
      "shipping": null,
      "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ",
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_confirmation",
      "transfer_data": null,
      "transfer_group": null
    },
    "payment_settings": {
      "payment_method_options": null,
      "payment_method_types": null,
      "save_default_payment_method": "on_subscription"
    },
    "period_end": 1623873347,
    "period_start": 1623873347,
    "post_payment_credit_notes_amount": 0,
    "pre_payment_credit_notes_amount": 0,
    "receipt_number": null,
    "starting_balance": 0,
    "statement_descriptor": null,
    "status": "open",
    "status_transitions": {
      "finalized_at": 1623873347,
      "marked_uncollectible_at": null,
      "paid_at": null,
      "voided_at": null
    },
    "subscription": "sub_JgRjFjhKbtD2qz",
    "subtotal": 2000,
    "tax": null,
    "tax_percent": null,
    "total": 2000,
    "total_discount_amounts": [],
    "total_tax_amounts": [],
    "transfer_data": null,
    "webhooks_delivered_at": 1623873347
  },
  "livemode": false,
  "metadata": {
  },
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "plan": {
    "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
    "object": "plan",
    "active": true,
    "amount": 2000,
    "amount_decimal": "2000",
    "billing_scheme": "per_unit",
    "created": 1623864151,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "nickname": null,
    "product": "prod_JgPF5xnq7qBun3",
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "schedule": null,
  "start": 1623873347,
  "start_date": 1623873347,
  "status": "incomplete",
  "tax_percent": null,
  "transfer_data": null,
  "trial_end": null,
  "trial_start": null
}
```

## Recopila datos de pago [Cliente]

Utiliza [Stripe Elements](https://docs.stripe.com/payments/elements.md) para cobrar los datos de pago y activar la suscripción. Puedes personalizar Elements para que se adapte al aspecto de tu solicitud.

El [Payment Element](https://docs.stripe.com/payments/payment-element.md) admite [Link](https://docs.stripe.com/payments/link.md), tarjetas de crédito, débito directo SEPA y débito directo BECS para suscripciones. Puedes mostrar los métodos de pago habilitados y recopilar de forma segura los datos de pago según la selección de tu cliente.

### Configurar Stripe Elements

El Payment Element se encuentra disponible automáticamente como funcionalidad de Stripe.js. Incluye el script de Stripe.js en tu página de confirmación de compra agregándolo al `head` de tu archivo HTML. Siempre debes cargar Stripe.js directamente desde js.stripe.com para cumplir con la normativa PCI. No incluyas el script en un paquete ni alojes una copia en tus sistemas.

```html
<head>
  <title>Checkout</title>
  <script src="https://js.stripe.com/dahlia/stripe.js"></script>
</head>
<body>
  <!-- content here -->
</body>
```

Crea una instancia de Stripe con el siguiente JavaScript en tu página de pago:

```javascript
// Set your publishable key: remember to change this to your live publishable key in production
// See your keys here: https://dashboard.stripe.com/apikeys
const stripe = Stripe('<<YOUR_PUBLISHABLE_KEY>>');
```

### Agrega el Payment Element a tu página

El Payment Element necesita un lugar donde residir en tu página de pago. Crea un nodo DOM vacío (contenedor) con una ID única en tu formulario de pago.

```html
<form id="payment-form">
  <div id="payment-element">
    <!-- Elements will create form elements here -->
  </div>
  <button id="submit">Subscribe</button>
  <div id="error-message">
    <!-- Display error message to your customers here -->
  </div>
</form>
```

Una vez cargado el formulario, cree una instancia de Payment Element y móntalo en el nodo DOM contenedor. Cuando [creaste la suscripción](https://docs.stripe.com/billing/subscriptions/build-subscriptions.md#create-subscription), pasaste el valor `client_secret` al front-end. Pasa este valor como una opción cuando crees una instancia de Elements.

```javascript
const options = {
  clientSecret: '{{CLIENT_SECRET}}',
  // Fully customizable with appearance API.
  appearance: {/*...*/},
};

// Set up Stripe.js and Elements to use in the payment form, passing the client secret obtained in step 5
const elements = stripe.elements(options);

const paymentElementOptions = {
  layout: "tabs",
};

// Create and mount the Payment Element
const paymentElement = elements.create('payment', paymentElementOptions);
paymentElement.mount('#payment-element');
```

El elemento de pago muestra un formulario dinámico que le permite a tu cliente seleccionar un método de pago. El formulario recopila automáticamente todos los datos de pago necesarios para el método de pago que seleccionen.

#### Configuraciones opcionales del Payment Element

Opcionalmente, puedes hacer lo siguiente:

- Personaliza el Payment Element para que se ajuste al diseño de tu sitio web pasando el [objeto de apariencia](https://docs.stripe.com/js/elements_object/create#stripe_elements-options-appearance) a `opciones` cuando estés por crear una instancia de Elements.
- Configura la interfaz de Apple Pay para que devuelva un [token de comerciante](https://docs.stripe.com/apple-pay/merchant-tokens.md?pay-element=web-pe) para admitir pagos recurrentes, recargas automáticas y pagos aplazados.

### Completar pago

Utiliza `stripe.confirmPayment` para completar el pago utilizando los datos del elemento de pago y activar la suscripción. Esto crea un método de pago, confirma la primera intención de pago de la suscripción incompleta y realiza el cargo. Si se requiere la *autenticación reforzada de clientes (SCA)* (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) (SCA) para el pago, el elemento de pago se encarga del proceso de autenticación antes de confirmar la intención de pago.

Proporciona una dirección [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) para indicar a dónde redirige Stripe al usuario después de completar el pago. Tu usuario podría redirigirse primero a un sitio intermedio, como una página de autorización bancaria, antes de redirigirse a la `return_url`. Los pagos con tarjeta redirigen inmediatamente a la `return_url` cuando el pago se realiza correctamente.

```javascript
const form = document.getElementById('payment-form');

form.addEventListener('submit', async (event) => {
  event.preventDefault();
const {error} = await stripe.confirmPayment({
    //`Elements` instance that was used to create the Payment Element
    elements,
    confirmParams: {
      return_url: "https://example.com/order/123/complete",
    }
  });

  if (error) {
    // This point is reached only if there's an immediate error when
    // confirming the payment. Show an error to your customer (for example, payment
    // details incomplete)
    const messageContainer = document.querySelector('#error-message');
    messageContainer.textContent = error.message;
  } else {
    // Your customer redirects to your `return_url`. For some payment
    // methods, such as iDEAL, your customer redirects to an intermediate
    // site first to authorize the payment, and then redirects to the `return_url`.
  }
});
```

Cuando tu cliente envía un pago, Stripe lo redirige a `return_url` e incluye los siguientes parámetros de consulta de URL. La página de retorno puede usarlos para obtener el estado del PaymentIntent a fin de mostrarle el estado del pago al cliente.

Cuando especificas la `return_url`, también puedes adjuntar tus propios parámetros de consulta para usarlos en la página de retorno.

| Parámetro                      | Descripción                                                                                                                                                                                                                                                                                                                                                                |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `payment_intent`               | El identificador único del `PaymentIntent`.                                                                                                                                                                                                                                                                                                                                |
| `payment_intent_client_secret` | El [secreto de cliente](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) del objeto `PaymentIntent`. Para las integraciones de suscripciones, este client_secret también se expone en el objeto `Invoice` a través de [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) |

Cuando el cliente es redirigido a tu sitio, puedes usar el `payment_intent_client_secret` para consultar el PaymentIntent y mostrarle el estado de la transacción a tu cliente.

> Si tienes herramientas que hacen el seguimiento de la sesión de navegador del cliente, es posible que tengas que agregar el dominio `stripe.com` a la lista de exclusión de referentes. Los redireccionamientos hacen que algunas herramientas creen nuevas sesiones que te impiden hacer el seguimiento de toda la sesión.

Utiliza uno de los parámetros de consulta para recuperar el PaymentIntent. Inspecciona el estado [del PaymentIntent](https://docs.stripe.com/payments/paymentintents/lifecycle.md) para decidir qué mostrar a tus clientes. También puedes añadir tus propios parámetros de consulta al proporcionar la `return_url`, que persisten a través del proceso de redirección.

```javascript
// Initialize Stripe.js using your publishable key
const stripe = Stripe('<<YOUR_PUBLISHABLE_KEY>>');

// Retrieve the "payment_intent_client_secret" query parameter appended to
// your return_url by Stripe.js
const clientSecret = new URLSearchParams(window.location.search).get(
  'payment_intent_client_secret'
);

// Retrieve the PaymentIntent
stripe.retrievePaymentIntent(clientSecret).then(({paymentIntent}) => {
  const message = document.querySelector('#message')

  // Inspect the PaymentIntent `status` to indicate the status of the payment
  // to your customer.
  //
  // Some payment methods [immediately succeed or fail][0] upon
  // confirmation, while others first enter a `processing` status.
  //
  // [0]: https://stripe.com/docs/payments/payment-methods#payment-notification
  switch (paymentIntent.status) {
    case 'succeeded':
      message.innerText = 'Success! Payment received.';
      break;

    case 'processing':
      message.innerText = "Payment processing. We'll update you when payment is received.";
      break;

    case 'requires_payment_method':
      message.innerText = 'Payment failed. Please try another payment method.';
      // Redirect your user back to your payment page to attempt collecting
      // payment again
      break;

    default:
      message.innerText = 'Something went wrong.';
      break;
  }
});
```

## Escucha webhooks [Servidor]

Para completar la integración, tienes que procesar los *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) que envió Stripe. Estos son eventos que se originan cada vez que un estado dentro de Stripe cambia, por ejemplo, cuando las suscripciones crean facturas nuevas. En tu aplicación, configura un controlador de HTTP para aceptar una solicitud POST que contenga el evento de webhook y verifica la firma del evento:

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/webhook' do
  # You can use webhooks to receive information about asynchronous payment events.
  # For more about our webhook events, see https://stripe.com/docs/webhooks.
  webhook_secret = ENV['STRIPE_WEBHOOK_SECRET']
  payload = request.body.read
  if !webhook_secret.empty?
    # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, webhook_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts '⚠️  Webhook signature verification failed.'
      status 400
      return
    end
  else
    data = JSON.parse(payload, symbolize_names: true)
    event = Stripe::Event.construct_from(data)
  end
  # Get the type of webhook event sent - used to check the status of PaymentIntents.
  event_type = event['type']
  data = event['data']
  data_object = data['object']

  if event_type == 'invoice.paid'
    # Used to provision services after the trial has ended.
    # The status of the invoice shows up as paid. Store the status in your
    # database to reference when a user accesses your service to avoid hitting rate
    # limits.
    # puts data_object
  end

  if event_type == 'invoice.payment_failed'
    # If the payment fails or the customer doesn't have a valid payment method,
    # an invoice.payment_failed event is sent and the subscription becomes past_due.
    # Use this webhook to notify your user that their payment has
    # failed and to retrieve new card details.
    # puts data_object
  end

  if event_type == 'customer.subscription.deleted'
    # handle subscription canceled automatically based
    # upon your subscription settings. Or if the user cancels it.
    # puts data_object
  end

  content_type 'application/json'
  { status: 'success' }.to_json
end
```

Durante el desarrollo, utiliza la CLI de Stripe para [observar los webhooks y reenviarlos a tu solicitud](https://docs.stripe.com/webhooks.md#test-webhook). Ejecuta lo siguiente en un terminal nuevo mientras se ejecuta tu aplicación de desarrollo:

#### curl

```bash
  stripe listen --forward-to localhost:4242/webhook
```

Para la producción, configura un punto de conexión webhook en [Workbench](https://docs.stripe.com/workbench.md), o utiliza la API [Webhook Endpoints](https://docs.stripe.com/api/webhook_endpoints.md).

Escucha algunos eventos para completar los pasos restantes de esta guía. Consulta [Eventos de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) y obtén más detalles sobre los webhooks específicos de la suscripción.

## Brindar acceso a tu servicio [Cliente y servidor]

Ahora que la suscripción está activa, dale a tu usuario acceso a tu servicio. Para ello, escucha los eventos `customer.subscription.created`, `customer.subscription.updated`, y `customer.subscription.deleted`. Estos eventos pasan un objeto `Subscription` que contiene un campo `estado` que indica si la suscripción está activa, vencida o cancelada. Consulta [el ciclo de vida de la suscripción](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle) para obtener una lista completa de estados.

En tu controlador de webhook:

1. Verifica el estado de la suscripción. Si es `active`, tu usuario ha pagado por su producto.
1. Revisa el producto al que se suscribió el cliente y bríndale acceso al servicio. Es mejor revisar el producto que el precio porque te da más flexibilidad en caso de que tengas que cambiar el precio o el período de facturación.
1. Almacena el estado `product.id`, `subscription.id` y `subscription.status` en tu base de datos junto con el `customer_account.id` o el `customer.id` que ya guardaste. Consulta este registro cuando tengas que determinar qué funcionalidades habilitar para el usuario en tu aplicación.

El estado de la suscripción puede cambiar en cualquier momento de su ciclo de vida, incluso si tu solicitud no hace ninguna llamada directa a Stripe. Por ejemplo, se puede producir un error de renovación debido a una tarjeta de crédito vencida, lo que genera que el estado de la suscripción pase a `vencido`. O, si usas el [portal de clientes](https://docs.stripe.com/customer-management.md), un usuario puede optar por cancelar la suscripción sin ingresar a tu aplicación directamente. El uso correcto del controlador mantiene el estado de tu solicitud sincronizado con Stripe.

## Cancelación de la suscripción [Cliente y servidor]

Puedes permitir que los clientes cancelen sus suscripciones. El ejemplo siguiente añade una opción de cancelación a la página de configuración de la cuenta.
![Ejemplo de interfaz de cancelación de suscripción](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png)

Configuración de la cuenta con la posibilidad de cancelar la suscripción

```javascript
function cancelSubscription(subscriptionId) {
  return fetch('/cancel-subscription', {
    method: 'post',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
    }),
  })
    .then(response => {
      return response.json();
    })
    .then(cancelSubscriptionResponse => {
      // Display to the user that the subscription has been canceled.
    });
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/cancel-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId'])

  deleted_subscription.to_json
end
```

En tu aplicación, se recibe un evento `customer.subscription.deleted`.

Una vez que se cancela la suscripción, actualiza tu base de datos para eliminar el ID de suscripción de Stripe que estaba almacenado y limitar el acceso al servicio.

Cuando se cancela una suscripción, no se puede reactivar. En su lugar, recopila la información de facturación actualizada de tu cliente, actualiza su método de pago predeterminado y crea una nueva suscripción con tu registro de cliente existente.

## Prueba la integración

### Prueba métodos de pago

Usa la siguiente tabla para probar diferentes métodos y escenarios de pago.

| Método de pago      | Escenario                                                                                                                                                                                                                                                                                       | Cómo hacer la prueba                                                                                                                                                                         |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Débito directo BECS | Tu cliente paga correctamente con débito directo BECS.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `900123456` y BSB `000000`. El PaymentIntent confirmado pasa en un principio al estado `processing` y, tres minutos más tarde, a `succeeded`. |
| Débito directo BECS | El pago de tu cliente falla con un código de error `account_closed`.                                                                                                                                                                                                                            | Completa el formulario con el número de cuenta `111111113` y BSB `000000`.                                                                                                                   |
| Tarjeta de crédito  | El pago con tarjeta se efectúa correctamente y no requiere autenticación.                                                                                                                                                                                                                       | Completa el formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | El pago con tarjeta 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). | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | La tarjeta es rechazada con el código `insufficient_funds`.                                                                                                                                                                                                                                     | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Débito directo SEPA | Tu cliente paga correctamente con débito directo SEPA.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `AT321904300235473204`. El PaymentIntent confirmado pasa inicialmente al estado “en proceso” y, tres minutos más tarde, a “completado”.       |
| Débito directo SEPA | El estado de PaymentIntent de tu cliente pasa de `processing` a `requires_payment_method`.                                                                                                                                                                                                      | Completa el formulario con el número de cuenta `AT861904300235473202`.                                                                                                                       |

### Supervisa los acontecimientos

Configura webhooks para escuchar los eventos de cambio de suscripción, como actualizaciones y cancelaciones. Más información sobre [webhooks de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md). Puedes ver los eventos en el [Dashboard](https://dashboard.stripe.com/test/events) o con [Stripe CLI](https://docs.stripe.com/webhooks.md#test-webhook).

Para más detalles, consulta [Comprobación de la integración con Billing](https://docs.stripe.com/billing/testing.md).

## Optional: Permitir que los clientes cambien de plan [Cliente y servidor]

Para permitir que tus clientes cambien su suscripción, recopila el ID de precio de la opción a la que desean cambiar. A continuación, envía el nuevo ID de precio desde el front-end a un punto final del back-end. El ejemplo siguiente también pasa el ID de suscripción, pero puedes recuperarlo de tu base de datos para el usuario que ha iniciado sesión.

```javascript
function updateSubscription(priceId, subscriptionId) {
  return fetch('/update-subscription', {
    method: 'post',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
      newPriceId: priceId,
    }),
  })
    .then(response => {
      return response.json();
    })
    .then(response => {
      return response;
    });
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada especificando el ID de suscripción y el nuevo ID de precio. La suscripción ahora es una suscripción Premium que cuesta USD 15 por mes en lugar de una suscripción básica de USD 5 por mes.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/update-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  updated_subscription =
    client.v1.subscriptions.update(
      data['subscriptionId'],
      cancel_at_period_end: false,
      items: [
        { id: subscription.items.data[0].id, price: data['newPriceId'] }
      ]
    )

  updated_subscription.to_json
end
```

En tu aplicación, se recibe un evento `customer.subscription.updated`.

## Optional: Previsualizar un cambio de precio [Cliente y servidor]

Cuando tu cliente cambia de suscripción, a menudo se produce un ajuste del importe que debe, conocido como [prorrateo](https://docs.stripe.com/billing/subscriptions/prorations.md). Puedes utilizar el [punto de conexión de creación de factura preliminar](https://docs.stripe.com/api/invoices/create_preview.md) para mostrar el importe ajustado a tus clientes.

En el front-end, pasa los detalles de `create preview invoice` a un punto de conexión de back-end.

#### Accounts&nbsp;v2

```javascript
function createPreviewInvoice(
  customerAccountId,
  subscriptionId,
  newPriceId,
  trialEndDate
) {
  return fetch('/create-preview-invoice', {
    method: 'post',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({
      customerAccountId: customerAccountId,
      subscriptionId: subscriptionId,
      newPriceId: newPriceId,
    }),
  })
    .then(response => {
      return response.json();
    })
    .then((invoice) => {
      return invoice;
    });
}
```

#### Customers&nbsp;v1

```javascript
function createPreviewInvoice(
  customerId,
  subscriptionId,
  newPriceId,
  trialEndDate
) {
  return fetch('/create-preview-invoice', {
    method: 'post',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({
      customerId: customerId,
      subscriptionId: subscriptionId,
      newPriceId: newPriceId,
    }),
  })
    .then(response => {
      return response.json();
    })
    .then((invoice) => {
      return invoice;
    });
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Accounts&nbsp;v2

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = Stripe::Subscription.retrieve(data['subscriptionId'])

  invoice =
    Stripe::Invoice.create_preview(
      customer_account: data['customerAccountId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

#### Customers&nbsp;v1

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  invoice =
    client.v1.invoices.create_preview(
      customer: data['customerId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

## Optional: Mostrar el método de pago del cliente [Cliente y servidor]

Mostrar la marca y los últimos 4 dígitos de la tarjeta le permite saber al cliente qué tarjeta se está utilizando o si es necesario actualizar el método de pago.

En el front end, envía el identificador del método de pago a un punto de conexión que recupere los detalles del método de pago.

```javascript
function retrieveCustomerPaymentMethod(paymentMethodId) {
  return fetch('/retrieve-customer-payment-method', {
    method: 'post',
    headers: {
      'Content-type': 'application/json',
    },
    body: JSON.stringify({
      paymentMethodId: paymentMethodId,
    }),
  })
    .then((response) => {
      return response.json();
    })
    .then((response) => {
      return response;
    });
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/retrieve-customer-payment-method' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId'])

  payment_method.to_json
end
```

Ejemplo de respuesta:

```json
{
  "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42",
  "object": "payment_method",
  "billing_details": {
    "address": {
      "city": null,
      "country": null,
      "line1": null,
      "line2": null,
      "postal_code": null,
      "state": null
    },
    "email": null,
    "name": null,
    "phone": null
  },
  "card": {
    "brand": "visa",
    "checks": {
      "address_line1_check": null,
      "address_postal_code_check": null,
      "cvc_check": "pass"
    },
    "country": "US",
    "exp_month": 8,
    "exp_year": 2021,
    "fingerprint": "Xt5EWLLDS7FJjR1c",
    "funding": "credit",
    "generated_from": null,
    "last4": "4242",
    "three_d_secure_usage": {
      "supported": true
    },
    "wallet": null
  },
  "created": 1588010536,
  "customer": "cus_HAxB7dVQxhoKLh",
  "livemode": false,
  "metadata": {},
  "type": "card"
}
```

> Te recomendamos guardar `paymentMethod.id` y `last4` en tu base de datos, por ejemplo, `paymentMethod.id` como `stripeCustomerPaymentMethodId` en tu colección o tabla de `users`. Si lo necesitas, también tienes la opción de guardar `exp_month`, `exp_year`, `fingerprint` y `billing_details`. Esto sirve para limitar el número de llamadas a Stripe, mejorar el rendimiento y evitar una posible limitación de la frecuencia.

## Cuéntales a tus clientes qué es Stripe

Stripe recopila información sobre las interacciones de los clientes con Elements para proporcionarte servicios, mejorarlos y prevenir el fraude. Esto incluye el uso de cookies y direcciones IP para identificar qué Elements vio un cliente durante una sola sesión de finalización de compra. Tienes la responsabilidad de divulgar y obtener todos los derechos y consentimientos necesarios para que Stripe use los datos para dichos fines. Si deseas obtener más información, visita nuestro [centro de privacidad](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe).

#### Móvil

#### iOS

Aprende a vender *subscriptions* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) de precio fijo. Usarás [Payment Element para dispositivos móviles](https://docs.stripe.com/payments/accept-a-payment.md) para crear un formulario de pago personalizado que puedes integrar en tu aplicación.
![Página de suscripción de precio fijo con Payment Element móvil](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png)

> Si vendes productos o servicios digitales que se consumen dentro de tu aplicación (por ejemplo, suscripciones, monedas de juegos, niveles de juegos, acceso a contenido prémium o desbloqueo de una versión completa), debes usar las API de compra desde la aplicación de Apple. Esta regla tiene algunas excepciones, como los servicios personales uno a uno y las [aplicaciones basadas en regiones específicas](https://support.stripe.com/questions/changes-to-mobile-app-store-rules). Consulta las [pautas de revisión de la App Store](https://developer.apple.com/app-store/review/guidelines/#payments) para obtener más información.

## Crear tu suscripción

Esta guía te explica cómo:

- Modelar tu empresa creando un catálogo de productos.
- Crear un proceso de registro para agregar clientes.
- Crear suscripciones y recopilar información de pago.
- Comprueba y supervisa el estado de los pagos y las suscripciones.
- Permitir que los clientes cambien de plan o cancelen la suscripción.
- Aprenda a usar el [modo facturación flexible](https://docs.stripe.com/billing/subscriptions/billing-mode.md) para acceder a un comportamiento de facturación mejorado y funcionalidades adicionales.

## Cómo modelar la suscripción en Stripe

Las [suscripciones](https://docs.stripe.com/api/subscriptions.md) simplifican la facturación, ya que crean de forma automática *facturas* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice) y [PaymentIntents](https://docs.stripe.com/api/payment_intents.md). Para crear y activar una suscripción, primero debes crear un *producto* (Products represent what your business sells—whether that's a good or a service) para modelar lo que se vende y un *precio* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) que determine el intervalo y el importe para aceptar pagos. También necesitas un objeto `Account` configurado por el cliente o un objeto `Customer` para almacenar los *PaymentMethods* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) utilizados para realizar cada pago recurrente.

#### Accounts&nbsp;v2
Diagrama que muestra objetos de facturación comunes y sus relaciones (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions)
#### Customer v1
Diagrama que muestra objetos de facturación comunes y sus relaciones (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions)
### Definiciones de los objetos de la API

| Recurso                                                                                                                                | Definición                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Cuenta configurada como un cliente](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | Representa a un cliente en la API Accounts v2 que compra una suscripción. Configura un objeto `Cuenta` como cliente y asócialo a una suscripción para realizar cargos recurrentes y hacerles un seguimiento, y para gestionar los productos a los que se suscribe. Consulta nuestra [guía Usar cuentas como clientes](https://docs.stripe.com/connect/use-accounts-as-customers.md) para obtener más información.                                 |
| [Customer](https://docs.stripe.com/api/customers.md)                                                                                   | Representa a un cliente en la API Clientes que compra una suscripción. Usa el objeto `Cliente` asociado a una suscripción para realizar y hacer seguimiento de los cargos recurrentes y administrar los productos a los que se suscriben.                                                                                                                                                                                                         |
| [Derecho](https://docs.stripe.com/api/entitlements/active-entitlement.md)                                                              | Representa el acceso de un cliente a una funcionalidad incluida en un producto de servicio al que está suscrito. Cuando creas una suscripción para la compra recurrente de un producto por parte de un cliente, se crea automáticamente un derecho activo para cada funcionalidad asociada a ese producto. Cuando un cliente accede a tus servicios, utiliza sus derechos activos para habilitar las funcionalidades incluidas en su suscripción. |
| [Funcionalidad](https://docs.stripe.com/api/entitlements/feature.md)                                                                   | Representa una funcionalidad o capacidad a la que tus clientes pueden acceder cuando se suscriben a un producto de servicio. Puedes incluir funciones en un producto creando ProductFeatures.                                                                                                                                                                                                                                                     |
| [Factura](https://docs.stripe.com/api/invoices.md)                                                                                     | Una declaración de importes que un cliente adeuda y que rastrea los estados de pago desde el borrador hasta su pago o su finalización. Las suscripciones generan facturas automáticamente.                                                                                                                                                                                                                                                        |
| [PaymentIntent](https://docs.stripe.com/api/payment_intents.md)                                                                        | Una forma de crear flujos de pago dinámicos. Un PaymentIntent hace un seguimiento del ciclo de vida del flujo del proceso compra del cliente y activa pasos adicionales de autenticación, si así lo exigen las disposiciones normativas, las reglas antifraude personalizadas de Radar o los métodos de pago con redireccionamiento. Las facturas crean PaymentIntents de forma automática.                                                       |
| [PaymentMethod](https://docs.stripe.com/api/payment_methods.md)                                                                        | Los métodos de pago que usa un cliente para pagar tus productos. Por ejemplo, puedes guardar una tarjeta de crédito en un objeto `Cuenta` o `Cliente` configurado por el cliente y usarla para hacer pagos recurrentes para ese cliente. Por lo general, se usa con las API Payment Intents o Setup Intents.                                                                                                                                      |
| [Precio](https://docs.stripe.com/api/prices.md)                                                                                        | Define el precio por unidad, la moneda y el ciclo de facturación para un producto.                                                                                                                                                                                                                                                                                                                                                                |
| [Producto](https://docs.stripe.com/api/products.md)                                                                                    | Un bien o servicio que vende tu empresa. Un producto de servicio puede incluir una o más funciones.                                                                                                                                                                                                                                                                                                                                               |
| [ProductFeature](https://docs.stripe.com/api/product-feature.md)                                                                       | Representa la inclusión de una sola funcionalidades en un solo producto. Cada producto está asociado a una ProductFeature para cada funcionalidad que incluye, y cada funcionalidad está asociada a una ProductFeature para cada producto que la incluye.                                                                                                                                                                                         |
| [Suscripción](https://docs.stripe.com/api/subscriptions.md)                                                                            | Representa la compra recurrente programada de un producto por parte de un cliente. Usa una suscripción para cobrar pagos y proporcionar entrega repetida o acceso continuo a un producto.                                                                                                                                                                                                                                                         |

Veamos un ejemplo de cómo funcionan juntos los productos, las funcionalidades y los derechos. Imagina que quieres configurar un servicio recurrente que ofrezca dos niveles: un producto estándar con funcionalidad básica y un producto avanzado que agregue funcionalidad extendida.

1. Creas dos funcionalidades: `basic_features` y `extended_features`.
1. Creas dos productos: `standard_product` y `advanced_product`.
1. Para el producto estándar, creas una ProductFeature que asocia `basic_features` con `standard_product`.
1. Para el producto avanzado, creas dos ProductFeatures: una que asocia `basic_features` con `advanced_product` y otra que asocia `extended_features` con `advanced_product`.

Un cliente, `first_customer`, se suscribe al producto estándar. Cuando creas la suscripción, Stripe crea automáticamente un derecho que asocia `first_customer` con `basic_features`.

Otro cliente, `second_customer`, se suscribe al producto avanzado. Al crear la suscripción, Stripe crea automáticamente dos derechos: uno que asocia `second_customer` con `basic_features` y otro que asocia `second_customer` con `extended_features`.

Puedes determinar qué funcionalidades aprovisionar para un cliente [recuperando sus derechos activos o recibiendo notificaciones del evento Resumen de derechos activos](https://docs.stripe.com/billing/entitlements.md#entitlements). No tienes que recuperar sus suscripciones, productos y funcionalidades.

## Configura Stripe

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.

#### Swift Package Manager

Para instalar el SDK, sigue estos pasos:

1. En Xcode, selecciona **Archivo** > **Agregar dependencias de paquetes…** e introduce `https://github.com/stripe/stripe-ios-spm` como 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. Agrega 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), crea uno al ejecutar el siguiente comando:
   ```bash
   pod init
   ```
1. Agrega 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. Agrega 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
   ```

#### Framework 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 [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 de nuestro SDK, repite los pasos 1 a 3.

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

Configura el SDK con tu [clave publicable](https://dashboard.stripe.com/test/apikeys) de Stripe al iniciar la aplicación. Esto permite que tu aplicación haga solicitudes a la API de Stripe.

#### Swift

```swift
import UIKitimportStripePaymentSheet

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

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

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

A continuación, instala la CLI de Stripe. La CLI proporciona pruebas de webhook y puedes ejecutarla para realizar llamadas API a Stripe. Esta guía muestra cómo utilizar la CLI para configurar un modelo de precios en una sección posterior.
Para obtener más opciones de instalación, consulta [Empezar a usar la CLI de Stripe](https://docs.stripe.com/stripe-cli.md).
## Crear el modelo de tarifas [CLI o Dashboard de Stripe]

Los [modelos de precios recurrentes](https://docs.stripe.com/products-prices/pricing-models.md) representan los productos o servicios que vendes, cuánto cuestan, qué monedas aceptas para los pagos y el período de servicio para las suscripciones. Para crear el modelo de precios, crea [productos](https://docs.stripe.com/api/products.md) (lo que vendes) y [precios](https://docs.stripe.com/api/prices.md) (cuánto cuestan y con qué frecuencia cobrar por los productos).

En este ejemplo, se utiliza una tarifa con tasa fija con dos opciones de niveles de servicio diferentes: básico y premium. Para cada opción de nivel de servicio, debes crear un producto y un precio recurrente. Si quieres agregar un cargo por única vez, como el costo de instalación, crea un tercer producto con un precio por única vez.

Cada producto se factura de forma mensual. El precio del producto básico es de 5 USD. El precio del producto premium es de 15 USD. Consulta la guía de [tarifas con tasa fija](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md) para ver un ejemplo con tres niveles.

#### Dashboard

Ve a la página [Agregar un producto](https://dashboard.stripe.com/test/products/create) y crea dos productos. Agrega un precio a cada producto, cada uno con un período de facturación mensual recurrente:

- Producto prémium: servicio prémium con más funcionalidades

  - Precio: Tarifa plana | 15 USD

- Producto básico: servicio básico con las funcionalidades mínimas

  - Precio: Tarifa plana | 5 USD

Después de crear los precios, registra los ID de precio para usarlos en otros pasos. Los ID de precio se ven así: `price_G0FvDp6vZvdwRZ`.

Cuando esté todo listo, usa el botón **Copiar en modo activo**, en la parte superior derecha de la página, para clonar el producto y pasarlo de [entorno de prueba a modo activo](https://docs.stripe.com/keys.md#test-live-modes).

#### API

Puedes usar la API para crear los [productos](https://docs.stripe.com/api/products.md) y los [precios](https://docs.stripe.com/api/prices.md).

Crear el producto premium:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

Crear el producto básico:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Basic Service" \
  -d "description=Basic service with minimum features"
```

Registra el ID de cada producto. Se ve así:

```json
{
  "id": "prod_H94k5odtwJXMtQ",
  "object": "product",
  "active": true,
  "attributes": [

  ],
  "created": 1587577341,
  "description": "Premium service with extra features",
  "images": [

  ],
  "livemode": false,
  "metadata": {
  },
  "name": "Billing Guide: Premium Service",
  "statement_descriptor": null,
  "type": "service",
  "unit_label": null,
  "updated": 1587577341
}
```

Usa los ID de producto para crear el precio de cada producto. El número [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) está en centavos. Por ejemplo, `1500` = 15 USD.

Crear el precio superior:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{PREMIUM_PRODUCT_ID}} \
  -d unit_amount=1500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Crear el precio básico:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{BASIC_PRODUCT_ID}} \
  -d unit_amount=500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Registra el ID de cada precio para poder utilizarlo en los pasos siguientes. Se ve así:

```json
{
  "id": "price_HGd7M3DV3IMXkC",
  "object": "price",
  "product": "prod_HGd6W1VUqqXGvr",
  "type": "recurring",
  "currency": "usd",
  "recurring": {
    "interval": "month",
    "interval_count": 1,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "active": true,
  "billing_scheme": "per_unit",
  "created": 1589319695,
  "livemode": false,
  "lookup_key": null,
  "metadata": {},
  "nickname": null,
  "unit_amount": 1500,
  "unit_amount_decimal": "1500",
  "tiers": null,
  "tiers_mode": null,
  "transform_quantity": null
}
```

## Crear el cliente [Cliente y servidor]

Stripe necesita un cliente para cada suscripción. En el front-end de tu solicitud, recopila toda la información necesaria de tus usuarios y envíala al back-end.

Si necesitas recopilar datos de la dirección, el Address Element te permite recopilar una dirección de envío o facturación para tus clientes. Para obtener más información sobre el Address Element, visita la página de [Address Element](https://docs.stripe.com/elements/address-element.md).

```swift
struct RegisterView: View {
    @State var email = ""
    var body: some View {
        VStack {
            TextField(text: $email) {
                Text("Email")
            }
            Button {
                Task {
                    var request = URLRequest(url: URL(string: "http://localhost:4242/create-customer")!)
                    request.httpMethod = "POST"
                    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
                    request.httpBody = try! JSONEncoder().encode(["email": email])
                    let (data, _) = try! await URLSession.shared.data(for: request)
                    let responseJSON = try! JSONSerialization.jsonObject(with: data) as! [String: Any]
                    // Return the customer ID here
                    print(responseJSON["customer"])
                }
            } label: {
                Text("Submit")
            }
        }
    }
}
```

Crea el “Customer Object” de Stripe en el servidor.

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

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.preview" \
  --json '{
    "contact_email": "jenny.rosen@example.com",
    "display_name": "Jenny Rosen",
    "identity": {
        "individual": {
            "given_name": "Jenny Rosen",
            "address": {
                "city": "San Francisco",
                "country": "US",
                "line1": "123 Main Street",
                "postal_code": "94605",
                "state": "CA"
            }
        }
    },
    "configuration": {
        "customer": {
            "capabilities": {
                "automatic_indirect_tax": {
                    "requested": true
                }
            },
            "shipping": {
                "address": {
                    "city": "San Francisco",
                    "country": "US",
                    "line1": "123 Main Street",
                    "postal_code": "94605",
                    "state": "CA"
                }
            }
        }
    },
    "include": [
        "configuration.customer",
        "identity"
    ]
  }'
```

#### Customers v1

```curl
curl https://api.stripe.com/v1/customers \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "email=jenny.rosen@example.com" \
  -d "name=Jenny Rosen" \
  -d "shipping[address][city]=San Francisco" \
  -d "shipping[address][country]=US" \
  -d "shipping[address][line1]=123 Main Street" \
  -d "shipping[address][postal_code]=9460" \
  -d "shipping[address][state]=CA" \
  -d "shipping[name]=Jenny Rosen" \
  -d "address[city]=San Francisco" \
  -d "address[country]=US" \
  -d "address[line1]=123 Main Street" \
  -d "address[postal_code]=9460" \
  -d "address[state]=CA"
```

## Crear la suscripción [Cliente y servidor]

> Si quieres procesar el Payment Element antes de crear una suscripción, consulta [Recopilar los datos de pago antes de crear un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription).

Permite que tu nuevo cliente elija un plan y luego cree la suscripción. En esta guía, elegirá entre un plan Básico y un plan Prémium.

En tu aplicación, envía el ID de precio seleccionado y el ID del registro del cliente al back-end.

#### Accounts&nbsp;v2

```swift
func createSubscription(priceId: String, customerAccountId: String) async -> SubscriptionsResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/create-subscription")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["customerAccountId": customerAccountId, "priceId": priceId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // SubscriptionsResponse is a Decodable struct conforming to the expected response from your backend.
    // It should include the client_secret, as discussed below.
    let subscriptionsResponse = try! JSONDecoder().decode(SubscriptionsResponse.self, from: responseData)
    return subscriptionsResponse
}
```

#### Customers&nbsp;v1

```swift
func createSubscription(priceId: String, customerId: String) async -> SubscriptionsResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/create-subscription")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["customerId": customerId, "priceId": priceId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // SubscriptionsResponse is a Decodable struct conforming to the expected response from your backend.
    // It should include the client_secret, as discussed below.
    let subscriptionsResponse = try! JSONDecoder().decode(SubscriptionsResponse.self, from: responseData)
    return subscriptionsResponse
}
```

En el back-end, crea una suscripción con estado `incomplete` usando `payment_behavior=default_incomplete`. Luego, devuelve el `client_secret` desde el primer [payment intent](https://docs.stripe.com/payments/payment-intents.md) de la suscripción al front-end para completar el pago expandiendo el [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) en la factura más reciente de la suscripción.

Para habilitar el [comportamiento de suscripción mejorado](https://docs.stripe.com/billing/subscriptions/billing-mode.md), establece `billing_mode[type]` en `flexible`. Debes utilizar la versión de la API de Stripe [2025-06-30.basil](https://docs.stripe.com/changelog/basil.md#2025-06-30.basil) o posterior.

Establece [save_default_payment_method](https://docs.stripe.com/api/subscriptions/object.md#subscription_object-payment_settings-save_default_payment_method) en `on_subscription` para guardar el método de pago como predeterminado para una suscripción cuando un pago se realiza correctamente. Guardar un método de pago predeterminado aumenta la tasa de éxito de futuros pagos de suscripción.

En el siguiente ejemplo, se crea una `Subscription` y se expande el `confirmation_secret` de su última factura en la respuesta. Esto te permite pasar el secreto al front-end para confirmar el pago.

#### Accounts&nbsp;v2

```curl
curl https://api.stripe.com/v1/subscriptions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d "items[0][price]={{PRICE_ID}}" \
  -d payment_behavior=default_incomplete \
  -d "payment_settings[save_default_payment_method]=on_subscription" \
  -d "billing_mode[type]=flexible" \
  -d "expand[0]=latest_invoice.confirmation_secret"
```

#### Customers&nbsp;v1

```curl
curl https://api.stripe.com/v1/subscriptions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d "items[0][price]={{PRICE_ID}}" \
  -d payment_behavior=default_incomplete \
  -d "payment_settings[save_default_payment_method]=on_subscription" \
  -d "billing_mode[type]=flexible" \
  -d "expand[0]=latest_invoice.confirmation_secret"
```

> Si usas un *precio en múltiples monedas* (A single Price object can support multiple currencies. Each purchase uses one of the supported currencies for the Price, depending on how you use the Price in your integration), usa el parámetro [currency](https://docs.stripe.com/api/subscriptions/create.md#create_subscription-currency) para indicarle a la suscripción cuál de las monedas del precio debe usar. (Si omites el parámetro `currency`, la suscripción utilizará la moneda predeterminada del precio).

La suscripción ahora está `inactiva` y a la espera de pago. El ejemplo de respuesta que figura a continuación destaca los campos mínimos que deben almacenarse, pero puedes almacenar los campos a los que tu solicitud accede con frecuencia.

#### Accounts&nbsp;v2

```json
{"id": "sub_JgRjFjhKbtD2qz",
  "object": "subscription",
  "application_fee_percent": null,
  "automatic_tax": {
    "disabled_reason": null,
    "enabled": false,
    "liability": "null"
  },
  "billing_cycle_anchor": 1623873347,
  "billing_cycle_anchor_config": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "cancellation_details": {
    "comment": null,
    "feedback": null,
    "reason": null
  },
  "collection_method": "charge_automatically",
  "created": 1623873347,
  "currency": "usd","customer_account": identifier("customerAccount"),
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [

  ],
  "discounts": [],
  "ended_at": null,
  "invoice_customer_balance_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_JgRjmS4Ur1khEx",
        "object": "subscription_item",
        "created": 1623873347,"current_period_end": 1626465347,
        "current_period_start": 1623873347,
        "discounts": [],
        "metadata": {
        },
        "plan": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "plan",
          "active": true,
          "amount": 2000,
          "amount_decimal": "2000",
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "price": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 2000,
          "unit_amount_decimal": "2000"
        },
        "quantity": 1,
        "subscription": "sub_JgRjFjhKbtD2qz",
        "tax_rates": [

        ]
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz"
  },
  "latest_invoice": {
    "id": "in_1J34pzGPZ1iASj5zB87qdBNZ",
    "object": "invoice",
    "account_country": "US",
    "account_name": "Angelina's Store",
    "account_tax_ids": null,
    "amount_due": 2000,
    "amount_overpaid": 0,
    "amount_paid": 0,
    "amount_remaining": 2000,
    "amount_shipping": 0,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "disabled_reason": null,
      "enabled": false,
      "liability": null,
      "status": null
    },
    "automatically_finalizes_at": null,
    "billing_reason": "subscription_update",
    "collection_method": "charge_automatically",
    "created": 1623873347,
    "currency": "usd",
    "custom_fields": null,
    "customer_account": identifier("customerAccount"),
    "customer_address": null,
    "customer_email": "angelina@stripe.com",
    "customer_name": null,
    "customer_phone": null,
    "customer_shipping": {
      "address": {
        "city": "",
        "country": "US",
        "line1": "Berry",
        "line2": "",
        "postal_code": "",
        "state": ""
      },
      "name": "",
      "phone": null
    },
    "customer_tax_exempt": "none",
    "customer_tax_ids": [

    ],
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [

    ],
    "description": null,
    "discounts": [],
    "due_date": null,
    "effective_at": "1623873347",
    "ending_balance": 0,
    "footer": null,
    "from_invoice": null,
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp",
    "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf",
    "last_finalization_error": null,
    "latest_revision": null,
    "lines": {
      "object": "list",
      "data": [
        {
          "id": "il_1N2CjMBwKQ696a5NeOawRQP2",
          "object": "line_item",
          "amount": 2000,
          "currency": "usd",
          "description": "1 × Gold Special (at $20.00 / month)",
          "discount_amounts": [

          ],
          "discountable": true,
          "discounts": [

          ],
          "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
          "livemode": false,
          "metadata": {
          },
          "parent": {
            "invoice_item_details": null,
            "subscription_item_details":
            {
              "invoice_item": null,
            "proration": false,
            "proration_details":
            {
              "credited_items": null
            },
            "subscription":
            "sub_JgRjFjhKbtD2qz",
            "subscription_item":
              "si_JgRjmS4Ur1khEx"
            },
            "type": "subscription_item_details"
          },
          "period": {
            "end": 1626465347,
            "start": 1623873347
          },
          "plan": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "plan",
            "active": true,
            "amount": 2000,
            "amount_decimal": "2000",
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "price": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "recurring": {
              "interval": "month",
              "interval_count": 1,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 2000,
            "unit_amount_decimal": "2000"
          },
          "quantity": 1,
          "taxes": []
        }
      ],
      "has_more": false,
      "total_count": 1,
      "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines"
    },
    "livemode": false,
    "metadata": {
    },
    "next_payment_attempt": null,
    "number": "C008FC2-0354",
    "on_behalf_of": null,
    "parent": {
      "quote_details": null,
      "subscription_details": {
        "metadata": {},
        "pause_collection": null,
        "subscription": "sub_JgRjFjhKbtD2qz"
      }
    },
    "payment_intent": {
      "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6"
      },
      "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu",
      "confirmation_method": "automatic",
      "created": 1623873347,
      "currency": "usd",
      "customer": "cus_CMqDWO2xODTZqt",
      "description": "Subscription creation",
      "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
      "last_payment_error": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "receipt_email": null,
      "review": null,
      "setup_future_usage": "off_session",
      "shipping": null,
      "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ",
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_confirmation",
      "transfer_data": null,
      "transfer_group": null
    },
    "payment_settings": {
      "payment_method_options": null,
      "payment_method_types": null,
      "save_default_payment_method": "on_subscription"
    },
    "period_end": 1623873347,
    "period_start": 1623873347,
    "post_payment_credit_notes_amount": 0,
    "pre_payment_credit_notes_amount": 0,
    "receipt_number": null,
    "starting_balance": 0,
    "statement_descriptor": null,
    "status": "open",
    "status_transitions": {
      "finalized_at": 1623873347,
      "marked_uncollectible_at": null,
      "paid_at": null,
      "voided_at": null
    },
    "subscription": "sub_JgRjFjhKbtD2qz",
    "subtotal": 2000,
    "tax": null,
    "tax_percent": null,
    "total": 2000,
    "total_discount_amounts": [],
    "total_tax_amounts": [],
    "transfer_data": null,
    "webhooks_delivered_at": 1623873347
  },
  "livemode": false,
  "metadata": {
  },
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "plan": {
    "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
    "object": "plan",
    "active": true,
    "amount": 2000,
    "amount_decimal": "2000",
    "billing_scheme": "per_unit",
    "created": 1623864151,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "nickname": null,
    "product": "prod_JgPF5xnq7qBun3",
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "schedule": null,
  "start": 1623873347,
  "start_date": 1623873347,
  "status": "incomplete",
  "tax_percent": null,
  "transfer_data": null,
  "trial_end": null,
  "trial_start": null
}
```

#### Customers&nbsp;v1

```json
{"id": "sub_JgRjFjhKbtD2qz",
  "object": "subscription",
  "application_fee_percent": null,
  "automatic_tax": {
    "disabled_reason": null,
    "enabled": false,
    "liability": "null"
  },
  "billing_cycle_anchor": 1623873347,
  "billing_cycle_anchor_config": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "cancellation_details": {
    "comment": null,
    "feedback": null,
    "reason": null
  },
  "collection_method": "charge_automatically",
  "created": 1623873347,
  "currency": "usd","customer": identifier("customer"),
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [

  ],
  "discounts": [],
  "ended_at": null,
  "invoice_customer_balance_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_JgRjmS4Ur1khEx",
        "object": "subscription_item",
        "created": 1623873347,"current_period_end": 1626465347,
        "current_period_start": 1623873347,
        "discounts": [],
        "metadata": {
        },
        "plan": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "plan",
          "active": true,
          "amount": 2000,
          "amount_decimal": "2000",
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "price": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 2000,
          "unit_amount_decimal": "2000"
        },
        "quantity": 1,
        "subscription": "sub_JgRjFjhKbtD2qz",
        "tax_rates": [

        ]
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz"
  },
  "latest_invoice": {
    "id": "in_1J34pzGPZ1iASj5zB87qdBNZ",
    "object": "invoice",
    "account_country": "US",
    "account_name": "Angelina's Store",
    "account_tax_ids": null,
    "amount_due": 2000,
    "amount_overpaid": 0,
    "amount_paid": 0,
    "amount_remaining": 2000,
    "amount_shipping": 0,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "disabled_reason": null,
      "enabled": false,
      "liability": null,
      "status": null
    },
    "automatically_finalizes_at": null,
    "billing_reason": "subscription_update",
    "collection_method": "charge_automatically",
    "created": 1623873347,
    "currency": "usd",
    "custom_fields": null,
    "customer": identifier("customer"),
    "customer_address": null,
    "customer_email": "angelina@stripe.com",
    "customer_name": null,
    "customer_phone": null,
    "customer_shipping": {
      "address": {
        "city": "",
        "country": "US",
        "line1": "Berry",
        "line2": "",
        "postal_code": "",
        "state": ""
      },
      "name": "",
      "phone": null
    },
    "customer_tax_exempt": "none",
    "customer_tax_ids": [

    ],
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [

    ],
    "description": null,
    "discounts": [],
    "due_date": null,
    "effective_at": "1623873347",
    "ending_balance": 0,
    "footer": null,
    "from_invoice": null,
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp",
    "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf",
    "last_finalization_error": null,
    "latest_revision": null,
    "lines": {
      "object": "list",
      "data": [
        {
          "id": "il_1N2CjMBwKQ696a5NeOawRQP2",
          "object": "line_item",
          "amount": 2000,
          "currency": "usd",
          "description": "1 × Gold Special (at $20.00 / month)",
          "discount_amounts": [

          ],
          "discountable": true,
          "discounts": [

          ],
          "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
          "livemode": false,
          "metadata": {
          },
          "parent": {
            "invoice_item_details": null,
            "subscription_item_details":
            {
              "invoice_item": null,
            "proration": false,
            "proration_details":
            {
              "credited_items": null
            },
            "subscription":
            "sub_JgRjFjhKbtD2qz",
            "subscription_item":
              "si_JgRjmS4Ur1khEx"
            },
            "type": "subscription_item_details"
          },
          "period": {
            "end": 1626465347,
            "start": 1623873347
          },
          "plan": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "plan",
            "active": true,
            "amount": 2000,
            "amount_decimal": "2000",
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "price": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "recurring": {
              "interval": "month",
              "interval_count": 1,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 2000,
            "unit_amount_decimal": "2000"
          },
          "quantity": 1,
          "taxes": []
        }
      ],
      "has_more": false,
      "total_count": 1,
      "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines"
    },
    "livemode": false,
    "metadata": {
    },
    "next_payment_attempt": null,
    "number": "C008FC2-0354",
    "on_behalf_of": null,
    "parent": {
      "quote_details": null,
      "subscription_details": {
        "metadata": {},
        "pause_collection": null,
        "subscription": "sub_JgRjFjhKbtD2qz"
      }
    },
    "payment_intent": {
      "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6"
      },
      "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu",
      "confirmation_method": "automatic",
      "created": 1623873347,
      "currency": "usd",
      "customer": "cus_CMqDWO2xODTZqt",
      "description": "Subscription creation",
      "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
      "last_payment_error": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "receipt_email": null,
      "review": null,
      "setup_future_usage": "off_session",
      "shipping": null,
      "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ",
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_confirmation",
      "transfer_data": null,
      "transfer_group": null
    },
    "payment_settings": {
      "payment_method_options": null,
      "payment_method_types": null,
      "save_default_payment_method": "on_subscription"
    },
    "period_end": 1623873347,
    "period_start": 1623873347,
    "post_payment_credit_notes_amount": 0,
    "pre_payment_credit_notes_amount": 0,
    "receipt_number": null,
    "starting_balance": 0,
    "statement_descriptor": null,
    "status": "open",
    "status_transitions": {
      "finalized_at": 1623873347,
      "marked_uncollectible_at": null,
      "paid_at": null,
      "voided_at": null
    },
    "subscription": "sub_JgRjFjhKbtD2qz",
    "subtotal": 2000,
    "tax": null,
    "tax_percent": null,
    "total": 2000,
    "total_discount_amounts": [],
    "total_tax_amounts": [],
    "transfer_data": null,
    "webhooks_delivered_at": 1623873347
  },
  "livemode": false,
  "metadata": {
  },
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "plan": {
    "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
    "object": "plan",
    "active": true,
    "amount": 2000,
    "amount_decimal": "2000",
    "billing_scheme": "per_unit",
    "created": 1623864151,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "nickname": null,
    "product": "prod_JgPF5xnq7qBun3",
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "schedule": null,
  "start": 1623873347,
  "start_date": 1623873347,
  "status": "incomplete",
  "tax_percent": null,
  "transfer_data": null,
  "trial_end": null,
  "trial_start": null
}
```

### Actualiza el punto de conexión del servidor

Agrega la creación de claves efímeras al punto de conexión de la suscripción y devuélvela en la respuesta:

#### Accounts&nbsp;v2

#### Ruby

```ruby
ephemeral_key = Stripe::EphemeralKey.create(
  {customer_account: customer_account_id},
  {stripe_version: '2026-03-25.dahlia'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerAccountId: customer_account_id,
}.to_json
```

#### Customers&nbsp;v1

#### Ruby

```ruby
ephemeral_key = client.v1.ephemeral_keys.create(
  {customer: customer_id},
  {stripe_version: '2025-06-30.basil'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerId: customer_id,
}.to_json
```

### Actualiza tu modelo de respuesta

#### Accounts&nbsp;v2

```swift
struct SubscriptionsResponse: Decodable {
    let subscriptionId: String
    let clientSecret: String
    let ephemeralKey: String
    let customerAccountId: String
}
```

#### Customers&nbsp;v1

```swift
struct SubscriptionsResponse: Decodable {
    let subscriptionId: String
    let clientSecret: String
    let ephemeralKey: String
    let customerId: String
}
```

### Pasar la configuración del cliente a PaymentSheet

#### Accounts&nbsp;v2

Agrega lo siguiente al configurar PaymentSheet:

```swift
config.customerAccount = .init(id: customerAccountId, ephemeralKeySecret: ephemeralKey)
```

#### Customers&nbsp;v1

Agrega lo siguiente al configurar PaymentSheet:

```swift
config.customer = .init(id: customerId, ephemeralKeySecret: ephemeralKey)
```

## Recopilar datos de pago [Cliente]

Utiliza [Payment Sheet](https://docs.stripe.com/payments/mobile/payment-sheet.md) para recolectar detalles del pago y activar la suscripción. Puedes personalizar Elements para que coincida con la apariencia de tu solicitud.

Payment Sheet recopila de forma segura todos los detalles de pago necesarios para una amplia variedad de métodos de pago. Más información sobre los [métodos de pago admitidos](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support) para Payment Sheet y Subscriptions.

### Agregar el Payment Element a tu aplicación

> Este paso muestra una forma de empezar, pero puedes usar cualquier [integración de pagos dentro de la aplicación](https://docs.stripe.com/payments/mobile.md).

Inicializa y presenta el Payment Element móvil usando la clase PaymentSheet.

```swift
struct SubscribeView: View {
    let paymentSheet: PaymentSheet
    @State var isPaymentSheetPresented = false
    init(clientSecret: String) {
        var config = PaymentSheet.Configuration()
        // Set `allowsDelayedPaymentMethods` to true if your business handles
        // delayed notification payment methods like US bank accounts.
        config.allowsDelayedPaymentMethods = true
        config.primaryButtonLabel = "Subscribe for $15/month"
        self.paymentSheet = PaymentSheet(paymentIntentClientSecret: clientSecret, configuration: config)
    }
    var body: some View {
        Button {
            isPaymentSheetPresented = true
        } label: {
            Text("Subscribe")
        }.paymentSheet(isPresented: $isPaymentSheetPresented, paymentSheet: paymentSheet) { result in
            switch result {
            case .completed:
                // Handle completion
            case .canceled:
                break
            case .failed(let error):
                // Handle error
            }
        }
    }
}
```

El Payment Element móvil renderiza una hoja que le permite a tu cliente seleccionar un método de pago. El formulario recopila automáticamente todos los datos de pago necesarios para el método de pago que elijan.

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

Puedes personalizar el Payment Element para que coincida con el diseño de tu aplicación usando la [propiedad `appearance`](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) de tu objeto `PaymentSheet.Configuration`.

### Confirmar pago

El Payment Element móvil crea un PaymentMethod y confirma que el primer PaymentIntent de la suscripción está incompleto, lo que genera un cargo. Si se requiere *autenticación reforzada de clientes* (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) (SCA) para el pago, el Payment Element se encarga del proceso de autenticación antes de confirmar el PaymentIntent.

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

El cliente puede salir de tu aplicación para autenticarse (por ejemplo, en Safari o en su aplicación bancaria). Para permitirles que regresen automáticamente a tu aplicación después de autenticarse, [configura un esquema de URL personalizado](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) y define 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, debes definir la [returnURL](https://stripe.dev/stripe-ios/stripe-paymentsheet/Classes/PaymentSheet/Configuration.html#/s:6Stripe12PaymentSheetC13ConfigurationV9returnURLSSSgvp) del 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"
```

## Optional: Habilitar Apple Pay

### Inscribirse para obtener un ID de comerciante Apple

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

Completa el formulario con una descripción y el identificador. La descripción es para tus registros y se puede modificar en el futuro. Stripe recomienda usar el nombre de tu aplicación como identificador (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 **Agregar nueva aplicación** y sigue la guía.

Descarga un archivo de solicitud 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 exactamente un certificado. 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 una nueva CSR y un nuevo certificado.

### Integrarse con Xcode

Agrega la funcionalidad Apple Pay a tu aplicación. En Xcode, abre la configuración del proyecto, selecciona la pestaña **Firma y funcionalidades** y agrega la funcionalidad **Apple Pay**. En este paso, quizá se te solicite iniciar 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)

Habilitar la funcionalidad Apple Pay en Xcode

### Agregar Apple Pay

#### Pagos recurrentes

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

Conforme a las [directrices de Apple](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) para pagos recurrentes, también debes establecer otros atributos en `PKPaymentRequest`. Agrega 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 la cantidad que pretendes cobrar (por ejemplo, USD&nbsp;9.95 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 la [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 agregar información de [seguimiento de pedidos](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) en iOS 16 o posterior, configura un [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) en tu `PaymentSheet.ApplePayConfiguration.Handlers`. Stripe llamará a tu implementación después de que se efectivice el pago, pero antes de que iOS descarte la hoja de Apple Pay.

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

Para obtener más información sobre el seguimiento de pedidos, consulta la [Documentación sobre los pedidos por billetera de Apple](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)
```

## Escuchar webhooks [Servidor]

Para completar la integración, tienes que procesar los *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) que envió Stripe. Estos son eventos que se originan cada vez que un estado dentro de Stripe cambia, por ejemplo, cuando las suscripciones crean facturas nuevas. En tu aplicación, configura un controlador de HTTP para aceptar una solicitud POST que contenga el evento de webhook y verifica la firma del evento:

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/webhook' do
  # You can use webhooks to receive information about asynchronous payment events.
  # For more about our webhook events check out https://stripe.com/docs/webhooks.
  webhook_secret = ENV['STRIPE_WEBHOOK_SECRET']
  payload = request.body.read
  if !webhook_secret.empty?
    # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, webhook_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts '⚠️  Webhook signature verification failed.'
      status 400
      return
    end
  else
    data = JSON.parse(payload, symbolize_names: true)
    event = Stripe::Event.construct_from(data)
  end
  # Get the type of webhook event sent - used to check the status of PaymentIntents.
  event_type = event['type']
  data = event['data']
  data_object = data['object']

  if event_type == 'invoice.paid'
    # Used to provision services after the trial has ended.
    # The status of the invoice will show up as paid. Store the status in your
    # database to reference when a user accesses your service to avoid hitting rate
    # limits.
    # puts data_object
  end

  if event_type == 'invoice.payment_failed'
    # If the payment fails or the customer does not have a valid payment method,
    # an invoice.payment_failed event is sent, the subscription becomes past_due.
    # Use this webhook to notify your user that their payment has
    # failed and to retrieve new card details.
    # puts data_object
  end

  if event_type == 'customer.subscription.deleted'
    # handle subscription canceled automatically based
    # upon your subscription settings. Or if the user cancels it.
    # puts data_object
  end

  content_type 'application/json'
  { status: 'success' }.to_json
end
```

Durante el desarrollo, usa la CLI de Stripe para [observar los webhooks y reenviarlos a tu aplicación](https://docs.stripe.com/webhooks.md#test-webhook). Ejecuta lo siguiente en una nueva terminal mientras tu aplicación de desarrollo está funcionando:

#### curl

```bash
  stripe listen --forward-to localhost:4242/webhook
```

Para la producción, configura una URL de punto de conexión de webhook en el Dashboard o utiliza la [API Webhook Endpoints](https://docs.stripe.com/api/webhook_endpoints.md).

Necesita escuchar algunos eventos para completar los pasos restantes de esta guía. Consulte [Eventos de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) para más detalles sobre los webhooks específicos de suscripción.

## Brindar acceso a tu servicio [Cliente y servidor]

Ahora que la suscripción está activa, dale a tu usuario acceso a tu servicio. Para ello, escucha los eventos `customer.subscription.created`, `customer.subscription.updated`, y `customer.subscription.deleted`. Estos eventos pasan un objeto Subscription que contiene un campo `status` que indica si la suscripción está activa, vencida o cancelada. Consulta [el ciclo de vida de la suscripción](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle) para obtener una lista completa de estados.

En tu controlador de webhook:

1. Verifica el estado de la suscripción. Si es `activo`, entonces tu usuario ha pagado por su producto.
1. Revisa el producto al que se suscribió el cliente y bríndale acceso al servicio. Es mejor revisar el producto que el precio porque te da más flexibilidad en caso de que necesites cambiar la tarifa o el intervalo de facturación.
1. Almacena el `product.id`, `subscription.id` y el `subscription.status` en tu base de datos junto con `customer.id` que ya guardaste. Consulta este registro cuando tengas que determinar qué funcionalidades habilitar para el usuario en tu aplicación.

El estado de la suscripción puede cambiar en cualquier momento de su ciclo de vida, incluso si tu solicitud no hace ninguna llamada directa a Stripe. Por ejemplo, se puede producir un error de renovación debido a una tarjeta de crédito vencida, lo que genera que el estado de la suscripción pase a vencido. O, si usas el [portal de clientes](https://docs.stripe.com/customer-management.md), un usuario puede optar por cancelar la suscripción sin ingresar a tu aplicación directamente. El uso correcto del controlador mantiene el estado de tu solicitud sincronizado con Stripe.

## Cancelar la suscripción [Cliente y servidor]

Con frecuencia, se les permite a los clientes cancelar su suscripción. En este ejemplo, se agrega la opción de cancelación en la página de configuración de la cuenta.

En este ejemplo, el ID de la suscripción se recopila en el front-end, pero tu aplicación puede obtener esta información de tu base de datos para el usuario que ha iniciado sesión.
![Modelo de interfaz de cancelación de suscripciones.](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png)

Configuración de la cuenta con la posibilidad de cancelar la suscripción

```swift
func cancelSubscription() async {
    var request = URLRequest(url: URL(string: "http://localhost:4242/cancel-subscription")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscription.id])
    let (subscriptionResponse, _) = try! await URLSession.shared.data(for: request)
    // Update the state to show the subscription has been cancelled
}
```

En el back-end, define el punto de conexión para que la aplicación haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/cancel-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId'])

  deleted_subscription.to_json
end
```

Tu back-end recibe un evento `customer.subscription.deleted`.

Una vez que se cancela la suscripción, actualiza tu base de datos para eliminar el ID de suscripción de Stripe que estaba almacenado y limitar el acceso al servicio.

Cuando una suscripción se cancela, no se puede reactivar. En su lugar, recopila información de facturación actualizada de tu cliente, actualiza su método de pago predeterminado y crea una nueva suscripción con su registro de cliente existente.

## Prueba tu integración

### Prueba métodos de pago

Usa la siguiente tabla para probar diferentes métodos y escenarios de pago.

| Método de pago      | Escenario                                                                                                                                                                                                                                                                                       | Cómo hacer la prueba                                                                                                                                                                         |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Débito directo BECS | Tu cliente paga correctamente con débito directo BECS.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `900123456` y BSB `000000`. El PaymentIntent confirmado pasa en un principio al estado `processing` y, tres minutos más tarde, a `succeeded`. |
| Débito directo BECS | El pago de tu cliente falla con un código de error `account_closed`.                                                                                                                                                                                                                            | Completa el formulario con el número de cuenta `111111113` y BSB `000000`.                                                                                                                   |
| Tarjeta de crédito  | El pago con tarjeta se efectúa correctamente y no requiere autenticación.                                                                                                                                                                                                                       | Completa el formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | El pago con tarjeta 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). | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | La tarjeta es rechazada con el código `insufficient_funds`.                                                                                                                                                                                                                                     | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Débito directo SEPA | Tu cliente paga correctamente con débito directo SEPA.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `AT321904300235473204`. El PaymentIntent confirmado pasa inicialmente al estado “en proceso” y, tres minutos más tarde, a “completado”.       |
| Débito directo SEPA | El estado de PaymentIntent de tu cliente pasa de `processing` a `requires_payment_method`.                                                                                                                                                                                                      | Completa el formulario con el número de cuenta `AT861904300235473202`.                                                                                                                       |

### Supervisa eventos

Configura webhooks para recibir notificaciones de los eventos de cambios en las suscripciones, como actualizaciones y cancelaciones. Obtén más información sobre los [webhooks de suscripciones](https://docs.stripe.com/billing/subscriptions/webhooks.md). Puedes ver los eventos en el [Dashboard](https://dashboard.stripe.com/test/events) o con la [CLI de Stripe](https://docs.stripe.com/webhooks.md#test-webhook).

Para obtener más detalles, consulta [cómo probar tu integración con Billing](https://docs.stripe.com/billing/testing.md).

## Optional: Permitir que los clientes cambien de plan [Cliente y servidor]

Para permitirles a los clientes cambiar de suscripción, recopila el ID de precio de la opción a la que quieren pasar. A continuación, envía el nuevo ID de precio desde la aplicación a un punto de conexión del back-end. En este ejemplo, también se especifica el ID de suscripción, pero puedes recuperarlo de tu base de datos para el usuario que ha iniciado sesión.

```swift
func updateSubscription(priceId: String, subscriptionId: String) async -> SubscriptionsResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/update-subscription")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscriptionId, "priceId": priceId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // SubscriptionsResponse is a Decodable struct conforming to the expected response from your backend
    let subscriptionsResponse = try! JSONDecoder().decode(SubscriptionsResponse.self, from: responseData)
    return subscriptionsResponse
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada especificando el ID de suscripción y el nuevo ID de precio. La suscripción ahora es Premium, a USD&nbsp;15 por mes, en lugar de Básica a USD&nbsp;5 por mes.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/update-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  updated_subscription =
    client.v1.subscriptions.update(
      data['subscriptionId'],
      cancel_at_period_end: false,
      items: [
        { id: subscription.items.data[0].id, price: data['newPriceId'] }
      ]
    )

  updated_subscription.to_json
end
```

En tu aplicación, se recibe un evento `customer.subscription.updated`.

## Optional: Previsualizar un cambio de precio [Cliente y servidor]

Cuando tu cliente cambia de suscripción, a menudo es necesario hacer un ajuste en el importe adeudado que se conoce como [prorrateo](https://docs.stripe.com/billing/subscriptions/prorations.md). Puedes usar el [punto de conexión de creación de la vista previa de facturas](https://docs.stripe.com/api/invoices/create_preview.md) para mostrarles a tus clientes el importe ajustado.

Desde la aplicación, pasa los datos de la vista previa de la factura a un punto de conexión del back-end.

```swift
func createPreviewInvoice(customerId: String, subscriptionId: String, newPriceId: String) async -> InvoiceResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/create-preview-invoice")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["subscriptionId": subscriptionId, "customerId": customerId, "newPriceId": newPriceId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // Invoice is a Decodable struct conforming to the expected response from your backend
    let invoiceResponse = try! JSONDecoder().decode(InvoiceResponse.self, from: responseData)
    return invoiceResponse
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Accounts&nbsp;v2

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = Stripe::Subscription.retrieve(data['subscriptionId'])

  invoice =
    Stripe::Invoice.create_preview(
      customer_account: data['customerAccountId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

#### Customers&nbsp;v1

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  invoice =
    client.v1.invoices.create_preview(
      customer: data['customerId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

## Optional: Mostrar el método de pago del cliente [Cliente y servidor]

Mostrar la marca y los últimos 4 dígitos de la tarjeta le permite al cliente saber qué tarjeta se está utilizando o si es necesario actualizar el método de pago.

Desde el front-end, pasa el ID del método de pago a un punto de conexión del back-end que recupere los datos del método de pago.

```swift
func retrieveCustomerPaymentMethod(paymentMethodId: String) async -> PaymentMethodResponse {
    var request = URLRequest(url: URL(string: "http://localhost:4242/retrieve-customer-payment-method")!)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = try! JSONEncoder().encode(["paymentMethodId": paymentMethodId])
    let (responseData, _) = try! await URLSession.shared.data(for: request)
    // PaymentMethodResponse is a Decodable struct conforming to the expected response from your backend
    let paymentMethodResponse = try! JSONDecoder().decode(PaymentMethodResponse.self, from: responseData)
    return paymentMethodResponse
}
```

En el back-end, define el punto de conexión para que la aplicación haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/retrieve-customer-payment-method' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId'])

  payment_method.to_json
end
```

Ejemplo de respuesta:

```json
{
  "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42",
  "object": "payment_method",
  "billing_details": {
    "address": {
      "city": null,
      "country": null,
      "line1": null,
      "line2": null,
      "postal_code": null,
      "state": null
    },
    "email": null,
    "name": null,
    "phone": null
  },
  "card": {
    "brand": "visa",
    "checks": {
      "address_line1_check": null,
      "address_postal_code_check": null,
      "cvc_check": "pass"
    },
    "country": "US",
    "exp_month": 8,
    "exp_year": 2021,
    "fingerprint": "Xt5EWLLDS7FJjR1c",
    "funding": "credit",
    "generated_from": null,
    "last4": "4242",
    "three_d_secure_usage": {
      "supported": true
    },
    "wallet": null
  },
  "created": 1588010536,
  "customer": "cus_HAxB7dVQxhoKLh",
  "livemode": false,
  "metadata": {},
  "type": "card"
}
```

> Te recomendamos guardar `paymentMethod.id` y `last4` en tu base de datos, por ejemplo, `paymentMethod.id` como `stripeCustomerPaymentMethodId` en tu colección o tabla de `users`. Si lo necesitas, también tienes la opción de guardar `exp_month`, `exp_year`, `fingerprint` y `billing_details`. Esto sirve para limitar el número de llamadas a Stripe, tanto para mejorar el rendimiento como para evitar una posible limitación de la frecuencia.

## Cuéntales a tus clientes qué es Stripe

Stripe recopila información sobre las interacciones de los clientes con Elements para proporcionarte servicios, mejorarlos y prevenir el fraude. Esto incluye el uso de cookies y direcciones IP para identificar qué Elements vio un cliente durante una sola sesión de finalización de compra. Tienes la responsabilidad de divulgar y obtener todos los derechos y consentimientos necesarios para que Stripe use los datos para dichos fines. Si deseas obtener más información, visita nuestro [centro de privacidad](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe).

#### Android

Aprende a vender *subscriptions* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) de precio fijo. Usarás [Payment Element para dispositivos móviles](https://docs.stripe.com/payments/accept-a-payment.md) para crear un formulario de pago personalizado que puedes integrar en tu aplicación.
![Página de suscripción de precio fijo con Payment Element móvil](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png)

> Si vendes productos o servicios digitales que se consumen dentro de tu aplicación (por ejemplo, suscripciones, monedas de juegos, niveles de juegos, acceso a contenido prémium o desbloqueo de una versión completa), debes usar las API de compra desde la aplicación de Apple. Esta regla tiene algunas excepciones, como los servicios personales uno a uno y las [aplicaciones basadas en regiones específicas](https://support.stripe.com/questions/changes-to-mobile-app-store-rules). Consulta las [pautas de revisión de la App Store](https://developer.apple.com/app-store/review/guidelines/#payments) para obtener más información.

## Crear tu suscripción

Esta guía te explica cómo:

- Modelar tu empresa creando un catálogo de productos.
- Crear un proceso de registro para agregar clientes.
- Crear suscripciones y recopilar información de pago.
- Comprueba y supervisa el estado de los pagos y las suscripciones.
- Permitir que los clientes cambien de plan o cancelen la suscripción.
- Aprenda a usar el [modo facturación flexible](https://docs.stripe.com/billing/subscriptions/billing-mode.md) para acceder a un comportamiento de facturación mejorado y funcionalidades adicionales.

## Cómo modelar la suscripción en Stripe

Las [suscripciones](https://docs.stripe.com/api/subscriptions.md) simplifican la facturación, ya que crean de forma automática *facturas* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice) y [PaymentIntents](https://docs.stripe.com/api/payment_intents.md). Para crear y activar una suscripción, primero debes crear un *producto* (Products represent what your business sells—whether that's a good or a service) para modelar lo que se vende y un *precio* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) que determine el intervalo y el importe para aceptar pagos. También necesitas un objeto `Account` configurado por el cliente o un objeto `Customer` para almacenar los *PaymentMethods* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) utilizados para realizar cada pago recurrente.

#### Accounts&nbsp;v2
Diagrama que muestra objetos de facturación comunes y sus relaciones (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions)
#### Customer v1
Diagrama que muestra objetos de facturación comunes y sus relaciones (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions)
### Definiciones de los objetos de la API

| Recurso                                                                                                                                | Definición                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Cuenta configurada como un cliente](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | Representa a un cliente en la API Accounts v2 que compra una suscripción. Configura un objeto `Cuenta` como cliente y asócialo a una suscripción para realizar cargos recurrentes y hacerles un seguimiento, y para gestionar los productos a los que se suscribe. Consulta nuestra [guía Usar cuentas como clientes](https://docs.stripe.com/connect/use-accounts-as-customers.md) para obtener más información.                                 |
| [Customer](https://docs.stripe.com/api/customers.md)                                                                                   | Representa a un cliente en la API Clientes que compra una suscripción. Usa el objeto `Cliente` asociado a una suscripción para realizar y hacer seguimiento de los cargos recurrentes y administrar los productos a los que se suscriben.                                                                                                                                                                                                         |
| [Derecho](https://docs.stripe.com/api/entitlements/active-entitlement.md)                                                              | Representa el acceso de un cliente a una funcionalidad incluida en un producto de servicio al que está suscrito. Cuando creas una suscripción para la compra recurrente de un producto por parte de un cliente, se crea automáticamente un derecho activo para cada funcionalidad asociada a ese producto. Cuando un cliente accede a tus servicios, utiliza sus derechos activos para habilitar las funcionalidades incluidas en su suscripción. |
| [Funcionalidad](https://docs.stripe.com/api/entitlements/feature.md)                                                                   | Representa una funcionalidad o capacidad a la que tus clientes pueden acceder cuando se suscriben a un producto de servicio. Puedes incluir funciones en un producto creando ProductFeatures.                                                                                                                                                                                                                                                     |
| [Factura](https://docs.stripe.com/api/invoices.md)                                                                                     | Una declaración de importes que un cliente adeuda y que rastrea los estados de pago desde el borrador hasta su pago o su finalización. Las suscripciones generan facturas automáticamente.                                                                                                                                                                                                                                                        |
| [PaymentIntent](https://docs.stripe.com/api/payment_intents.md)                                                                        | Una forma de crear flujos de pago dinámicos. Un PaymentIntent hace un seguimiento del ciclo de vida del flujo del proceso compra del cliente y activa pasos adicionales de autenticación, si así lo exigen las disposiciones normativas, las reglas antifraude personalizadas de Radar o los métodos de pago con redireccionamiento. Las facturas crean PaymentIntents de forma automática.                                                       |
| [PaymentMethod](https://docs.stripe.com/api/payment_methods.md)                                                                        | Los métodos de pago que usa un cliente para pagar tus productos. Por ejemplo, puedes guardar una tarjeta de crédito en un objeto `Cuenta` o `Cliente` configurado por el cliente y usarla para hacer pagos recurrentes para ese cliente. Por lo general, se usa con las API Payment Intents o Setup Intents.                                                                                                                                      |
| [Precio](https://docs.stripe.com/api/prices.md)                                                                                        | Define el precio por unidad, la moneda y el ciclo de facturación para un producto.                                                                                                                                                                                                                                                                                                                                                                |
| [Producto](https://docs.stripe.com/api/products.md)                                                                                    | Un bien o servicio que vende tu empresa. Un producto de servicio puede incluir una o más funciones.                                                                                                                                                                                                                                                                                                                                               |
| [ProductFeature](https://docs.stripe.com/api/product-feature.md)                                                                       | Representa la inclusión de una sola funcionalidades en un solo producto. Cada producto está asociado a una ProductFeature para cada funcionalidad que incluye, y cada funcionalidad está asociada a una ProductFeature para cada producto que la incluye.                                                                                                                                                                                         |
| [Suscripción](https://docs.stripe.com/api/subscriptions.md)                                                                            | Representa la compra recurrente programada de un producto por parte de un cliente. Usa una suscripción para cobrar pagos y proporcionar entrega repetida o acceso continuo a un producto.                                                                                                                                                                                                                                                         |

Veamos un ejemplo de cómo funcionan juntos los productos, las funcionalidades y los derechos. Imagina que quieres configurar un servicio recurrente que ofrezca dos niveles: un producto estándar con funcionalidad básica y un producto avanzado que agregue funcionalidad extendida.

1. Creas dos funcionalidades: `basic_features` y `extended_features`.
1. Creas dos productos: `standard_product` y `advanced_product`.
1. Para el producto estándar, creas una ProductFeature que asocia `basic_features` con `standard_product`.
1. Para el producto avanzado, creas dos ProductFeatures: una que asocia `basic_features` con `advanced_product` y otra que asocia `extended_features` con `advanced_product`.

Un cliente, `first_customer`, se suscribe al producto estándar. Cuando creas la suscripción, Stripe crea automáticamente un derecho que asocia `first_customer` con `basic_features`.

Otro cliente, `second_customer`, se suscribe al producto avanzado. Al crear la suscripción, Stripe crea automáticamente dos derechos: uno que asocia `second_customer` con `basic_features` y otro que asocia `second_customer` con `extended_features`.

Puedes determinar qué funcionalidades aprovisionar para un cliente [recuperando sus derechos activos o recibiendo notificaciones del evento Resumen de derechos activos](https://docs.stripe.com/billing/entitlements.md#entitlements). No tienes que recuperar sus suscripciones, productos y funcionalidades.

## Configura Stripe

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, agrega `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) en 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).

Configura el SDK con tu [clave publicable](https://dashboard.stripe.com/apikeys) de Stripe para que pueda hacer solicitudes a la API de Stripe, así como en tu subclase `Application`:

#### Kotlin

```kotlin
import com.stripe.android.PaymentConfiguration

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        PaymentConfiguration.init(
            applicationContext,
            "<<YOUR_PUBLISHABLE_KEY>>"
        )
    }
}
```

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

A continuación, instala la CLI de Stripe. La CLI proporciona pruebas de webhook y puedes ejecutarla para realizar llamadas API a Stripe. Esta guía muestra cómo utilizar la CLI para configurar un modelo de precios en una sección posterior.
Para obtener más opciones de instalación, consulta [Empezar a usar la CLI de Stripe](https://docs.stripe.com/stripe-cli.md).
## Crear el modelo de tarifas [CLI o Dashboard de Stripe]

Los [modelos de precios recurrentes](https://docs.stripe.com/products-prices/pricing-models.md) representan los productos o servicios que vendes, cuánto cuestan, qué monedas aceptas para los pagos y el período de servicio para las suscripciones. Para crear el modelo de precios, crea [productos](https://docs.stripe.com/api/products.md) (lo que vendes) y [precios](https://docs.stripe.com/api/prices.md) (cuánto cuestan y con qué frecuencia cobrar por los productos).

En este ejemplo, se utiliza una tarifa con tasa fija con dos opciones de niveles de servicio diferentes: básico y premium. Para cada opción de nivel de servicio, debes crear un producto y un precio recurrente. Si quieres agregar un cargo por única vez, como el costo de instalación, crea un tercer producto con un precio por única vez.

Cada producto se factura de forma mensual. El precio del producto básico es de 5 USD. El precio del producto premium es de 15 USD. Consulta la guía de [tarifas con tasa fija](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md) para ver un ejemplo con tres niveles.

#### Dashboard

Ve a la página [Agregar un producto](https://dashboard.stripe.com/test/products/create) y crea dos productos. Agrega un precio a cada producto, cada uno con un período de facturación mensual recurrente:

- Producto prémium: servicio prémium con más funcionalidades

  - Precio: Tarifa plana | 15 USD

- Producto básico: servicio básico con las funcionalidades mínimas

  - Precio: Tarifa plana | 5 USD

Después de crear los precios, registra los ID de precio para usarlos en otros pasos. Los ID de precio se ven así: `price_G0FvDp6vZvdwRZ`.

Cuando esté todo listo, usa el botón **Copiar en modo activo**, en la parte superior derecha de la página, para clonar el producto y pasarlo de [entorno de prueba a modo activo](https://docs.stripe.com/keys.md#test-live-modes).

#### API

Puedes usar la API para crear los [productos](https://docs.stripe.com/api/products.md) y los [precios](https://docs.stripe.com/api/prices.md).

Crear el producto premium:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

Crear el producto básico:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Basic Service" \
  -d "description=Basic service with minimum features"
```

Registra el ID de cada producto. Se ve así:

```json
{
  "id": "prod_H94k5odtwJXMtQ",
  "object": "product",
  "active": true,
  "attributes": [

  ],
  "created": 1587577341,
  "description": "Premium service with extra features",
  "images": [

  ],
  "livemode": false,
  "metadata": {
  },
  "name": "Billing Guide: Premium Service",
  "statement_descriptor": null,
  "type": "service",
  "unit_label": null,
  "updated": 1587577341
}
```

Usa los ID de producto para crear el precio de cada producto. El número [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) está en centavos. Por ejemplo, `1500` = 15 USD.

Crear el precio superior:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{PREMIUM_PRODUCT_ID}} \
  -d unit_amount=1500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Crear el precio básico:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{BASIC_PRODUCT_ID}} \
  -d unit_amount=500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Registra el ID de cada precio para poder utilizarlo en los pasos siguientes. Se ve así:

```json
{
  "id": "price_HGd7M3DV3IMXkC",
  "object": "price",
  "product": "prod_HGd6W1VUqqXGvr",
  "type": "recurring",
  "currency": "usd",
  "recurring": {
    "interval": "month",
    "interval_count": 1,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "active": true,
  "billing_scheme": "per_unit",
  "created": 1589319695,
  "livemode": false,
  "lookup_key": null,
  "metadata": {},
  "nickname": null,
  "unit_amount": 1500,
  "unit_amount_decimal": "1500",
  "tiers": null,
  "tiers_mode": null,
  "transform_quantity": null
}
```

## Crear el cliente [Cliente y servidor]

Stripe necesita un cliente para cada suscripción. En el front-end de tu solicitud, recopila toda la información necesaria de tus usuarios y envíala al back-end.

Es posible que desees usar una biblioteca de la red para enviar solicitudes de red a tu back-end. Este documento utiliza [okhttp](https://square.github.io/okhttp/), pero puedes utilizar cualquier biblioteca que funcione mejor en tu proyecto.

```groovy
dependencies {
  ...
  implementation "com.squareup.okhttp3:okhttp:4.12.0"
}
```

Si necesitas recopilar datos de la dirección, el Address Element te permite recopilar una dirección de envío o facturación para tus clientes. Para obtener más información sobre el Address Element, visita la página de [Address Element](https://docs.stripe.com/elements/address-element.md).

```kotlin
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Button
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

@Composable
fun RegisterView() {
    var email by remember { mutableStateOf("") }
    Column {
        OutlinedTextField(value = email,
            label = { Text(text = "Email") },
            onValueChange = { email = it })
        Button(onClick = {
            val body = JSONObject().put("email", email).toString()
                .toRequestBody("application/json".toMediaType())
            val request =
                Request.Builder().url("http://10.0.2.2:4567/create-customer").post(body).build()
            CoroutineScope(Dispatchers.IO).launch {
                OkHttpClient().newCall(request).execute().use { response ->
                    if (response.isSuccessful) {
                        println(JSONObject(response.body!!.string()).get("customer"))
                    }
                }
            }
        }) {
            Text(text = "Submit")
        }
    }
}
```

Crea el “Customer Object” de Stripe en el servidor.

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

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.preview" \
  --json '{
    "contact_email": "jenny.rosen@example.com",
    "display_name": "Jenny Rosen",
    "identity": {
        "individual": {
            "given_name": "Jenny Rosen",
            "address": {
                "city": "San Francisco",
                "country": "US",
                "line1": "123 Main Street",
                "postal_code": "94605",
                "state": "CA"
            }
        }
    },
    "configuration": {
        "customer": {
            "capabilities": {
                "automatic_indirect_tax": {
                    "requested": true
                }
            },
            "shipping": {
                "address": {
                    "city": "San Francisco",
                    "country": "US",
                    "line1": "123 Main Street",
                    "postal_code": "94605",
                    "state": "CA"
                }
            }
        }
    },
    "include": [
        "configuration.customer",
        "identity"
    ]
  }'
```

#### Customers v1

```curl
curl https://api.stripe.com/v1/customers \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "email=jenny.rosen@example.com" \
  -d "name=Jenny Rosen" \
  -d "shipping[address][city]=San Francisco" \
  -d "shipping[address][country]=US" \
  -d "shipping[address][line1]=123 Main Street" \
  -d "shipping[address][postal_code]=9460" \
  -d "shipping[address][state]=CA" \
  -d "shipping[name]=Jenny Rosen" \
  -d "address[city]=San Francisco" \
  -d "address[country]=US" \
  -d "address[line1]=123 Main Street" \
  -d "address[postal_code]=9460" \
  -d "address[state]=CA"
```

## Crear la suscripción [Cliente y servidor]

> Si quieres procesar el Payment Element antes de crear una suscripción, consulta [Recopilar los datos de pago antes de crear un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription).

Permite que tu nuevo cliente elija un plan y luego cree la suscripción. En esta guía, elegirá entre un plan Básico y un plan Prémium.

En tu aplicación, envía el ID de precio seleccionado y el ID del registro del cliente al back-end.

#### Accounts&nbsp;v2

```kotlin
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

fun createSubscription(priceId: String, customerAccountId: String): SubscriptionResponse? {
    val body = JSONObject()
        .put("priceId", priceId)
        .put("customerAccountId", customerAccountId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/create-subscription").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // SubscriptionsResponse is data class conforming to the expected response from your backend.
            // It should include the client_secret, as discussed below.
            return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java)
        }
    }
    return null
}
```

#### Customers&nbsp;v1

```kotlin
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject

fun createSubscription(priceId: String, customerId: String): SubscriptionResponse? {
    val body = JSONObject()
        .put("priceId", priceId)
        .put("customerId", customerId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/create-subscription").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // SubscriptionsResponse is data class conforming to the expected response from your backend.
            // It should include the client_secret, as discussed below.
            return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java)
        }
    }
    return null
}
```

En el back-end, crea una suscripción con estado `incomplete` usando `payment_behavior=default_incomplete`. Luego, devuelve el `client_secret` desde el primer [payment intent](https://docs.stripe.com/payments/payment-intents.md) de la suscripción al front-end para completar el pago expandiendo el [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) en la factura más reciente de la suscripción.

Para habilitar el [comportamiento de suscripción mejorado](https://docs.stripe.com/billing/subscriptions/billing-mode.md), establece `billing_mode[type]` en `flexible`. Debes utilizar la versión de la API de Stripe [2025-06-30.basil](https://docs.stripe.com/changelog/basil.md#2025-06-30.basil) o posterior.

Establece [save_default_payment_method](https://docs.stripe.com/api/subscriptions/object.md#subscription_object-payment_settings-save_default_payment_method) en `on_subscription` para guardar el método de pago como predeterminado para una suscripción cuando un pago se realiza correctamente. Guardar un método de pago predeterminado aumenta la tasa de éxito de futuros pagos de suscripción.

En el siguiente ejemplo, se crea una `Subscription` y se expande el `confirmation_secret` de su última factura en la respuesta. Esto te permite pasar el secreto al front-end para confirmar el pago.

#### Accounts&nbsp;v2

```curl
curl https://api.stripe.com/v1/subscriptions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d "items[0][price]={{PRICE_ID}}" \
  -d payment_behavior=default_incomplete \
  -d "payment_settings[save_default_payment_method]=on_subscription" \
  -d "billing_mode[type]=flexible" \
  -d "expand[0]=latest_invoice.confirmation_secret"
```

#### Customers&nbsp;v1

```curl
curl https://api.stripe.com/v1/subscriptions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d "items[0][price]={{PRICE_ID}}" \
  -d payment_behavior=default_incomplete \
  -d "payment_settings[save_default_payment_method]=on_subscription" \
  -d "billing_mode[type]=flexible" \
  -d "expand[0]=latest_invoice.confirmation_secret"
```

> Si usas un *precio en múltiples monedas* (A single Price object can support multiple currencies. Each purchase uses one of the supported currencies for the Price, depending on how you use the Price in your integration), usa el parámetro [currency](https://docs.stripe.com/api/subscriptions/create.md#create_subscription-currency) para indicarle a la suscripción cuál de las monedas del precio debe usar. (Si omites el parámetro `currency`, la suscripción utilizará la moneda predeterminada del precio).

La suscripción ahora está `inactiva` y a la espera de pago. El ejemplo de respuesta que figura a continuación destaca los campos mínimos que deben almacenarse, pero puedes almacenar los campos a los que tu solicitud accede con frecuencia.

#### Accounts&nbsp;v2

```json
{"id": "sub_JgRjFjhKbtD2qz",
  "object": "subscription",
  "application_fee_percent": null,
  "automatic_tax": {
    "disabled_reason": null,
    "enabled": false,
    "liability": "null"
  },
  "billing_cycle_anchor": 1623873347,
  "billing_cycle_anchor_config": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "cancellation_details": {
    "comment": null,
    "feedback": null,
    "reason": null
  },
  "collection_method": "charge_automatically",
  "created": 1623873347,
  "currency": "usd","customer_account": identifier("customerAccount"),
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [

  ],
  "discounts": [],
  "ended_at": null,
  "invoice_customer_balance_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_JgRjmS4Ur1khEx",
        "object": "subscription_item",
        "created": 1623873347,"current_period_end": 1626465347,
        "current_period_start": 1623873347,
        "discounts": [],
        "metadata": {
        },
        "plan": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "plan",
          "active": true,
          "amount": 2000,
          "amount_decimal": "2000",
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "price": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 2000,
          "unit_amount_decimal": "2000"
        },
        "quantity": 1,
        "subscription": "sub_JgRjFjhKbtD2qz",
        "tax_rates": [

        ]
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz"
  },
  "latest_invoice": {
    "id": "in_1J34pzGPZ1iASj5zB87qdBNZ",
    "object": "invoice",
    "account_country": "US",
    "account_name": "Angelina's Store",
    "account_tax_ids": null,
    "amount_due": 2000,
    "amount_overpaid": 0,
    "amount_paid": 0,
    "amount_remaining": 2000,
    "amount_shipping": 0,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "disabled_reason": null,
      "enabled": false,
      "liability": null,
      "status": null
    },
    "automatically_finalizes_at": null,
    "billing_reason": "subscription_update",
    "collection_method": "charge_automatically",
    "created": 1623873347,
    "currency": "usd",
    "custom_fields": null,
    "customer_account": identifier("customerAccount"),
    "customer_address": null,
    "customer_email": "angelina@stripe.com",
    "customer_name": null,
    "customer_phone": null,
    "customer_shipping": {
      "address": {
        "city": "",
        "country": "US",
        "line1": "Berry",
        "line2": "",
        "postal_code": "",
        "state": ""
      },
      "name": "",
      "phone": null
    },
    "customer_tax_exempt": "none",
    "customer_tax_ids": [

    ],
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [

    ],
    "description": null,
    "discounts": [],
    "due_date": null,
    "effective_at": "1623873347",
    "ending_balance": 0,
    "footer": null,
    "from_invoice": null,
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp",
    "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf",
    "last_finalization_error": null,
    "latest_revision": null,
    "lines": {
      "object": "list",
      "data": [
        {
          "id": "il_1N2CjMBwKQ696a5NeOawRQP2",
          "object": "line_item",
          "amount": 2000,
          "currency": "usd",
          "description": "1 × Gold Special (at $20.00 / month)",
          "discount_amounts": [

          ],
          "discountable": true,
          "discounts": [

          ],
          "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
          "livemode": false,
          "metadata": {
          },
          "parent": {
            "invoice_item_details": null,
            "subscription_item_details":
            {
              "invoice_item": null,
            "proration": false,
            "proration_details":
            {
              "credited_items": null
            },
            "subscription":
            "sub_JgRjFjhKbtD2qz",
            "subscription_item":
              "si_JgRjmS4Ur1khEx"
            },
            "type": "subscription_item_details"
          },
          "period": {
            "end": 1626465347,
            "start": 1623873347
          },
          "plan": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "plan",
            "active": true,
            "amount": 2000,
            "amount_decimal": "2000",
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "price": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "recurring": {
              "interval": "month",
              "interval_count": 1,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 2000,
            "unit_amount_decimal": "2000"
          },
          "quantity": 1,
          "taxes": []
        }
      ],
      "has_more": false,
      "total_count": 1,
      "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines"
    },
    "livemode": false,
    "metadata": {
    },
    "next_payment_attempt": null,
    "number": "C008FC2-0354",
    "on_behalf_of": null,
    "parent": {
      "quote_details": null,
      "subscription_details": {
        "metadata": {},
        "pause_collection": null,
        "subscription": "sub_JgRjFjhKbtD2qz"
      }
    },
    "payment_intent": {
      "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6"
      },
      "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu",
      "confirmation_method": "automatic",
      "created": 1623873347,
      "currency": "usd",
      "customer": "cus_CMqDWO2xODTZqt",
      "description": "Subscription creation",
      "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
      "last_payment_error": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "receipt_email": null,
      "review": null,
      "setup_future_usage": "off_session",
      "shipping": null,
      "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ",
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_confirmation",
      "transfer_data": null,
      "transfer_group": null
    },
    "payment_settings": {
      "payment_method_options": null,
      "payment_method_types": null,
      "save_default_payment_method": "on_subscription"
    },
    "period_end": 1623873347,
    "period_start": 1623873347,
    "post_payment_credit_notes_amount": 0,
    "pre_payment_credit_notes_amount": 0,
    "receipt_number": null,
    "starting_balance": 0,
    "statement_descriptor": null,
    "status": "open",
    "status_transitions": {
      "finalized_at": 1623873347,
      "marked_uncollectible_at": null,
      "paid_at": null,
      "voided_at": null
    },
    "subscription": "sub_JgRjFjhKbtD2qz",
    "subtotal": 2000,
    "tax": null,
    "tax_percent": null,
    "total": 2000,
    "total_discount_amounts": [],
    "total_tax_amounts": [],
    "transfer_data": null,
    "webhooks_delivered_at": 1623873347
  },
  "livemode": false,
  "metadata": {
  },
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "plan": {
    "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
    "object": "plan",
    "active": true,
    "amount": 2000,
    "amount_decimal": "2000",
    "billing_scheme": "per_unit",
    "created": 1623864151,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "nickname": null,
    "product": "prod_JgPF5xnq7qBun3",
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "schedule": null,
  "start": 1623873347,
  "start_date": 1623873347,
  "status": "incomplete",
  "tax_percent": null,
  "transfer_data": null,
  "trial_end": null,
  "trial_start": null
}
```

#### Customers&nbsp;v1

```json
{"id": "sub_JgRjFjhKbtD2qz",
  "object": "subscription",
  "application_fee_percent": null,
  "automatic_tax": {
    "disabled_reason": null,
    "enabled": false,
    "liability": "null"
  },
  "billing_cycle_anchor": 1623873347,
  "billing_cycle_anchor_config": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "cancellation_details": {
    "comment": null,
    "feedback": null,
    "reason": null
  },
  "collection_method": "charge_automatically",
  "created": 1623873347,
  "currency": "usd","customer": identifier("customer"),
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [

  ],
  "discounts": [],
  "ended_at": null,
  "invoice_customer_balance_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_JgRjmS4Ur1khEx",
        "object": "subscription_item",
        "created": 1623873347,"current_period_end": 1626465347,
        "current_period_start": 1623873347,
        "discounts": [],
        "metadata": {
        },
        "plan": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "plan",
          "active": true,
          "amount": 2000,
          "amount_decimal": "2000",
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "price": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 2000,
          "unit_amount_decimal": "2000"
        },
        "quantity": 1,
        "subscription": "sub_JgRjFjhKbtD2qz",
        "tax_rates": [

        ]
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz"
  },
  "latest_invoice": {
    "id": "in_1J34pzGPZ1iASj5zB87qdBNZ",
    "object": "invoice",
    "account_country": "US",
    "account_name": "Angelina's Store",
    "account_tax_ids": null,
    "amount_due": 2000,
    "amount_overpaid": 0,
    "amount_paid": 0,
    "amount_remaining": 2000,
    "amount_shipping": 0,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "disabled_reason": null,
      "enabled": false,
      "liability": null,
      "status": null
    },
    "automatically_finalizes_at": null,
    "billing_reason": "subscription_update",
    "collection_method": "charge_automatically",
    "created": 1623873347,
    "currency": "usd",
    "custom_fields": null,
    "customer": identifier("customer"),
    "customer_address": null,
    "customer_email": "angelina@stripe.com",
    "customer_name": null,
    "customer_phone": null,
    "customer_shipping": {
      "address": {
        "city": "",
        "country": "US",
        "line1": "Berry",
        "line2": "",
        "postal_code": "",
        "state": ""
      },
      "name": "",
      "phone": null
    },
    "customer_tax_exempt": "none",
    "customer_tax_ids": [

    ],
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [

    ],
    "description": null,
    "discounts": [],
    "due_date": null,
    "effective_at": "1623873347",
    "ending_balance": 0,
    "footer": null,
    "from_invoice": null,
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp",
    "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf",
    "last_finalization_error": null,
    "latest_revision": null,
    "lines": {
      "object": "list",
      "data": [
        {
          "id": "il_1N2CjMBwKQ696a5NeOawRQP2",
          "object": "line_item",
          "amount": 2000,
          "currency": "usd",
          "description": "1 × Gold Special (at $20.00 / month)",
          "discount_amounts": [

          ],
          "discountable": true,
          "discounts": [

          ],
          "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
          "livemode": false,
          "metadata": {
          },
          "parent": {
            "invoice_item_details": null,
            "subscription_item_details":
            {
              "invoice_item": null,
            "proration": false,
            "proration_details":
            {
              "credited_items": null
            },
            "subscription":
            "sub_JgRjFjhKbtD2qz",
            "subscription_item":
              "si_JgRjmS4Ur1khEx"
            },
            "type": "subscription_item_details"
          },
          "period": {
            "end": 1626465347,
            "start": 1623873347
          },
          "plan": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "plan",
            "active": true,
            "amount": 2000,
            "amount_decimal": "2000",
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "price": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "recurring": {
              "interval": "month",
              "interval_count": 1,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 2000,
            "unit_amount_decimal": "2000"
          },
          "quantity": 1,
          "taxes": []
        }
      ],
      "has_more": false,
      "total_count": 1,
      "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines"
    },
    "livemode": false,
    "metadata": {
    },
    "next_payment_attempt": null,
    "number": "C008FC2-0354",
    "on_behalf_of": null,
    "parent": {
      "quote_details": null,
      "subscription_details": {
        "metadata": {},
        "pause_collection": null,
        "subscription": "sub_JgRjFjhKbtD2qz"
      }
    },
    "payment_intent": {
      "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6"
      },
      "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu",
      "confirmation_method": "automatic",
      "created": 1623873347,
      "currency": "usd",
      "customer": "cus_CMqDWO2xODTZqt",
      "description": "Subscription creation",
      "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
      "last_payment_error": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "receipt_email": null,
      "review": null,
      "setup_future_usage": "off_session",
      "shipping": null,
      "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ",
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_confirmation",
      "transfer_data": null,
      "transfer_group": null
    },
    "payment_settings": {
      "payment_method_options": null,
      "payment_method_types": null,
      "save_default_payment_method": "on_subscription"
    },
    "period_end": 1623873347,
    "period_start": 1623873347,
    "post_payment_credit_notes_amount": 0,
    "pre_payment_credit_notes_amount": 0,
    "receipt_number": null,
    "starting_balance": 0,
    "statement_descriptor": null,
    "status": "open",
    "status_transitions": {
      "finalized_at": 1623873347,
      "marked_uncollectible_at": null,
      "paid_at": null,
      "voided_at": null
    },
    "subscription": "sub_JgRjFjhKbtD2qz",
    "subtotal": 2000,
    "tax": null,
    "tax_percent": null,
    "total": 2000,
    "total_discount_amounts": [],
    "total_tax_amounts": [],
    "transfer_data": null,
    "webhooks_delivered_at": 1623873347
  },
  "livemode": false,
  "metadata": {
  },
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "plan": {
    "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
    "object": "plan",
    "active": true,
    "amount": 2000,
    "amount_decimal": "2000",
    "billing_scheme": "per_unit",
    "created": 1623864151,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "nickname": null,
    "product": "prod_JgPF5xnq7qBun3",
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "schedule": null,
  "start": 1623873347,
  "start_date": 1623873347,
  "status": "incomplete",
  "tax_percent": null,
  "transfer_data": null,
  "trial_end": null,
  "trial_start": null
}
```

### Actualiza el punto de conexión del servidor

Agrega la creación de claves efímeras al punto de conexión de la suscripción y devuélvela en la respuesta:

#### Accounts&nbsp;v2

#### Ruby

```ruby
ephemeral_key = Stripe::EphemeralKey.create(
  {customer_account: customer_account_id},
  {stripe_version: '2026-03-25.dahlia'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerAccountId: customer_account_id,
}.to_json
```

#### Customers&nbsp;v1

#### Ruby

```ruby
ephemeral_key = client.v1.ephemeral_keys.create(
  {customer: customer_id},
  {stripe_version: '2025-06-30.basil'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerId: customer_id,
}.to_json
```

### Actualiza tu modelo de respuesta

#### Accounts&nbsp;v2

```kotlin
data class SubscriptionsResponse(
    val subscriptionId: String,
    val clientSecret: String,
    val ephemeralKey: String,
    val customerAccountId: String
)
```

#### Customers&nbsp;v1

```kotlin
data class SubscriptionsResponse(
    val subscriptionId: String,
    val clientSecret: String,
    val ephemeralKey: String,
    val customerId: String
)
```

### Pasar la configuración del cliente a PaymentSheet

#### Accounts&nbsp;v2

Agrega lo siguiente al configurar PaymentSheet:

```kotlin
PaymentSheet.Configuration(
    primaryButtonLabel = "Subscribe for $15/month",
    merchantDisplayName = "My merchant name",
    customerAccount = PaymentSheet.CustomerConfiguration(
        id = customerAccountId,
        ephemeralKeySecret = ephemeralKey
    )
)
```

#### Customers&nbsp;v1

Agrega lo siguiente al configurar PaymentSheet:

```kotlin
PaymentSheet.Configuration(
    primaryButtonLabel = "Subscribe for $15/month",
    merchantDisplayName = "My merchant name",
    customer = PaymentSheet.CustomerConfiguration(
        id = customerId,
        ephemeralKeySecret = ephemeralKey
    )
)
```

## Recopilar datos de pago [Cliente]

Utiliza [Payment Sheet](https://docs.stripe.com/payments/mobile/payment-sheet.md) para recolectar detalles del pago y activar la suscripción. Puedes personalizar Elements para que coincida con la apariencia de tu solicitud.

Payment Sheet recopila de forma segura todos los detalles de pago necesarios para una amplia variedad de métodos de pago. Más información sobre los [métodos de pago admitidos](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support) para Payment Sheet y Subscriptions.

### Agregar el Payment Element a tu aplicación

> Este paso muestra una forma de empezar, pero puedes usar cualquier [integración de pagos dentro de la aplicación](https://docs.stripe.com/payments/mobile.md).

Inicializa y presenta el Payment Element móvil usando la clase PaymentSheet.

```kotlin
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import com.stripe.android.paymentsheet.PaymentSheet
import com.stripe.android.paymentsheet.PaymentSheetResult
import com.stripe.android.paymentsheet.rememberPaymentSheet

@Composable
fun SubscribeView(clientSecret: String) {
    val paymentSheet = rememberPaymentSheet(::onPaymentSheetResult)

    Button(onClick = {
        paymentSheet.presentWithPaymentIntent(
            clientSecret, PaymentSheet.Configuration(
                primaryButtonLabel = "Subscribe for $15/month",
                merchantDisplayName = "My merchant name",
                // Set `allowsDelayedPaymentMethods` to true if your business handles
                // delayed notification payment methods like US bank accounts.
                allowsDelayedPaymentMethods = true
            )
        )
    }) {
        Text(text = "Subscribe")
    }
}

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

El Payment Element móvil renderiza una hoja que le permite a tu cliente seleccionar un método de pago. El formulario recopila automáticamente todos los datos de pago necesarios para el método de pago que elijan.

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

Puedes personalizar el Payment Element para que coincida con el diseño de tu aplicación usando la [propiedad `appearance`](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) de tu objeto `PaymentSheet.Configuration`.

### Confirmar pago

El Payment Element móvil crea un PaymentMethod y confirma que el primer PaymentIntent de la suscripción está incompleto, lo que genera un cargo. Si se requiere *autenticación reforzada de clientes* (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) (SCA) para el pago, el Payment Element se encarga del proceso de autenticación antes de confirmar el PaymentIntent.

## Escuchar webhooks [Servidor]

Para completar la integración, tienes que procesar los *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) que envió Stripe. Estos son eventos que se originan cada vez que un estado dentro de Stripe cambia, por ejemplo, cuando las suscripciones crean facturas nuevas. En tu aplicación, configura un controlador de HTTP para aceptar una solicitud POST que contenga el evento de webhook y verifica la firma del evento:

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/webhook' do
  # You can use webhooks to receive information about asynchronous payment events.
  # For more about our webhook events check out https://stripe.com/docs/webhooks.
  webhook_secret = ENV['STRIPE_WEBHOOK_SECRET']
  payload = request.body.read
  if !webhook_secret.empty?
    # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, webhook_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts '⚠️  Webhook signature verification failed.'
      status 400
      return
    end
  else
    data = JSON.parse(payload, symbolize_names: true)
    event = Stripe::Event.construct_from(data)
  end
  # Get the type of webhook event sent - used to check the status of PaymentIntents.
  event_type = event['type']
  data = event['data']
  data_object = data['object']

  if event_type == 'invoice.paid'
    # Used to provision services after the trial has ended.
    # The status of the invoice will show up as paid. Store the status in your
    # database to reference when a user accesses your service to avoid hitting rate
    # limits.
    # puts data_object
  end

  if event_type == 'invoice.payment_failed'
    # If the payment fails or the customer does not have a valid payment method,
    # an invoice.payment_failed event is sent, the subscription becomes past_due.
    # Use this webhook to notify your user that their payment has
    # failed and to retrieve new card details.
    # puts data_object
  end

  if event_type == 'customer.subscription.deleted'
    # handle subscription canceled automatically based
    # upon your subscription settings. Or if the user cancels it.
    # puts data_object
  end

  content_type 'application/json'
  { status: 'success' }.to_json
end
```

Durante el desarrollo, usa la CLI de Stripe para [observar los webhooks y reenviarlos a tu aplicación](https://docs.stripe.com/webhooks.md#test-webhook). Ejecuta lo siguiente en una nueva terminal mientras tu aplicación de desarrollo está funcionando:

#### curl

```bash
  stripe listen --forward-to localhost:4242/webhook
```

Para la producción, configura una URL de punto de conexión de webhook en el Dashboard o utiliza la [API Webhook Endpoints](https://docs.stripe.com/api/webhook_endpoints.md).

Necesita escuchar algunos eventos para completar los pasos restantes de esta guía. Consulte [Eventos de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) para más detalles sobre los webhooks específicos de suscripción.

## Brindar acceso a tu servicio [Cliente y servidor]

Ahora que la suscripción está activa, dale a tu usuario acceso a tu servicio. Para ello, escucha los eventos `customer.subscription.created`, `customer.subscription.updated`, y `customer.subscription.deleted`. Estos eventos pasan un objeto Subscription que contiene un campo `status` que indica si la suscripción está activa, vencida o cancelada. Consulta [el ciclo de vida de la suscripción](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle) para obtener una lista completa de estados.

En tu controlador de webhook:

1. Verifica el estado de la suscripción. Si es `activo`, entonces tu usuario ha pagado por su producto.
1. Revisa el producto al que se suscribió el cliente y bríndale acceso al servicio. Es mejor revisar el producto que el precio porque te da más flexibilidad en caso de que necesites cambiar la tarifa o el intervalo de facturación.
1. Almacena el `product.id`, `subscription.id` y el `subscription.status` en tu base de datos junto con `customer.id` que ya guardaste. Consulta este registro cuando tengas que determinar qué funcionalidades habilitar para el usuario en tu aplicación.

El estado de la suscripción puede cambiar en cualquier momento de su ciclo de vida, incluso si tu solicitud no hace ninguna llamada directa a Stripe. Por ejemplo, se puede producir un error de renovación debido a una tarjeta de crédito vencida, lo que genera que el estado de la suscripción pase a vencido. O, si usas el [portal de clientes](https://docs.stripe.com/customer-management.md), un usuario puede optar por cancelar la suscripción sin ingresar a tu aplicación directamente. El uso correcto del controlador mantiene el estado de tu solicitud sincronizado con Stripe.

## Cancelar la suscripción [Cliente y servidor]

Con frecuencia, se les permite a los clientes cancelar su suscripción. En este ejemplo, se agrega la opción de cancelación en la página de configuración de la cuenta.

En este ejemplo, el ID de la suscripción se recopila en el front-end, pero tu aplicación puede obtener esta información de tu base de datos para el usuario que ha iniciado sesión.
![Modelo de interfaz de cancelación de suscripciones.](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png)

Configuración de la cuenta con la posibilidad de cancelar la suscripción

```kotlin
fun cancelSubscription(subscriptionId: String): SubscriptionResponse? {
    val body = JSONObject().put("subscriptionId", subscriptionId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/cancel-subscription").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java)
        }
    }
    return null
}
```

En el back-end, define el punto de conexión para que la aplicación haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/cancel-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId'])

  deleted_subscription.to_json
end
```

Tu back-end recibe un evento `customer.subscription.deleted`.

Una vez que se cancela la suscripción, actualiza tu base de datos para eliminar el ID de suscripción de Stripe que estaba almacenado y limitar el acceso al servicio.

Cuando una suscripción se cancela, no se puede reactivar. En su lugar, recopila información de facturación actualizada de tu cliente, actualiza su método de pago predeterminado y crea una nueva suscripción con su registro de cliente existente.

## Prueba tu integración

### Prueba métodos de pago

Usa la siguiente tabla para probar diferentes métodos y escenarios de pago.

| Método de pago      | Escenario                                                                                                                                                                                                                                                                                       | Cómo hacer la prueba                                                                                                                                                                         |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Débito directo BECS | Tu cliente paga correctamente con débito directo BECS.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `900123456` y BSB `000000`. El PaymentIntent confirmado pasa en un principio al estado `processing` y, tres minutos más tarde, a `succeeded`. |
| Débito directo BECS | El pago de tu cliente falla con un código de error `account_closed`.                                                                                                                                                                                                                            | Completa el formulario con el número de cuenta `111111113` y BSB `000000`.                                                                                                                   |
| Tarjeta de crédito  | El pago con tarjeta se efectúa correctamente y no requiere autenticación.                                                                                                                                                                                                                       | Completa el formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | El pago con tarjeta 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). | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | La tarjeta es rechazada con el código `insufficient_funds`.                                                                                                                                                                                                                                     | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Débito directo SEPA | Tu cliente paga correctamente con débito directo SEPA.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `AT321904300235473204`. El PaymentIntent confirmado pasa inicialmente al estado “en proceso” y, tres minutos más tarde, a “completado”.       |
| Débito directo SEPA | El estado de PaymentIntent de tu cliente pasa de `processing` a `requires_payment_method`.                                                                                                                                                                                                      | Completa el formulario con el número de cuenta `AT861904300235473202`.                                                                                                                       |

### Supervisa eventos

Configura webhooks para recibir notificaciones de los eventos de cambios en las suscripciones, como actualizaciones y cancelaciones. Obtén más información sobre los [webhooks de suscripciones](https://docs.stripe.com/billing/subscriptions/webhooks.md). Puedes ver los eventos en el [Dashboard](https://dashboard.stripe.com/test/events) o con la [CLI de Stripe](https://docs.stripe.com/webhooks.md#test-webhook).

Para obtener más detalles, consulta [cómo probar tu integración con Billing](https://docs.stripe.com/billing/testing.md).

## Optional: Permitir que los clientes cambien de plan [Cliente y servidor]

Para permitirles a los clientes cambiar de suscripción, recopila el ID de precio de la opción a la que quieren pasar. A continuación, envía el nuevo ID de precio desde la aplicación a un punto de conexión del back-end. En este ejemplo, también se especifica el ID de suscripción, pero puedes recuperarlo de tu base de datos para el usuario que ha iniciado sesión.

```kotlin
fun updateSubscription(subscriptionId: String, priceId: String): SubscriptionResponse? {
    val body = JSONObject()
        .put("priceId", priceId)
        .put("subscriptionId", subscriptionId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/update-subscription").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // It should include the client_secret, as discussed below.
            return Gson().fromJson(response.body!!.string(), SubscriptionResponse::class.java)
        }
    }
    return null
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada especificando el ID de suscripción y el nuevo ID de precio. La suscripción ahora es Premium, a USD&nbsp;15 por mes, en lugar de Básica a USD&nbsp;5 por mes.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/update-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  updated_subscription =
    client.v1.subscriptions.update(
      data['subscriptionId'],
      cancel_at_period_end: false,
      items: [
        { id: subscription.items.data[0].id, price: data['newPriceId'] }
      ]
    )

  updated_subscription.to_json
end
```

En tu aplicación, se recibe un evento `customer.subscription.updated`.

## Optional: Previsualizar un cambio de precio [Cliente y servidor]

Cuando tu cliente cambia de suscripción, a menudo es necesario hacer un ajuste en el importe adeudado que se conoce como [prorrateo](https://docs.stripe.com/billing/subscriptions/prorations.md). Puedes usar el [punto de conexión de creación de la vista previa de facturas](https://docs.stripe.com/api/invoices/create_preview.md) para mostrarles a tus clientes el importe ajustado.

Desde la aplicación, pasa los datos de la vista previa de la factura a un punto de conexión del back-end.

```kotlin
fun createPreviewInvoice(
    subscriptionId: String,
    priceId: String,
    newPriceId: String
): InvoiceResponse? {
    val body = JSONObject()
        .put("priceId", priceId)
        .put("subscriptionId", subscriptionId)
        .put("newPriceId", newPriceId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/create-preview-invoice").post(body).build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // InvoiceResponse is a data class conforming to the expected response from your backend
            return Gson().fromJson(response.body!!.string(), InvoiceResponse::class.java)
        }
    }
    return null
}
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Accounts&nbsp;v2

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = Stripe::Subscription.retrieve(data['subscriptionId'])

  invoice =
    Stripe::Invoice.create_preview(
      customer_account: data['customerAccountId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

#### Customers&nbsp;v1

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  invoice =
    client.v1.invoices.create_preview(
      customer: data['customerId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

## Optional: Mostrar el método de pago del cliente [Cliente y servidor]

Mostrar la marca y los últimos 4 dígitos de la tarjeta le permite al cliente saber qué tarjeta se está utilizando o si es necesario actualizar el método de pago.

Desde el front-end, pasa el ID del método de pago a un punto de conexión del back-end que recupere los datos del método de pago.

```kotlin
fun retrieveCustomerPaymentMethod(paymentMethodId: String): PaymentMethodResponse? {
    val body = JSONObject()
        .put("paymentMethodId", paymentMethodId).toString()
        .toRequestBody("application/json".toMediaType())
    val request =
        Request.Builder().url("http://10.0.2.2:4567/retrieve-customer-payment-method").post(body)
            .build()
    OkHttpClient().newCall(request).execute().use { response ->
        if (response.isSuccessful) {
            // PaymentMethodResponse is a data class conforming to the expected response from your backend
            return Gson().fromJson(response.body!!.string(), PaymentMethodResponse::class.java)
        }
    }
    return null
}
```

En el back-end, define el punto de conexión para que la aplicación haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/retrieve-customer-payment-method' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId'])

  payment_method.to_json
end
```

Ejemplo de respuesta:

```json
{
  "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42",
  "object": "payment_method",
  "billing_details": {
    "address": {
      "city": null,
      "country": null,
      "line1": null,
      "line2": null,
      "postal_code": null,
      "state": null
    },
    "email": null,
    "name": null,
    "phone": null
  },
  "card": {
    "brand": "visa",
    "checks": {
      "address_line1_check": null,
      "address_postal_code_check": null,
      "cvc_check": "pass"
    },
    "country": "US",
    "exp_month": 8,
    "exp_year": 2021,
    "fingerprint": "Xt5EWLLDS7FJjR1c",
    "funding": "credit",
    "generated_from": null,
    "last4": "4242",
    "three_d_secure_usage": {
      "supported": true
    },
    "wallet": null
  },
  "created": 1588010536,
  "customer": "cus_HAxB7dVQxhoKLh",
  "livemode": false,
  "metadata": {},
  "type": "card"
}
```

> Te recomendamos guardar `paymentMethod.id` y `last4` en tu base de datos, por ejemplo, `paymentMethod.id` como `stripeCustomerPaymentMethodId` en tu colección o tabla de `users`. Si lo necesitas, también tienes la opción de guardar `exp_month`, `exp_year`, `fingerprint` y `billing_details`. Esto sirve para limitar el número de llamadas a Stripe, tanto para mejorar el rendimiento como para evitar una posible limitación de la frecuencia.

## Cuéntales a tus clientes qué es Stripe

Stripe recopila información sobre las interacciones de los clientes con Elements para proporcionarte servicios, mejorarlos y prevenir el fraude. Esto incluye el uso de cookies y direcciones IP para identificar qué Elements vio un cliente durante una sola sesión de finalización de compra. Tienes la responsabilidad de divulgar y obtener todos los derechos y consentimientos necesarios para que Stripe use los datos para dichos fines. Si deseas obtener más información, visita nuestro [centro de privacidad](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe).

#### React Native

Aprende a vender *subscriptions* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis) de precio fijo. Usarás [Payment Element para dispositivos móviles](https://docs.stripe.com/payments/accept-a-payment.md) para crear un formulario de pago personalizado que puedes integrar en tu aplicación.
![Página de suscripción de precio fijo con Payment Element móvil](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-collect-payment-details-mobile.b11cdc8fa8952d753238df4df3375fa6.png)

> Si vendes productos o servicios digitales que se consumen dentro de tu aplicación (por ejemplo, suscripciones, monedas de juegos, niveles de juegos, acceso a contenido prémium o desbloqueo de una versión completa), debes usar las API de compra desde la aplicación de Apple. Esta regla tiene algunas excepciones, como los servicios personales uno a uno y las [aplicaciones basadas en regiones específicas](https://support.stripe.com/questions/changes-to-mobile-app-store-rules). Consulta las [pautas de revisión de la App Store](https://developer.apple.com/app-store/review/guidelines/#payments) para obtener más información.

## Crear tu suscripción

Esta guía te explica cómo:

- Modelar tu empresa creando un catálogo de productos.
- Crear un proceso de registro para agregar clientes.
- Crear suscripciones y recopilar información de pago.
- Comprueba y supervisa el estado de los pagos y las suscripciones.
- Permitir que los clientes cambien de plan o cancelen la suscripción.
- Aprenda a usar el [modo facturación flexible](https://docs.stripe.com/billing/subscriptions/billing-mode.md) para acceder a un comportamiento de facturación mejorado y funcionalidades adicionales.

## Cómo modelar la suscripción en Stripe

Las [suscripciones](https://docs.stripe.com/api/subscriptions.md) simplifican la facturación, ya que crean de forma automática *facturas* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice) y [PaymentIntents](https://docs.stripe.com/api/payment_intents.md). Para crear y activar una suscripción, primero debes crear un *producto* (Products represent what your business sells—whether that's a good or a service) para modelar lo que se vende y un *precio* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) que determine el intervalo y el importe para aceptar pagos. También necesitas un objeto `Account` configurado por el cliente o un objeto `Customer` para almacenar los *PaymentMethods* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) utilizados para realizar cada pago recurrente.

#### Accounts&nbsp;v2
Diagrama que muestra objetos de facturación comunes y sus relaciones (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions)
#### Customer v1
Diagrama que muestra objetos de facturación comunes y sus relaciones (See full diagram at https://docs.stripe.com/billing/subscriptions/build-subscriptions)
### Definiciones de los objetos de la API

| Recurso                                                                                                                                | Definición                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| -------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Cuenta configurada como un cliente](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) | Representa a un cliente en la API Accounts v2 que compra una suscripción. Configura un objeto `Cuenta` como cliente y asócialo a una suscripción para realizar cargos recurrentes y hacerles un seguimiento, y para gestionar los productos a los que se suscribe. Consulta nuestra [guía Usar cuentas como clientes](https://docs.stripe.com/connect/use-accounts-as-customers.md) para obtener más información.                                 |
| [Customer](https://docs.stripe.com/api/customers.md)                                                                                   | Representa a un cliente en la API Clientes que compra una suscripción. Usa el objeto `Cliente` asociado a una suscripción para realizar y hacer seguimiento de los cargos recurrentes y administrar los productos a los que se suscriben.                                                                                                                                                                                                         |
| [Derecho](https://docs.stripe.com/api/entitlements/active-entitlement.md)                                                              | Representa el acceso de un cliente a una funcionalidad incluida en un producto de servicio al que está suscrito. Cuando creas una suscripción para la compra recurrente de un producto por parte de un cliente, se crea automáticamente un derecho activo para cada funcionalidad asociada a ese producto. Cuando un cliente accede a tus servicios, utiliza sus derechos activos para habilitar las funcionalidades incluidas en su suscripción. |
| [Funcionalidad](https://docs.stripe.com/api/entitlements/feature.md)                                                                   | Representa una funcionalidad o capacidad a la que tus clientes pueden acceder cuando se suscriben a un producto de servicio. Puedes incluir funciones en un producto creando ProductFeatures.                                                                                                                                                                                                                                                     |
| [Factura](https://docs.stripe.com/api/invoices.md)                                                                                     | Una declaración de importes que un cliente adeuda y que rastrea los estados de pago desde el borrador hasta su pago o su finalización. Las suscripciones generan facturas automáticamente.                                                                                                                                                                                                                                                        |
| [PaymentIntent](https://docs.stripe.com/api/payment_intents.md)                                                                        | Una forma de crear flujos de pago dinámicos. Un PaymentIntent hace un seguimiento del ciclo de vida del flujo del proceso compra del cliente y activa pasos adicionales de autenticación, si así lo exigen las disposiciones normativas, las reglas antifraude personalizadas de Radar o los métodos de pago con redireccionamiento. Las facturas crean PaymentIntents de forma automática.                                                       |
| [PaymentMethod](https://docs.stripe.com/api/payment_methods.md)                                                                        | Los métodos de pago que usa un cliente para pagar tus productos. Por ejemplo, puedes guardar una tarjeta de crédito en un objeto `Cuenta` o `Cliente` configurado por el cliente y usarla para hacer pagos recurrentes para ese cliente. Por lo general, se usa con las API Payment Intents o Setup Intents.                                                                                                                                      |
| [Precio](https://docs.stripe.com/api/prices.md)                                                                                        | Define el precio por unidad, la moneda y el ciclo de facturación para un producto.                                                                                                                                                                                                                                                                                                                                                                |
| [Producto](https://docs.stripe.com/api/products.md)                                                                                    | Un bien o servicio que vende tu empresa. Un producto de servicio puede incluir una o más funciones.                                                                                                                                                                                                                                                                                                                                               |
| [ProductFeature](https://docs.stripe.com/api/product-feature.md)                                                                       | Representa la inclusión de una sola funcionalidades en un solo producto. Cada producto está asociado a una ProductFeature para cada funcionalidad que incluye, y cada funcionalidad está asociada a una ProductFeature para cada producto que la incluye.                                                                                                                                                                                         |
| [Suscripción](https://docs.stripe.com/api/subscriptions.md)                                                                            | Representa la compra recurrente programada de un producto por parte de un cliente. Usa una suscripción para cobrar pagos y proporcionar entrega repetida o acceso continuo a un producto.                                                                                                                                                                                                                                                         |

Veamos un ejemplo de cómo funcionan juntos los productos, las funcionalidades y los derechos. Imagina que quieres configurar un servicio recurrente que ofrezca dos niveles: un producto estándar con funcionalidad básica y un producto avanzado que agregue funcionalidad extendida.

1. Creas dos funcionalidades: `basic_features` y `extended_features`.
1. Creas dos productos: `standard_product` y `advanced_product`.
1. Para el producto estándar, creas una ProductFeature que asocia `basic_features` con `standard_product`.
1. Para el producto avanzado, creas dos ProductFeatures: una que asocia `basic_features` con `advanced_product` y otra que asocia `extended_features` con `advanced_product`.

Un cliente, `first_customer`, se suscribe al producto estándar. Cuando creas la suscripción, Stripe crea automáticamente un derecho que asocia `first_customer` con `basic_features`.

Otro cliente, `second_customer`, se suscribe al producto avanzado. Al crear la suscripción, Stripe crea automáticamente dos derechos: uno que asocia `second_customer` con `basic_features` y otro que asocia `second_customer` con `extended_features`.

Puedes determinar qué funcionalidades aprovisionar para un cliente [recuperando sus derechos activos o recibiendo notificaciones del evento Resumen de derechos activos](https://docs.stripe.com/billing/entitlements.md#entitlements). No tienes que recuperar sus suscripciones, productos y funcionalidades.

## Configura Stripe

El [SDK para React Native](https://github.com/stripe/stripe-react-native) es de código abierto y está plenamente documentado. Internamente, utiliza SDK para [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 (según el 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, vaya al directorio **ios** y ejecute `pod install` para asegurarse de que también instala 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 agregar soporte para 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 usando 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 el desarrollo, y tus claves para [modo activo](https://docs.stripe.com/keys.md#test-live-modes) cuando publiques tu aplicación.

A continuación, instala la CLI de Stripe. La CLI proporciona pruebas de webhook y puedes ejecutarla para realizar llamadas API a Stripe. Esta guía muestra cómo utilizar la CLI para configurar un modelo de precios en una sección posterior.
Para obtener más opciones de instalación, consulta [Empezar a usar la CLI de Stripe](https://docs.stripe.com/stripe-cli.md).
## Crear el modelo de tarifas [CLI o Dashboard de Stripe]

Los [modelos de precios recurrentes](https://docs.stripe.com/products-prices/pricing-models.md) representan los productos o servicios que vendes, cuánto cuestan, qué monedas aceptas para los pagos y el período de servicio para las suscripciones. Para crear el modelo de precios, crea [productos](https://docs.stripe.com/api/products.md) (lo que vendes) y [precios](https://docs.stripe.com/api/prices.md) (cuánto cuestan y con qué frecuencia cobrar por los productos).

En este ejemplo, se utiliza una tarifa con tasa fija con dos opciones de niveles de servicio diferentes: básico y premium. Para cada opción de nivel de servicio, debes crear un producto y un precio recurrente. Si quieres agregar un cargo por única vez, como el costo de instalación, crea un tercer producto con un precio por única vez.

Cada producto se factura de forma mensual. El precio del producto básico es de 5 USD. El precio del producto premium es de 15 USD. Consulta la guía de [tarifas con tasa fija](https://docs.stripe.com/subscriptions/pricing-models/flat-rate-pricing.md) para ver un ejemplo con tres niveles.

#### Dashboard

Ve a la página [Agregar un producto](https://dashboard.stripe.com/test/products/create) y crea dos productos. Agrega un precio a cada producto, cada uno con un período de facturación mensual recurrente:

- Producto prémium: servicio prémium con más funcionalidades

  - Precio: Tarifa plana | 15 USD

- Producto básico: servicio básico con las funcionalidades mínimas

  - Precio: Tarifa plana | 5 USD

Después de crear los precios, registra los ID de precio para usarlos en otros pasos. Los ID de precio se ven así: `price_G0FvDp6vZvdwRZ`.

Cuando esté todo listo, usa el botón **Copiar en modo activo**, en la parte superior derecha de la página, para clonar el producto y pasarlo de [entorno de prueba a modo activo](https://docs.stripe.com/keys.md#test-live-modes).

#### API

Puedes usar la API para crear los [productos](https://docs.stripe.com/api/products.md) y los [precios](https://docs.stripe.com/api/prices.md).

Crear el producto premium:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Premium Service" \
  -d "description=Premium service with extra features"
```

Crear el producto básico:

```curl
curl https://api.stripe.com/v1/products \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "name=Billing Guide: Basic Service" \
  -d "description=Basic service with minimum features"
```

Registra el ID de cada producto. Se ve así:

```json
{
  "id": "prod_H94k5odtwJXMtQ",
  "object": "product",
  "active": true,
  "attributes": [

  ],
  "created": 1587577341,
  "description": "Premium service with extra features",
  "images": [

  ],
  "livemode": false,
  "metadata": {
  },
  "name": "Billing Guide: Premium Service",
  "statement_descriptor": null,
  "type": "service",
  "unit_label": null,
  "updated": 1587577341
}
```

Usa los ID de producto para crear el precio de cada producto. El número [unit_amount](https://docs.stripe.com/api/prices/object.md#price_object-unit_amount) está en centavos. Por ejemplo, `1500` = 15 USD.

Crear el precio superior:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{PREMIUM_PRODUCT_ID}} \
  -d unit_amount=1500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Crear el precio básico:

```curl
curl https://api.stripe.com/v1/prices \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d product={{BASIC_PRODUCT_ID}} \
  -d unit_amount=500 \
  -d currency=usd \
  -d "recurring[interval]=month"
```

Registra el ID de cada precio para poder utilizarlo en los pasos siguientes. Se ve así:

```json
{
  "id": "price_HGd7M3DV3IMXkC",
  "object": "price",
  "product": "prod_HGd6W1VUqqXGvr",
  "type": "recurring",
  "currency": "usd",
  "recurring": {
    "interval": "month",
    "interval_count": 1,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "active": true,
  "billing_scheme": "per_unit",
  "created": 1589319695,
  "livemode": false,
  "lookup_key": null,
  "metadata": {},
  "nickname": null,
  "unit_amount": 1500,
  "unit_amount_decimal": "1500",
  "tiers": null,
  "tiers_mode": null,
  "transform_quantity": null
}
```

## Crear el cliente [Cliente y servidor]

Stripe necesita un cliente para cada suscripción. En el front-end de tu solicitud, recopila toda la información necesaria de tus usuarios y envíala al back-end.

Si necesitas recopilar datos de la dirección, el Address Element te permite recopilar una dirección de envío o facturación para tus clientes. Para obtener más información sobre el Address Element, visita la página de [Address Element](https://docs.stripe.com/elements/address-element.md).

```javascript
import React from 'react';
import {View, TextInput, StyleSheet, Button, Platform} from 'react-native';

function RegisterView() {
  const [email, setEmail] = React.useState('');

  const createCustomer = async () => {
    const apiEndpoint =
      Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
    const response = await fetch(`${apiEndpoint}/create-customer`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email: email,
      }),
    });
    if (response.status === 200) {
      const customer = await response.json();
      console.log(customer);
    }
  };

  return (
    <View>
      <TextInput
        style={styles.input}
        placeholder="Email"
        value={email}
        onChangeText={setEmail}
      />
      <Button
        title="Register"
        onPress={async () => {
          await createCustomer();
        }}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  input: {
    height: 40,
    margin: 12,
    borderWidth: 1,
    padding: 10,
  },
});

export default RegisterView;
```

Crea el “Customer Object” de Stripe en el servidor.

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

#### Accounts v2

```curl
curl -X POST https://api.stripe.com/v2/core/accounts \
  -H "Authorization: Bearer <<YOUR_SECRET_KEY>>" \
  -H "Stripe-Version: 2026-03-25.preview" \
  --json '{
    "contact_email": "jenny.rosen@example.com",
    "display_name": "Jenny Rosen",
    "identity": {
        "individual": {
            "given_name": "Jenny Rosen",
            "address": {
                "city": "San Francisco",
                "country": "US",
                "line1": "123 Main Street",
                "postal_code": "94605",
                "state": "CA"
            }
        }
    },
    "configuration": {
        "customer": {
            "capabilities": {
                "automatic_indirect_tax": {
                    "requested": true
                }
            },
            "shipping": {
                "address": {
                    "city": "San Francisco",
                    "country": "US",
                    "line1": "123 Main Street",
                    "postal_code": "94605",
                    "state": "CA"
                }
            }
        }
    },
    "include": [
        "configuration.customer",
        "identity"
    ]
  }'
```

#### Customers v1

```curl
curl https://api.stripe.com/v1/customers \
  -u "<<YOUR_SECRET_KEY>>:" \
  --data-urlencode "email=jenny.rosen@example.com" \
  -d "name=Jenny Rosen" \
  -d "shipping[address][city]=San Francisco" \
  -d "shipping[address][country]=US" \
  -d "shipping[address][line1]=123 Main Street" \
  -d "shipping[address][postal_code]=9460" \
  -d "shipping[address][state]=CA" \
  -d "shipping[name]=Jenny Rosen" \
  -d "address[city]=San Francisco" \
  -d "address[country]=US" \
  -d "address[line1]=123 Main Street" \
  -d "address[postal_code]=9460" \
  -d "address[state]=CA"
```

## Crear la suscripción [Cliente y servidor]

> Si quieres procesar el Payment Element antes de crear una suscripción, consulta [Recopilar los datos de pago antes de crear un Intent](https://docs.stripe.com/payments/accept-a-payment-deferred.md?type=subscription).

Permite que tu nuevo cliente elija un plan y luego cree la suscripción. En esta guía, elegirá entre un plan Básico y un plan Prémium.

En tu aplicación, envía el ID de precio seleccionado y el ID del registro del cliente al back-end.

#### Accounts&nbsp;v2

```javascript
const createSubscription = async (priceId, customerAccountId) => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/create-subscription`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      priceId: priceId,
      customerAccountId: customerAccountId,
    }),
  });
  if (response.status === 200) {
    const subscription = await response.json();
    return subscription;
  }
};
```

#### Customers&nbsp;v1

```javascript
const createSubscription = async (priceId, customerId) => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/create-subscription`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      priceId: priceId,
      customerId: customerId,
    }),
  });
  if (response.status === 200) {
    const subscription = await response.json();
    return subscription;
  }
};
```

En el back-end, crea una suscripción con estado `incomplete` usando `payment_behavior=default_incomplete`. Luego, devuelve el `client_secret` desde el primer [payment intent](https://docs.stripe.com/payments/payment-intents.md) de la suscripción al front-end para completar el pago expandiendo el [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) en la factura más reciente de la suscripción.

Para habilitar el [comportamiento de suscripción mejorado](https://docs.stripe.com/billing/subscriptions/billing-mode.md), establece `billing_mode[type]` en `flexible`. Debes utilizar la versión de la API de Stripe [2025-06-30.basil](https://docs.stripe.com/changelog/basil.md#2025-06-30.basil) o posterior.

Establece [save_default_payment_method](https://docs.stripe.com/api/subscriptions/object.md#subscription_object-payment_settings-save_default_payment_method) en `on_subscription` para guardar el método de pago como predeterminado para una suscripción cuando un pago se realiza correctamente. Guardar un método de pago predeterminado aumenta la tasa de éxito de futuros pagos de suscripción.

En el siguiente ejemplo, se crea una `Subscription` y se expande el `confirmation_secret` de su última factura en la respuesta. Esto te permite pasar el secreto al front-end para confirmar el pago.

#### Accounts&nbsp;v2

```curl
curl https://api.stripe.com/v1/subscriptions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}" \
  -d "items[0][price]={{PRICE_ID}}" \
  -d payment_behavior=default_incomplete \
  -d "payment_settings[save_default_payment_method]=on_subscription" \
  -d "billing_mode[type]=flexible" \
  -d "expand[0]=latest_invoice.confirmation_secret"
```

#### Customers&nbsp;v1

```curl
curl https://api.stripe.com/v1/subscriptions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "customer={{CUSTOMER_ID}}" \
  -d "items[0][price]={{PRICE_ID}}" \
  -d payment_behavior=default_incomplete \
  -d "payment_settings[save_default_payment_method]=on_subscription" \
  -d "billing_mode[type]=flexible" \
  -d "expand[0]=latest_invoice.confirmation_secret"
```

> Si usas un *precio en múltiples monedas* (A single Price object can support multiple currencies. Each purchase uses one of the supported currencies for the Price, depending on how you use the Price in your integration), usa el parámetro [currency](https://docs.stripe.com/api/subscriptions/create.md#create_subscription-currency) para indicarle a la suscripción cuál de las monedas del precio debe usar. (Si omites el parámetro `currency`, la suscripción utilizará la moneda predeterminada del precio).

La suscripción ahora está `inactiva` y a la espera de pago. El ejemplo de respuesta que figura a continuación destaca los campos mínimos que deben almacenarse, pero puedes almacenar los campos a los que tu solicitud accede con frecuencia.

#### Accounts&nbsp;v2

```json
{"id": "sub_JgRjFjhKbtD2qz",
  "object": "subscription",
  "application_fee_percent": null,
  "automatic_tax": {
    "disabled_reason": null,
    "enabled": false,
    "liability": "null"
  },
  "billing_cycle_anchor": 1623873347,
  "billing_cycle_anchor_config": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "cancellation_details": {
    "comment": null,
    "feedback": null,
    "reason": null
  },
  "collection_method": "charge_automatically",
  "created": 1623873347,
  "currency": "usd","customer_account": identifier("customerAccount"),
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [

  ],
  "discounts": [],
  "ended_at": null,
  "invoice_customer_balance_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_JgRjmS4Ur1khEx",
        "object": "subscription_item",
        "created": 1623873347,"current_period_end": 1626465347,
        "current_period_start": 1623873347,
        "discounts": [],
        "metadata": {
        },
        "plan": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "plan",
          "active": true,
          "amount": 2000,
          "amount_decimal": "2000",
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "price": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 2000,
          "unit_amount_decimal": "2000"
        },
        "quantity": 1,
        "subscription": "sub_JgRjFjhKbtD2qz",
        "tax_rates": [

        ]
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz"
  },
  "latest_invoice": {
    "id": "in_1J34pzGPZ1iASj5zB87qdBNZ",
    "object": "invoice",
    "account_country": "US",
    "account_name": "Angelina's Store",
    "account_tax_ids": null,
    "amount_due": 2000,
    "amount_overpaid": 0,
    "amount_paid": 0,
    "amount_remaining": 2000,
    "amount_shipping": 0,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "disabled_reason": null,
      "enabled": false,
      "liability": null,
      "status": null
    },
    "automatically_finalizes_at": null,
    "billing_reason": "subscription_update",
    "collection_method": "charge_automatically",
    "created": 1623873347,
    "currency": "usd",
    "custom_fields": null,
    "customer_account": identifier("customerAccount"),
    "customer_address": null,
    "customer_email": "angelina@stripe.com",
    "customer_name": null,
    "customer_phone": null,
    "customer_shipping": {
      "address": {
        "city": "",
        "country": "US",
        "line1": "Berry",
        "line2": "",
        "postal_code": "",
        "state": ""
      },
      "name": "",
      "phone": null
    },
    "customer_tax_exempt": "none",
    "customer_tax_ids": [

    ],
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [

    ],
    "description": null,
    "discounts": [],
    "due_date": null,
    "effective_at": "1623873347",
    "ending_balance": 0,
    "footer": null,
    "from_invoice": null,
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp",
    "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf",
    "last_finalization_error": null,
    "latest_revision": null,
    "lines": {
      "object": "list",
      "data": [
        {
          "id": "il_1N2CjMBwKQ696a5NeOawRQP2",
          "object": "line_item",
          "amount": 2000,
          "currency": "usd",
          "description": "1 × Gold Special (at $20.00 / month)",
          "discount_amounts": [

          ],
          "discountable": true,
          "discounts": [

          ],
          "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
          "livemode": false,
          "metadata": {
          },
          "parent": {
            "invoice_item_details": null,
            "subscription_item_details":
            {
              "invoice_item": null,
            "proration": false,
            "proration_details":
            {
              "credited_items": null
            },
            "subscription":
            "sub_JgRjFjhKbtD2qz",
            "subscription_item":
              "si_JgRjmS4Ur1khEx"
            },
            "type": "subscription_item_details"
          },
          "period": {
            "end": 1626465347,
            "start": 1623873347
          },
          "plan": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "plan",
            "active": true,
            "amount": 2000,
            "amount_decimal": "2000",
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "price": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "recurring": {
              "interval": "month",
              "interval_count": 1,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 2000,
            "unit_amount_decimal": "2000"
          },
          "quantity": 1,
          "taxes": []
        }
      ],
      "has_more": false,
      "total_count": 1,
      "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines"
    },
    "livemode": false,
    "metadata": {
    },
    "next_payment_attempt": null,
    "number": "C008FC2-0354",
    "on_behalf_of": null,
    "parent": {
      "quote_details": null,
      "subscription_details": {
        "metadata": {},
        "pause_collection": null,
        "subscription": "sub_JgRjFjhKbtD2qz"
      }
    },
    "payment_intent": {
      "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6"
      },
      "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu",
      "confirmation_method": "automatic",
      "created": 1623873347,
      "currency": "usd",
      "customer": "cus_CMqDWO2xODTZqt",
      "description": "Subscription creation",
      "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
      "last_payment_error": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "receipt_email": null,
      "review": null,
      "setup_future_usage": "off_session",
      "shipping": null,
      "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ",
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_confirmation",
      "transfer_data": null,
      "transfer_group": null
    },
    "payment_settings": {
      "payment_method_options": null,
      "payment_method_types": null,
      "save_default_payment_method": "on_subscription"
    },
    "period_end": 1623873347,
    "period_start": 1623873347,
    "post_payment_credit_notes_amount": 0,
    "pre_payment_credit_notes_amount": 0,
    "receipt_number": null,
    "starting_balance": 0,
    "statement_descriptor": null,
    "status": "open",
    "status_transitions": {
      "finalized_at": 1623873347,
      "marked_uncollectible_at": null,
      "paid_at": null,
      "voided_at": null
    },
    "subscription": "sub_JgRjFjhKbtD2qz",
    "subtotal": 2000,
    "tax": null,
    "tax_percent": null,
    "total": 2000,
    "total_discount_amounts": [],
    "total_tax_amounts": [],
    "transfer_data": null,
    "webhooks_delivered_at": 1623873347
  },
  "livemode": false,
  "metadata": {
  },
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "plan": {
    "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
    "object": "plan",
    "active": true,
    "amount": 2000,
    "amount_decimal": "2000",
    "billing_scheme": "per_unit",
    "created": 1623864151,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "nickname": null,
    "product": "prod_JgPF5xnq7qBun3",
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "schedule": null,
  "start": 1623873347,
  "start_date": 1623873347,
  "status": "incomplete",
  "tax_percent": null,
  "transfer_data": null,
  "trial_end": null,
  "trial_start": null
}
```

#### Customers&nbsp;v1

```json
{"id": "sub_JgRjFjhKbtD2qz",
  "object": "subscription",
  "application_fee_percent": null,
  "automatic_tax": {
    "disabled_reason": null,
    "enabled": false,
    "liability": "null"
  },
  "billing_cycle_anchor": 1623873347,
  "billing_cycle_anchor_config": null,
  "cancel_at": null,
  "cancel_at_period_end": false,
  "canceled_at": null,
  "cancellation_details": {
    "comment": null,
    "feedback": null,
    "reason": null
  },
  "collection_method": "charge_automatically",
  "created": 1623873347,
  "currency": "usd","customer": identifier("customer"),
  "days_until_due": null,
  "default_payment_method": null,
  "default_source": null,
  "default_tax_rates": [

  ],
  "discounts": [],
  "ended_at": null,
  "invoice_customer_balance_settings": {
    "account_tax_ids": null,
    "issuer": {
      "type": "self"
    }
  },
  "items": {
    "object": "list",
    "data": [
      {
        "id": "si_JgRjmS4Ur1khEx",
        "object": "subscription_item",
        "created": 1623873347,"current_period_end": 1626465347,
        "current_period_start": 1623873347,
        "discounts": [],
        "metadata": {
        },
        "plan": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "plan",
          "active": true,
          "amount": 2000,
          "amount_decimal": "2000",
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "interval": "month",
          "interval_count": 1,
          "livemode": false,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "tiers": null,
          "tiers_mode": null,
          "transform_usage": null,
          "trial_period_days": null,
          "usage_type": "licensed"
        },
        "price": {
          "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
          "object": "price",
          "active": true,
          "billing_scheme": "per_unit",
          "created": 1623864151,
          "currency": "usd",
          "livemode": false,
          "lookup_key": null,
          "metadata": {
          },
          "nickname": null,
          "product": "prod_JgPF5xnq7qBun3",
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "tiers_mode": null,
          "transform_quantity": null,
          "type": "recurring",
          "unit_amount": 2000,
          "unit_amount_decimal": "2000"
        },
        "quantity": 1,
        "subscription": "sub_JgRjFjhKbtD2qz",
        "tax_rates": [

        ]
      }
    ],
    "has_more": false,
    "total_count": 1,
    "url": "/v1/subscription_items?subscription=sub_JgRjFjhKbtD2qz"
  },
  "latest_invoice": {
    "id": "in_1J34pzGPZ1iASj5zB87qdBNZ",
    "object": "invoice",
    "account_country": "US",
    "account_name": "Angelina's Store",
    "account_tax_ids": null,
    "amount_due": 2000,
    "amount_overpaid": 0,
    "amount_paid": 0,
    "amount_remaining": 2000,
    "amount_shipping": 0,
    "attempt_count": 0,
    "attempted": false,
    "auto_advance": false,
    "automatic_tax": {
      "disabled_reason": null,
      "enabled": false,
      "liability": null,
      "status": null
    },
    "automatically_finalizes_at": null,
    "billing_reason": "subscription_update",
    "collection_method": "charge_automatically",
    "created": 1623873347,
    "currency": "usd",
    "custom_fields": null,
    "customer": identifier("customer"),
    "customer_address": null,
    "customer_email": "angelina@stripe.com",
    "customer_name": null,
    "customer_phone": null,
    "customer_shipping": {
      "address": {
        "city": "",
        "country": "US",
        "line1": "Berry",
        "line2": "",
        "postal_code": "",
        "state": ""
      },
      "name": "",
      "phone": null
    },
    "customer_tax_exempt": "none",
    "customer_tax_ids": [

    ],
    "default_payment_method": null,
    "default_source": null,
    "default_tax_rates": [

    ],
    "description": null,
    "discounts": [],
    "due_date": null,
    "effective_at": "1623873347",
    "ending_balance": 0,
    "footer": null,
    "from_invoice": null,
    "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp",
    "invoice_pdf": "https://pay.stripe.com/invoice/acct_1By64KGPZ1iASj5z/invst_JgRjzIOILGeq2MKC9T0KtyXnD5udsLp/pdf",
    "last_finalization_error": null,
    "latest_revision": null,
    "lines": {
      "object": "list",
      "data": [
        {
          "id": "il_1N2CjMBwKQ696a5NeOawRQP2",
          "object": "line_item",
          "amount": 2000,
          "currency": "usd",
          "description": "1 × Gold Special (at $20.00 / month)",
          "discount_amounts": [

          ],
          "discountable": true,
          "discounts": [

          ],
          "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
          "livemode": false,
          "metadata": {
          },
          "parent": {
            "invoice_item_details": null,
            "subscription_item_details":
            {
              "invoice_item": null,
            "proration": false,
            "proration_details":
            {
              "credited_items": null
            },
            "subscription":
            "sub_JgRjFjhKbtD2qz",
            "subscription_item":
              "si_JgRjmS4Ur1khEx"
            },
            "type": "subscription_item_details"
          },
          "period": {
            "end": 1626465347,
            "start": 1623873347
          },
          "plan": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "plan",
            "active": true,
            "amount": 2000,
            "amount_decimal": "2000",
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "interval": "month",
            "interval_count": 1,
            "livemode": false,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "tiers": null,
            "tiers_mode": null,
            "transform_usage": null,
            "trial_period_days": null,
            "usage_type": "licensed"
          },
          "price": {
            "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
            "object": "price",
            "active": true,
            "billing_scheme": "per_unit",
            "created": 1623864151,
            "currency": "usd",
            "livemode": false,
            "lookup_key": null,
            "metadata": {
            },
            "nickname": null,
            "product": "prod_JgPF5xnq7qBun3",
            "recurring": {
              "interval": "month",
              "interval_count": 1,
              "trial_period_days": null,
              "usage_type": "licensed"
            },
            "tiers_mode": null,
            "transform_quantity": null,
            "type": "recurring",
            "unit_amount": 2000,
            "unit_amount_decimal": "2000"
          },
          "quantity": 1,
          "taxes": []
        }
      ],
      "has_more": false,
      "total_count": 1,
      "url": "/v1/invoices/in_1J34pzGPZ1iASj5zB87qdBNZ/lines"
    },
    "livemode": false,
    "metadata": {
    },
    "next_payment_attempt": null,
    "number": "C008FC2-0354",
    "on_behalf_of": null,
    "parent": {
      "quote_details": null,
      "subscription_details": {
        "metadata": {},
        "pause_collection": null,
        "subscription": "sub_JgRjFjhKbtD2qz"
      }
    },
    "payment_intent": {
      "id": "pi_1J34pzGPZ1iASj5zI2nOAaE6",
      "object": "payment_intent",
      "allowed_source_types": [
        "card"
      ],
      "amount": 2000,
      "amount_capturable": 0,
      "amount_received": 0,
      "application": null,
      "application_fee_amount": null,
      "canceled_at": null,
      "cancellation_reason": null,
      "capture_method": "automatic",
      "charges": {
        "object": "list",
        "data": [

        ],
        "has_more": false,
        "total_count": 0,
        "url": "/v1/charges?payment_intent=pi_1J34pzGPZ1iASj5zI2nOAaE6"
      },
      "client_secret": "pi_1J34pzGPZ1iASj5zI2nOAaE6_secret_l7FN6ldFfXiFmJEumenJ2y2wu",
      "confirmation_method": "automatic",
      "created": 1623873347,
      "currency": "usd",
      "customer": "cus_CMqDWO2xODTZqt",
      "description": "Subscription creation",
      "invoice": "in_1J34pzGPZ1iASj5zB87qdBNZ",
      "last_payment_error": null,
      "livemode": false,
      "metadata": {
      },
      "next_action": null,
      "next_source_action": null,
      "on_behalf_of": null,
      "payment_method": null,
      "payment_method_options": {
        "card": {
          "installments": null,
          "network": null,
          "request_three_d_secure": "automatic"
        }
      },
      "payment_method_types": [
        "card"
      ],
      "receipt_email": null,
      "review": null,
      "setup_future_usage": "off_session",
      "shipping": null,
      "source": "card_1By6iQGPZ1iASj5z7ijKBnXJ",
      "statement_descriptor": null,
      "statement_descriptor_suffix": null,
      "status": "requires_confirmation",
      "transfer_data": null,
      "transfer_group": null
    },
    "payment_settings": {
      "payment_method_options": null,
      "payment_method_types": null,
      "save_default_payment_method": "on_subscription"
    },
    "period_end": 1623873347,
    "period_start": 1623873347,
    "post_payment_credit_notes_amount": 0,
    "pre_payment_credit_notes_amount": 0,
    "receipt_number": null,
    "starting_balance": 0,
    "statement_descriptor": null,
    "status": "open",
    "status_transitions": {
      "finalized_at": 1623873347,
      "marked_uncollectible_at": null,
      "paid_at": null,
      "voided_at": null
    },
    "subscription": "sub_JgRjFjhKbtD2qz",
    "subtotal": 2000,
    "tax": null,
    "tax_percent": null,
    "total": 2000,
    "total_discount_amounts": [],
    "total_tax_amounts": [],
    "transfer_data": null,
    "webhooks_delivered_at": 1623873347
  },
  "livemode": false,
  "metadata": {
  },
  "next_pending_invoice_item_invoice": null,
  "pause_collection": null,
  "pending_invoice_item_interval": null,
  "pending_setup_intent": null,
  "pending_update": null,
  "plan": {
    "id": "price_1J32RfGPZ1iASj5zHHp57z7C",
    "object": "plan",
    "active": true,
    "amount": 2000,
    "amount_decimal": "2000",
    "billing_scheme": "per_unit",
    "created": 1623864151,
    "currency": "usd",
    "interval": "month",
    "interval_count": 1,
    "livemode": false,
    "metadata": {
    },
    "nickname": null,
    "product": "prod_JgPF5xnq7qBun3",
    "tiers": null,
    "tiers_mode": null,
    "transform_usage": null,
    "trial_period_days": null,
    "usage_type": "licensed"
  },
  "quantity": 1,
  "schedule": null,
  "start": 1623873347,
  "start_date": 1623873347,
  "status": "incomplete",
  "tax_percent": null,
  "transfer_data": null,
  "trial_end": null,
  "trial_start": null
}
```

### Actualiza el punto de conexión del servidor

Agrega la creación de claves efímeras al punto de conexión de la suscripción y devuélvela en la respuesta:

#### Accounts&nbsp;v2

#### Ruby

```ruby
ephemeral_key = Stripe::EphemeralKey.create(
  {customer_account: customer_account_id},
  {stripe_version: '2026-03-25.dahlia'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerAccountId: customer_account_id,
}.to_json
```

#### Customers&nbsp;v1

#### Ruby

```ruby
ephemeral_key = client.v1.ephemeral_keys.create(
  {customer: customer_id},
  {stripe_version: '2025-06-30.basil'}
)

{
  subscriptionId: subscription.id,
  clientSecret: subscription.latest_invoice.confirmation_secret.client_secret,
  ephemeralKey: ephemeral_key.secret,
  customerId: customer_id,
}.to_json
```

### Actualiza tu modelo de respuesta

#### Accounts&nbsp;v2

```typescript
interface SubscriptionsResponse {
  subscriptionId: string;
  clientSecret: string;
  ephemeralKey: string;
  customerAccountId: string;
}
```

#### Customers&nbsp;v1

```typescript
interface SubscriptionsResponse {
  subscriptionId: string;
  clientSecret: string;
  ephemeralKey: string;
  customerId: string;
}
```

### Pasar la configuración del cliente a PaymentSheet

#### Accounts&nbsp;v2

Agrega los siguientes parámetros al inicializar PaymentSheet:

```javascript
await initPaymentSheet({
  paymentIntentClientSecret: clientSecret,
  customerAccountId: customerAccountId,
  customerEphemeralKeySecret: ephemeralKey,
  // ... other parameters
});
```

#### Customers&nbsp;v1

Agrega los siguientes parámetros al inicializar PaymentSheet:

```javascript
await initPaymentSheet({
  paymentIntentClientSecret: clientSecret,
  customerId: customerId,
  customerEphemeralKeySecret: ephemeralKey,
  // ... other parameters
});
```

## Recopilar datos de pago [Cliente]

Utiliza [Payment Sheet](https://docs.stripe.com/payments/mobile/payment-sheet.md) para recolectar detalles del pago y activar la suscripción. Puedes personalizar Elements para que coincida con la apariencia de tu solicitud.

Payment Sheet recopila de forma segura todos los detalles de pago necesarios para una amplia variedad de métodos de pago. Más información sobre los [métodos de pago admitidos](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#product-support) para Payment Sheet y Subscriptions.

### Agregar el Payment Element a tu aplicación

> Este paso muestra una forma de empezar, pero puedes usar cualquier [integración de pagos dentro de la aplicación](https://docs.stripe.com/payments/mobile.md).

Inicializa y presenta el Payment Element móvil usando la clase PaymentSheet.

```javascript
import React from 'react';
import {useStripe, PaymentSheetError} from '@stripe/stripe-react-native';
import {View, Button} from 'react-native';

function SubscribeView({clientSecret}) {
  const {initPaymentSheet, presentPaymentSheet} = useStripe();

  React.useEffect(() => {
    const initializePaymentSheet = async () => {
      const {error} = await initPaymentSheet({
        paymentIntentClientSecret: clientSecret,
        returnURL: 'stripe-example://payment-sheet',
        // Set `allowsDelayedPaymentMethods` to true if your business handles
        // delayed notification payment methods like US bank accounts.
        allowsDelayedPaymentMethods: true,
      });
      if (error) {
        // Handle error
      }
    };

    initializePaymentSheet();
  }, [clientSecret, initPaymentSheet]);

  return (
    <View>
      <Button
        title="Subscribe"
        onPress={async () => {
          const {error} = await presentPaymentSheet();
          if (error) {
            if (error.code === PaymentSheetError.Failed) {
              // Handle failed
            } else if (error.code === PaymentSheetError.Canceled) {
              // Handle canceled
            }
          } else {
            // Payment succeeded
          }
        }}
      />
    </View>
  );
}

export default SubscribeView;
```

El Payment Element móvil renderiza una hoja que le permite a tu cliente seleccionar un método de pago. El formulario recopila automáticamente todos los datos de pago necesarios para el método de pago que elijan.

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

Puedes personalizar el Payment Element para que coincida con el diseño de tu aplicación usando la [propiedad `appearance`](https://docs.stripe.com/elements/appearance-api/mobile.md?platform=ios) de tu objeto `PaymentSheet.Configuration`.

### Confirmar pago

El Payment Element móvil crea un PaymentMethod y confirma que el primer PaymentIntent de la suscripción está incompleto, lo que genera un cargo. Si se requiere *autenticación reforzada de clientes* (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) (SCA) para el pago, el Payment Element se encarga del proceso de autenticación antes de confirmar el PaymentIntent.

## Configurar 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), proporciona una forma de regresar automáticamente a tu aplicación. Muchos tipos de métodos de pago *requieren* una URL de retorno. Si no la proporcionas, no podemos presentarles a tus usuarios métodos de pago que requieran una URL de retorno, incluso si los habilitaste.

Para proporcionar una URL de retorno:

1. [Registra](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app#Register-your-URL-scheme) una URL personalizada. No se admiten vínculos universales.
1. [Configura](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, al llamar al método `initPaymentSheet`, debes especificar `returnURL`:

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

Para obtener más información sobre esquemas 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).

## Optional: Habilitar Apple Pay

### Inscribirse para obtener un ID de comerciante Apple

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

Completa el formulario con una descripción y el identificador. La descripción es para tus registros y se puede modificar en el futuro. Stripe recomienda usar el nombre de tu aplicación como identificador (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 **Agregar nueva aplicación** y sigue la guía.

Descarga un archivo de solicitud 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 exactamente un certificado. 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 una nueva CSR y un nuevo certificado.

### Integrarse con Xcode

Agrega la funcionalidad Apple Pay a tu aplicación. En Xcode, abre la configuración del proyecto, selecciona la pestaña **Firma y funcionalidades** y agrega la funcionalidad **Apple Pay**. En este paso, quizá se te solicite iniciar 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)

Habilitar la funcionalidad Apple Pay en Xcode

### Agregar Apple Pay

#### Pagos recurrentes

Cuando accedes a `initPaymentSheet`, introduce los [parámetros de Apple Pay](https://stripe.dev/stripe-react-native/api-reference/modules/PaymentSheet.html#ApplePayParams) con `merchantCountryCode` establecido en el código de país de tu empresa.

De acuerdo con las [pautas de Apple](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) para pagos recurrentes, también debes establecer un `cardItem` que incluya un [RecurringCartSummaryItem](https://stripe.dev/stripe-react-native/api-reference/modules/ApplePay.html#RecurringCartSummaryItem) con el importe que pretendes cobrar (por ejemplo, “USD&nbsp;59.95 al mes”).

También puedes adoptar [tokens de comerciante](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 PassKit de Apple](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 agregar información [de seguimiento de pedidos](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) en iOS 16 o posterior, configura una función de de llamada`setOrderTracking`. Stripe llama a tu implementación después de que se complete el pago, pero antes de que iOS descarte la hoja de Apple Pay.

En su implementación de la función de devolución de llamada `setOrderTracking`, obtén los detalles del pedido de tu servidor para el pedido completado y transfiere los datos a la función de `completion` proporcionada.

Para obtener más información sobre el seguimiento de pedidos, consulta la [documentación sobre pedidos de billetera de Apple](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);
      }
    },
  },
});
```

## Escuchar webhooks [Servidor]

Para completar la integración, tienes que procesar los *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) que envió Stripe. Estos son eventos que se originan cada vez que un estado dentro de Stripe cambia, por ejemplo, cuando las suscripciones crean facturas nuevas. En tu aplicación, configura un controlador de HTTP para aceptar una solicitud POST que contenga el evento de webhook y verifica la firma del evento:

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/webhook' do
  # You can use webhooks to receive information about asynchronous payment events.
  # For more about our webhook events check out https://stripe.com/docs/webhooks.
  webhook_secret = ENV['STRIPE_WEBHOOK_SECRET']
  payload = request.body.read
  if !webhook_secret.empty?
    # Retrieve the event by verifying the signature using the raw body and secret if webhook signing is configured.
    sig_header = request.env['HTTP_STRIPE_SIGNATURE']
    event = nil

    begin
      event = Stripe::Webhook.construct_event(
        payload, sig_header, webhook_secret
      )
    rescue JSON::ParserError => e
      # Invalid payload
      status 400
      return
    rescue Stripe::SignatureVerificationError => e
      # Invalid signature
      puts '⚠️  Webhook signature verification failed.'
      status 400
      return
    end
  else
    data = JSON.parse(payload, symbolize_names: true)
    event = Stripe::Event.construct_from(data)
  end
  # Get the type of webhook event sent - used to check the status of PaymentIntents.
  event_type = event['type']
  data = event['data']
  data_object = data['object']

  if event_type == 'invoice.paid'
    # Used to provision services after the trial has ended.
    # The status of the invoice will show up as paid. Store the status in your
    # database to reference when a user accesses your service to avoid hitting rate
    # limits.
    # puts data_object
  end

  if event_type == 'invoice.payment_failed'
    # If the payment fails or the customer does not have a valid payment method,
    # an invoice.payment_failed event is sent, the subscription becomes past_due.
    # Use this webhook to notify your user that their payment has
    # failed and to retrieve new card details.
    # puts data_object
  end

  if event_type == 'customer.subscription.deleted'
    # handle subscription canceled automatically based
    # upon your subscription settings. Or if the user cancels it.
    # puts data_object
  end

  content_type 'application/json'
  { status: 'success' }.to_json
end
```

Durante el desarrollo, usa la CLI de Stripe para [observar los webhooks y reenviarlos a tu aplicación](https://docs.stripe.com/webhooks.md#test-webhook). Ejecuta lo siguiente en una nueva terminal mientras tu aplicación de desarrollo está funcionando:

#### curl

```bash
  stripe listen --forward-to localhost:4242/webhook
```

Para la producción, configura una URL de punto de conexión de webhook en el Dashboard o utiliza la [API Webhook Endpoints](https://docs.stripe.com/api/webhook_endpoints.md).

Necesita escuchar algunos eventos para completar los pasos restantes de esta guía. Consulte [Eventos de suscripción](https://docs.stripe.com/billing/subscriptions/webhooks.md#events) para más detalles sobre los webhooks específicos de suscripción.

## Brindar acceso a tu servicio [Cliente y servidor]

Ahora que la suscripción está activa, dale a tu usuario acceso a tu servicio. Para ello, escucha los eventos `customer.subscription.created`, `customer.subscription.updated`, y `customer.subscription.deleted`. Estos eventos pasan un objeto Subscription que contiene un campo `status` que indica si la suscripción está activa, vencida o cancelada. Consulta [el ciclo de vida de la suscripción](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle) para obtener una lista completa de estados.

En tu controlador de webhook:

1. Verifica el estado de la suscripción. Si es `activo`, entonces tu usuario ha pagado por su producto.
1. Revisa el producto al que se suscribió el cliente y bríndale acceso al servicio. Es mejor revisar el producto que el precio porque te da más flexibilidad en caso de que necesites cambiar la tarifa o el intervalo de facturación.
1. Almacena el `product.id`, `subscription.id` y el `subscription.status` en tu base de datos junto con `customer.id` que ya guardaste. Consulta este registro cuando tengas que determinar qué funcionalidades habilitar para el usuario en tu aplicación.

El estado de la suscripción puede cambiar en cualquier momento de su ciclo de vida, incluso si tu solicitud no hace ninguna llamada directa a Stripe. Por ejemplo, se puede producir un error de renovación debido a una tarjeta de crédito vencida, lo que genera que el estado de la suscripción pase a vencido. O, si usas el [portal de clientes](https://docs.stripe.com/customer-management.md), un usuario puede optar por cancelar la suscripción sin ingresar a tu aplicación directamente. El uso correcto del controlador mantiene el estado de tu solicitud sincronizado con Stripe.

## Cancelar la suscripción [Cliente y servidor]

Con frecuencia, se les permite a los clientes cancelar su suscripción. En este ejemplo, se agrega la opción de cancelación en la página de configuración de la cuenta.

En este ejemplo, el ID de la suscripción se recopila en el front-end, pero tu aplicación puede obtener esta información de tu base de datos para el usuario que ha iniciado sesión.
![Modelo de interfaz de cancelación de suscripciones.](https://b.stripecdn.com/docs-statics-srv/assets/fixed-price-subscriptions-guide-account-settings.6559626ba4b434826a67abfea165e097.png)

Configuración de la cuenta con la posibilidad de cancelar la suscripción

```javascript
const cancelSubscription = async subscriptionId => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/cancel-subscription`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
    }),
  });
  if (response.status === 200) {
    const subscription = await response.json();
    return subscription;
  }
};
```

En el back-end, define el punto de conexión para que la aplicación haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/cancel-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  deleted_subscription = client.v1.subscriptions.cancel(data['subscriptionId'])

  deleted_subscription.to_json
end
```

Tu back-end recibe un evento `customer.subscription.deleted`.

Una vez que se cancela la suscripción, actualiza tu base de datos para eliminar el ID de suscripción de Stripe que estaba almacenado y limitar el acceso al servicio.

Cuando una suscripción se cancela, no se puede reactivar. En su lugar, recopila información de facturación actualizada de tu cliente, actualiza su método de pago predeterminado y crea una nueva suscripción con su registro de cliente existente.

## Prueba tu integración

### Prueba métodos de pago

Usa la siguiente tabla para probar diferentes métodos y escenarios de pago.

| Método de pago      | Escenario                                                                                                                                                                                                                                                                                       | Cómo hacer la prueba                                                                                                                                                                         |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Débito directo BECS | Tu cliente paga correctamente con débito directo BECS.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `900123456` y BSB `000000`. El PaymentIntent confirmado pasa en un principio al estado `processing` y, tres minutos más tarde, a `succeeded`. |
| Débito directo BECS | El pago de tu cliente falla con un código de error `account_closed`.                                                                                                                                                                                                                            | Completa el formulario con el número de cuenta `111111113` y BSB `000000`.                                                                                                                   |
| Tarjeta de crédito  | El pago con tarjeta se efectúa correctamente y no requiere autenticación.                                                                                                                                                                                                                       | Completa el formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | El pago con tarjeta 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). | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0025 0000 3155` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Tarjeta de crédito  | La tarjeta es rechazada con el código `insufficient_funds`.                                                                                                                                                                                                                                     | Completa el formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y cualquier fecha de vencimiento, CVC y código postal.                                           |
| Débito directo SEPA | Tu cliente paga correctamente con débito directo SEPA.                                                                                                                                                                                                                                          | Completa el formulario con el número de cuenta `AT321904300235473204`. El PaymentIntent confirmado pasa inicialmente al estado “en proceso” y, tres minutos más tarde, a “completado”.       |
| Débito directo SEPA | El estado de PaymentIntent de tu cliente pasa de `processing` a `requires_payment_method`.                                                                                                                                                                                                      | Completa el formulario con el número de cuenta `AT861904300235473202`.                                                                                                                       |

### Supervisa eventos

Configura webhooks para recibir notificaciones de los eventos de cambios en las suscripciones, como actualizaciones y cancelaciones. Obtén más información sobre los [webhooks de suscripciones](https://docs.stripe.com/billing/subscriptions/webhooks.md). Puedes ver los eventos en el [Dashboard](https://dashboard.stripe.com/test/events) o con la [CLI de Stripe](https://docs.stripe.com/webhooks.md#test-webhook).

Para obtener más detalles, consulta [cómo probar tu integración con Billing](https://docs.stripe.com/billing/testing.md).

## Optional: Permitir que los clientes cambien de plan [Cliente y servidor]

Para permitirles a los clientes cambiar de suscripción, recopila el ID de precio de la opción a la que quieren pasar. A continuación, envía el nuevo ID de precio desde la aplicación a un punto de conexión del back-end. En este ejemplo, también se especifica el ID de suscripción, pero puedes recuperarlo de tu base de datos para el usuario que ha iniciado sesión.

```javascript
const updateSubscription = async (subscriptionId, priceId) => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/update-subscription`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
      newPriceId: priceId,
    }),
  });
  if (response.status === 200) {
    const subscription = await response.json();
    return subscription;
  }
};
```

En el back-end, define el punto de conexión para que el front-end haga la llamada especificando el ID de suscripción y el nuevo ID de precio. La suscripción ahora es Premium, a USD&nbsp;15 por mes, en lugar de Básica a USD&nbsp;5 por mes.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/update-subscription' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  updated_subscription =
    client.v1.subscriptions.update(
      data['subscriptionId'],
      cancel_at_period_end: false,
      items: [
        { id: subscription.items.data[0].id, price: data['newPriceId'] }
      ]
    )

  updated_subscription.to_json
end
```

En tu aplicación, se recibe un evento `customer.subscription.updated`.

## Optional: Previsualizar un cambio de precio [Cliente y servidor]

Cuando tu cliente cambia de suscripción, a menudo es necesario hacer un ajuste en el importe adeudado que se conoce como [prorrateo](https://docs.stripe.com/billing/subscriptions/prorations.md). Puedes usar el [punto de conexión de creación de la vista previa de facturas](https://docs.stripe.com/api/invoices/create_preview.md) para mostrarles a tus clientes el importe ajustado.

Desde la aplicación, pasa los datos de la vista previa de la factura a un punto de conexión del back-end.

```javascript
const createPreviewInvoice = async (subscriptionId, priceId, newPriceId) => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(`${apiEndpoint}/create-preview-invoice`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      subscriptionId: subscriptionId,
      priceId: priceId,
      newPriceId: newPriceId,
    }),
  });
  if (response.status === 200) {
    const invoice = await response.json();
    return invoice;
  }
};
```

En el back-end, define el punto de conexión para que el front-end haga la llamada.

#### Accounts&nbsp;v2

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = Stripe::Subscription.retrieve(data['subscriptionId'])

  invoice =
    Stripe::Invoice.create_preview(
      customer_account: data['customerAccountId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

#### Customers&nbsp;v1

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/create-preview-invoice' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  subscription = client.v1.subscriptions.retrieve(data['subscriptionId'])

  invoice =
    client.v1.invoices.create_preview(
      customer: data['customerId'],
      subscription: data['subscriptionId'],
      subscription_details: {
        items: [
          { id: subscription.items.data[0].id, deleted: true },
          { price: data['newPriceId'], deleted: false }
        ]
      }
    )

  invoice.to_json
end
```

## Optional: Mostrar el método de pago del cliente [Cliente y servidor]

Mostrar la marca y los últimos 4 dígitos de la tarjeta le permite al cliente saber qué tarjeta se está utilizando o si es necesario actualizar el método de pago.

Desde el front-end, pasa el ID del método de pago a un punto de conexión del back-end que recupere los datos del método de pago.

```javascript
const retrieveCustomerPaymentMethod = async paymentMethodId => {
  const apiEndpoint =
    Platform.OS === 'ios' ? 'http://localhost:4242' : 'http://10.0.2.2:4567';
  const response = await fetch(
    `${apiEndpoint}/retrieve-customer-payment-method`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        paymentMethodId: paymentMethodId,
      }),
    },
  );
  if (response.status === 200) {
    const paymentMethod = await response.json();
    return paymentMethod;
  }
};
```

En el back-end, define el punto de conexión para que la aplicación haga la llamada.

#### Ruby

```ruby

# Don't put any keys in code. See https://docs.stripe.com/keys-best-practices.
# Find your keys at https://dashboard.stripe.com/apikeys.
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/retrieve-customer-payment-method' do
  content_type 'application/json'
  data = JSON.parse request.body.read

  payment_method = client.v1.payment_methods.retrieve(data['paymentMethodId'])

  payment_method.to_json
end
```

Ejemplo de respuesta:

```json
{
  "id": "pm_1GcbHY2eZvKYlo2CoqlVxo42",
  "object": "payment_method",
  "billing_details": {
    "address": {
      "city": null,
      "country": null,
      "line1": null,
      "line2": null,
      "postal_code": null,
      "state": null
    },
    "email": null,
    "name": null,
    "phone": null
  },
  "card": {
    "brand": "visa",
    "checks": {
      "address_line1_check": null,
      "address_postal_code_check": null,
      "cvc_check": "pass"
    },
    "country": "US",
    "exp_month": 8,
    "exp_year": 2021,
    "fingerprint": "Xt5EWLLDS7FJjR1c",
    "funding": "credit",
    "generated_from": null,
    "last4": "4242",
    "three_d_secure_usage": {
      "supported": true
    },
    "wallet": null
  },
  "created": 1588010536,
  "customer": "cus_HAxB7dVQxhoKLh",
  "livemode": false,
  "metadata": {},
  "type": "card"
}
```

> Te recomendamos guardar `paymentMethod.id` y `last4` en tu base de datos, por ejemplo, `paymentMethod.id` como `stripeCustomerPaymentMethodId` en tu colección o tabla de `users`. Si lo necesitas, también tienes la opción de guardar `exp_month`, `exp_year`, `fingerprint` y `billing_details`. Esto sirve para limitar el número de llamadas a Stripe, tanto para mejorar el rendimiento como para evitar una posible limitación de la frecuencia.

## Cuéntales a tus clientes qué es Stripe

Stripe recopila información sobre las interacciones de los clientes con Elements para proporcionarte servicios, mejorarlos y prevenir el fraude. Esto incluye el uso de cookies y direcciones IP para identificar qué Elements vio un cliente durante una sola sesión de finalización de compra. Tienes la responsabilidad de divulgar y obtener todos los derechos y consentimientos necesarios para que Stripe use los datos para dichos fines. Si deseas obtener más información, visita nuestro [centro de privacidad](https://stripe.com/legal/privacy-center#as-a-business-user-what-notice-do-i-provide-to-my-end-customers-about-stripe).
