# Guarda el método de pago de un cliente cuando lo utilice para un pago

Aprende a guardar el método de pago del cliente cuando confirmes un PaymentIntent.

# Checkout Sessions API

> This is a Checkout Sessions API for when payment-ui is embedded-components. View the full page at https://docs.stripe.com/payments/save-during-payment?payment-ui=embedded-components.

Use the [Checkout Sessions API](https://docs.stripe.com/api/checkout/sessions.md) to save payment details during a purchase. This is useful for situations such as:

- Charging a customer for an e-commerce order and storing the payment details for future purchases.
- Initiating the first payment in a series of recurring payments.
- Charging a deposit and storing the payment details to charge the full amount later.

## Compliance

Eres responsable del cumplimiento de la normativa de todas las leyes, normativas y reglas de red aplicables cuando se guardan los datos de pago de un cliente para su uso futuro, como mostrarle el método de pago de un cliente en el flujo de compra para una compra futura o cobrarle cuando no esté usando activamente tu sitio web o aplicación. Antes de guardar o cobrar el método de pago de un cliente, asegúrate de lo siguiente:

- Agrega Condiciones a tu sitio web o aplicación que indiquen cómo planeas guardar los datos del método de pago, por ejemplo, lo siguiente:
  - El acuerdo del cliente para que puedas iniciar un pago o una serie de pagos en su nombre para transacciones específicas.
  - El momento y la frecuencia previstos de los pagos (por ejemplo, si los cargos son por cuotas programadas, pagos de suscripción o recargas no programadas).
  - Cómo determinas el importe de pago.
  - Tu política de cancelación, si el método de pago es para un servicio de suscripción.
- Usa un método de pago guardado solo para los fines indicados en tus Condiciones.
- Obtén el consentimiento explícito del cliente para este uso específico. Por ejemplo, incluye una casilla de verificación que indique «Guardar mi método de pago para usarlo en el futuro».
- Mantén un registro del acuerdo escrito de tu cliente con tus Condiciones.

> When using Elements with the Checkout Sessions API, only cards and ACH Direct Debit are supported for saved payment methods. You can’t save other payment methods, such as bank accounts.

## Prerequisites

1. Follow the Checkout guide to [accept a payment](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=checkout&ui=stripe-hosted).
1. Sigue esta guía para guardar el método de pago que se utilizó durante un pago, de modo que puedas recuperarlo y utilizarlo en futuros pagos del mismo cliente.

## Enable saved payment methods

> Las leyes internacionales sobre privacidad son complicadas y están llenas de matices. Antes de implementar la función de almacenamiento de los datos del método de pago del cliente, consulta con tu equipo legal para asegurarte de que cumpla con tu marco de privacidad y cumplimiento de la normativa.

A fin de permitir que un cliente guarde su método de pago para utilizarlo en el futuro, especifica el parámetro [saved_payment_method_options.payment_method_save](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_save) cuando crees la Checkout&nbsp;Session.

> #### 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).

Saving a payment method requires an object that represents your customer. This object can be a customer-configured [Account](https://docs.stripe.com/api/v2/core/accounts/object.md) if you use the Accounts v2 API, or a [Customer](https://docs.stripe.com/api/customers/object.md) if you use the Customers API. Pass an existing customer or create a new one by setting [customer_creation](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_creation) to `always` on the Checkout Session.

```curl
curl https://api.stripe.com/v1/checkout/sessions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "line_items[0][price]={{PRICE_ID}}" \
  -d "line_items[0][quantity]=2" \
  -d mode=payment \
  -d ui_mode=elements \
  -d customer_creation=always \
  -d "saved_payment_method_options[payment_method_save]=enabled"
```

Luego de crear la Checkout&nbsp;Session, utiliza el [secreto de cliente](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) devuelto en la respuesta para [crear tu página de confirmación de compra](https://docs.stripe.com/payments/quickstart-checkout-sessions.md).

> In the latest version of Stripe.js, specifying `enableSave` to `auto` is optional because that’s the default value when saved payment methods are enabled on the Checkout Session.

#### HTML + JS

The Payment Element automatically displays a consent collection checkbox when saved payment methods are enabled on the Checkout Session. You can explicitly configure this behavior using [elementsOptions](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions) on `initCheckoutElementsSdk`.

```javascript
const checkout = stripe.initCheckoutElementsSdk({
  clientSecret,
  elementsOptions: {savedPaymentMethod: {
      // Default is 'auto' in the latest version of Stripe.js - this configuration is optional
      enableSave: 'auto',
    }
  }
});
```

#### Reaccionar

The Payment Element automatically displays a consent collection checkbox when saved payment methods are enabled on the Checkout Session. You can explicitly configure this behavior using [elementsOptions](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions) on the `CheckoutElementsProvider`.

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

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

  return (
    <CheckoutElementsProvider
      stripe={stripe}
      options={{
        clientSecret,
        elementsOptions: {savedPaymentMethod: {
            // Default is 'auto' in the latest version of Stripe.js - this configuration is optional
            enableSave: 'auto',
          },
        },
      }}
    >
      <CheckoutForm />
    </CheckoutElementsProvider>
  );
};

export default App;
```

## Reutilizar un método de pago guardado anteriormente

Each saved payment method is linked to an object that represents your customer. This object can be a customer-configured [Account](https://docs.stripe.com/api/v2/core/accounts/object.md) if you use the Accounts v2 API, or a [Customer](https://docs.stripe.com/api/customers/object.md) if you use the Customers API. Before creating the Checkout Session, authenticate your customer, and pass the corresponding object ID to the Checkout Session.

> In the latest version of Stripe.js, `enableRedisplay` defaults to `auto` when saved payment methods are enabled on the Checkout Session.

The Payment Element automatically redisplays previously saved payment methods for your customer to use during checkout when saved payment methods are enabled on the Checkout Session.

#### Accounts v2

```curl
curl https://api.stripe.com/v1/checkout/sessions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "line_items[0][price]={{PRICE_ID}}" \
  -d "line_items[0][quantity]=2" \
  -d mode=payment \
  -d ui_mode=elements \
  -d "customer_account={{CUSTOMERACCOUNT_ID}}"
```

#### Customers v1

```curl
curl https://api.stripe.com/v1/checkout/sessions \
  -u "<<YOUR_SECRET_KEY>>:" \
  -d "line_items[0][price]={{PRICE_ID}}" \
  -d "line_items[0][quantity]=2" \
  -d mode=payment \
  -d ui_mode=elements \
  -d "customer={{CUSTOMER_ID}}"
```

#### HTML + JS

You can explicitly configure the redisplay behavior using [elementsOptions](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions) on `initCheckoutElementsSdk`.

```javascript
const checkout = stripe.initCheckoutElementsSdk({
  clientSecret,
  elementsOptions: {
    savedPaymentMethod: {
      // Default is 'auto' in the latest version of Stripe.js - this configuration is optional
      enableSave: 'auto',// Default is 'auto' in the latest version of Stripe.js - this configuration is optional
      enableRedisplay: 'auto',
    }
  }
});
```

#### Reaccionar

You can explicitly configure the redisplay behavior using [elementsOptions](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions) on the `CheckoutElementsProvider`.

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

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

  return (
    <CheckoutElementsProvider
      stripe={stripe}
      options={{
        clientSecret,
        elementsOptions: {
          savedPaymentMethod: {
            // Default is 'auto' in the latest version of Stripe.js - this configuration is optional
            enableSave: 'auto',// Default is 'auto' in the latest version of Stripe.js - this configuration is optional
            enableRedisplay: 'auto',
          }
        },
      }}
    >
      <CheckoutForm />
    </CheckoutElementsProvider>
  );
};

export default App;
```

## Optional: Build a saved payment method UI

#### HTML + JS

You can build your own saved payment method UI instead of using the built-in UI provided by the Payment Element.

To prevent the Payment Element from handling consent collection and displaying the previously saved payment methods, pass in additional [elementsOptions](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions) on `initCheckoutElementsSdk`.

```javascript
const checkout = stripe.initCheckoutElementsSdk({
  clientSecret,
  elementsOptions: {savedPaymentMethod: {
      enableSave: 'never',
      enableRedisplay: 'never',
    },
  }
});
```

#### Reaccionar

You can build your own saved payment method UI instead of using the built-in UI provided by the Payment Element. To prevent the Payment Element from handling consent collection and displaying the previously saved payment methods, pass in additional [elementsOptions](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions) on the `CheckoutElementsProvider`.

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

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

  return (
    <CheckoutElementsProvider
      stripe={stripe}
      options={{
        clientSecret,
        elementsOptions: {savedPaymentMethod: {
            enableSave: 'never',
            enableRedisplay: 'never',
          },
        },
      }}
    >
      <CheckoutForm />
    </CheckoutElementsProvider>
  );
};

export default App;
```

### Collect consent

> Las leyes internacionales sobre privacidad son complicadas y están llenas de matices. Antes de implementar la función de almacenamiento de los datos del método de pago del cliente, consulta con tu equipo legal para asegurarte de que cumpla con tu marco de privacidad y cumplimiento de la normativa.

In most cases, you must collect a customer’s consent before you save their payment method details. The following example shows how to obtain consent using a checkbox.

#### HTML + JS

```html
<label>
  <input type="checkbox" id="save-payment-method-checkbox" />
  Save my payment information for future purchases
</label>
<button id="pay-button">Pay</button>
<div id="confirm-errors"></div>
```

#### Reaccionar

```jsx
import React from 'react';

type Props = {
  savePaymentMethod: boolean;
  onSavePaymentMethodChange: (save: boolean) => void;
}
const ConsentCollection = (props: Props) => {
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    props.onSavePaymentMethodChange(e.target.checked);
  };
  return (
    <label>
      <input
        type="checkbox"
        checked={props.savePaymentMethod}
        onChange={handleChange}
      />
      Save my payment information for future purchases
    </label>
  );
};

export default ConsentCollection;
```

When you call [confirm](https://docs.stripe.com/js/custom_checkout/confirm), you can indicate to Stripe that your customer has provided consent by passing the `savePaymentMethod` parameter. When you save a customer’s payment details, you’re responsible for complying with all applicable laws, regulations, and network rules.

#### HTML + JS

```js
const checkout = stripe.initCheckoutElementsSdk({clientSecret});
const button = document.getElementById('pay-button');
const errors = document.getElementById('confirm-errors');
const checkbox = document.getElementById('save-payment-method-checkbox');
const loadActionsResult = await checkout.loadActions();
if (loadActionsResult.type === 'success') {
  const {actions} = loadActionsResult;
  button.addEventListener('click', () => {
    // Clear any validation errors
    errors.textContent = '';
const savePaymentMethod = checkbox.checked;
    actions.confirm({savePaymentMethod}).then((result) => {
      if (result.type === 'error') {
        errors.textContent = result.error.message;
      }
    });
  });
}
```

#### Reaccionar

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

type Props = {
  savePaymentMethod: boolean;
}
const PayButton = (props: Props) => {
  const checkoutState = useCheckout();
  const [loading, setLoading] = React.useState(false);
  const [error, setError] = React.useState(null);

  if (checkoutState.type === 'loading') {
    return (
      <div>Loading...</div>
    );
  } else if (checkoutState.type === 'error') {
    return (
      <div>Error: {checkoutState.error.message}</div>
    );
  }
  const {confirm} = checkoutState.checkout;
  const handleClick = () => {
    setLoading(true);confirm({savePaymentMethod: props.savePaymentMethod}).then((result) => {
      if (result.type === 'error') {
        setError(result.error)
      }
      setLoading(false);
    })
  };

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

export default PayButton;
```

### Render saved payment methods

Use the [savedPaymentMethods](https://docs.stripe.com/js/custom_checkout/session_object#custom_checkout_session_object-savedPaymentMethods) array on the front end to render the customer’s available payment methods.

> The `savedPaymentMethods` array includes only the payment methods that have [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay) set to `always`. Follow the steps for [collecting consent](https://docs.stripe.com/payments/save-during-payment.md#collect-consent) from your customer and make sure to properly set the `allow_redisplay` parameter.

#### HTML + JS

```html
<div id="saved-payment-methods"></div>
```

```js
const checkout = stripe.initCheckoutElementsSdk({clientSecret});
const loadActionsResult = await checkout.loadActions();
if (loadActionsResult.type === 'success') {
  const container = document.getElementById('saved-payment-methods');
  const {actions} = loadActionsResult;
  actions.getSession().savedPaymentMethods.forEach((pm) => {
    const label = document.createElement('label');
    const radio = document.createElement('input');

    radio.type = 'radio';
    radio.value = pm.id;

    label.appendChild(radio);
    label.appendChild(document.createTextNode(`Card ending in ${pm.card.last4}`));
    container.appendChild(label);
  });
}
```

#### Reaccionar

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

type Props = {
  selectedPaymentMethod: string | null;
  onSelectPaymentMethod: (paymentMethod: string) => void;
};
const PaymentMethods = (props: Props) => {const checkoutState = useCheckout();

  if (checkoutState.type === 'loading') {
    return (
      <div>Loading...</div>
    );
  } else if (checkoutState.type === 'error') {
    return (
      <div>Error: {checkoutState.error.message}</div>
    );
  }const {savedPaymentMethods} = checkoutState.checkout;

  const handleOptionChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    props.onSelectPaymentMethod(e.target.value);
  };

  return (
    <div>
      {savedPaymentMethods.map((pm) => (
        <label key={pm.id}>
          <input
            type="radio"
            value={pm.id}
            checked={props.selectedPaymentMethod === pm.id}
            onChange={handleOptionChange}
          />
          Card ending in {pm.card.last4}
        </label>
      ))}
    </div>
  );
};

export default PaymentMethods;
```

### Confirm with a saved payment method

When your customer selects a saved payment method and is ready to complete checkout, call [confirm](https://docs.stripe.com/js/custom_checkout/confirm) and pass in the [paymentMethod](https://docs.stripe.com/js/custom_checkout/confirm#custom_checkout_session_confirm-options-paymentMethod) ID.

#### HTML + JS

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

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

const loadActionsResult = await checkout.loadActions();
if (loadActionsResult.type === 'success') {
  const container = document.getElementById('saved-payment-methods');
  const {actions} = loadActionsResult;
  actions.getSession().savedPaymentMethods.forEach((pm) => {
    const label = document.createElement('label');
    const radio = document.createElement('input');

    radio.type = 'radio';
    radio.value = pm.id;

    label.appendChild(radio);
    label.appendChild(document.createTextNode(`Card ending in ${pm.card.last4}`));
    container.appendChild(label);
  });
}
```

#### Reaccionar

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

type Props = {
  selectedPaymentMethod: string | null;
}
const PayButton = (props: Props) => {
  const checkoutState = useCheckout();
  const [loading, setLoading] = React.useState(false);

  if (checkoutState.type === 'loading') {
    return (
      <div>Loading...</div>
    );
  } else if (checkoutState.type === 'error') {
    return (
      <div>Error: {checkoutState.error.message}</div>
    );
  }
  const {confirm} = checkoutState.checkout;

  const handleClick = () => {
    setLoading(true);confirm({paymentMethod: props.selectedPaymentMethod}).then((result) => {
      if (result.error) {
        // Confirmation failed. Display the error message.
      }
      setLoading(false);
    })
  };

  return (
    <button disabled={loading} onClick={handleClick}>
      Pay
    </button>
  )
};

export default PayButton;
```


# Payment Intents API

> This is a Payment Intents API for when payment-ui is elements. View the full page at https://docs.stripe.com/payments/save-during-payment?payment-ui=elements.

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

- Cóbrale al cliente un pedido de e-commerce y almacena los datos para compras futuras.
- Inicia el primer pago de una serie de pagos recurrentes.
- Cobra un depósito y almacena los datos para cobrar el importe total más tarde.

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

## Cumplimiento de la normativa

Eres responsable del cumplimiento de la normativa de todas las leyes, normativas y reglas de red aplicables cuando se guardan los datos de pago de un cliente para su uso futuro, como mostrarle el método de pago de un cliente en el flujo de compra para una compra futura o cobrarle cuando no esté usando activamente tu sitio web o aplicación. Antes de guardar o cobrar el método de pago de un cliente, asegúrate de lo siguiente:

- Agrega Condiciones a tu sitio web o aplicación que indiquen cómo planeas guardar los datos del método de pago, por ejemplo, lo siguiente:
  - El acuerdo del cliente para que puedas iniciar un pago o una serie de pagos en su nombre para transacciones específicas.
  - El momento y la frecuencia previstos de los pagos (por ejemplo, si los cargos son por cuotas programadas, pagos de suscripciones o recargas no programadas).
  - Cómo determinas el importe de pago.
  - Tu política de cancelación, si el método de pago es para un servicio por suscripción.
- Usa un método de pago guardado solo para los fines indicados en tus Condiciones.
- Obtén el consentimiento explícito del cliente para este uso específico. Por ejemplo, incluye una casilla de verificación que indique «Guardar mi método de pago para usarlo en el futuro».
- Mantén un registro del acuerdo escrito de tu cliente con tus Condiciones.

## Prerequisites

1. Follow the Payment Intents API guide to [accept a payment](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=elements&api-integration=paymentintents).
1. Sigue esta guía para guardar el método de pago que se utilizó durante un pago, de modo que puedas recuperarlo y utilizarlo en futuros pagos del mismo cliente.

## Save payment methods during payment [Lado del servidor]

Puedes configurar el Payment Element para guardar los métodos de pago de tu cliente para uso futuro. En esta sección, se muestra cómo integrar la [función de métodos de pago guardados](https://docs.stripe.com/payments/save-customer-payment-methods.md), que permite que el Payment Element realice lo siguiente:

- Solicitar a los compradores su consentimiento para guardar un método de pago
- Cómo guardar métodos de pago cuando los compradores brindan su consentimiento
- Cómo mostrar los métodos de pago guardados a los compradores para compras futuras
- [Actualizar automáticamente tarjetas perdidas o vencidas](https://docs.stripe.com/payments/cards/overview.md#automatic-card-updates) cuando los compradores las reemplacen
![El Payment Element y una casilla de verificación del método de pago guardado](https://b.stripecdn.com/docs-statics-srv/assets/spm-save.fe0b24afd0f0a06e0cf4eecb0ce2403a.png)

Guardar métodos de pago.
![El Payment Element con un método de pago guardado seleccionado](https://b.stripecdn.com/docs-statics-srv/assets/spm-saved.5dba5a8a190a9a0e9f1a99271bed3f4b.png)

Reutiliza un método de pago guardado previamente.

### Cómo habilitar la función para guardar el método de pago en el Payment Element

Al crear un [PaymentIntent](https://docs.stripe.com/api/payment_intents/.md) en tu servidor, crea también una [CustomerSession](https://docs.stripe.com/api/customer_sessions/.md) que proporcione el ID del cliente (usando `customer` para un objeto `Customer` o `customer_account` para un objeto `Account` configurado por el cliente) y habilitando el componente [payment_element](https://docs.stripe.com/api/customer_sessions/object.md#customer_session_object-components-payment_element) para tu sesión. Configura qué [funcionalidades](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components-payment_element-features) de métodos de pago guardados quieres habilitar. Por ejemplo, al habilitar [payment_method_save](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components-payment_element-features-payment_method_save), se muestra una casilla de verificación que ofrece a los clientes guardar sus datos de pago para su uso futuro.

Puedes especificar `setup_future_usage` en una PaymentIntent o sesión de Checkout para anular el comportamiento predeterminado para guardar métodos de pago. Esto garantiza que guardes automáticamente el método de pago para uso futuro, incluso si el cliente no elige guardarlo explícitamente. Si tienes la intención de especificar `setup_future_usage`, no establezcas `payment_method_save_usage` en la misma transacción porque esto causa un error de integración.

> #### 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&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-intent-and-customer-session' do
  intent = client.v1.payment_intents.create({
    amount: 1099,
    currency: 'usd',
    automatic_payment_methods: {enabled: true},
    customer_account: {{CUSTOMER_ACCOUNT_ID}},
  })
  customer_session = client.v1.customer_sessions.create({
    customer_account: {{CUSTOMER_ACCOUNT_ID}},
    components: {
      payment_element: {
          enabled: true,
          features: {
            payment_method_redisplay: 'enabled',
            payment_method_save: 'enabled',
            payment_method_save_usage: 'off_session',
            payment_method_remove: 'enabled',
          },
        },
    },
  })
  {
    client_secret: intent.client_secret,
    customer_session_client_secret: customer_session.client_secret
  }.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-intent-and-customer-session' do
  intent = client.v1.payment_intents.create({
    amount: 1099,
    currency: 'usd',
    # In the latest version of the API, specifying the `automatic_payment_methods` parameter
    # is optional because Stripe enables its functionality by default.
    automatic_payment_methods: {enabled: true},
    customer: {{CUSTOMER_ID}},
  })
  customer_session = client.v1.customer_sessions.create({
    customer: {{CUSTOMER_ID}},
    components: {
      payment_element: {
          enabled: true,
          features: {
            payment_method_redisplay: 'enabled',
            payment_method_save: 'enabled',
            payment_method_save_usage: 'off_session',
            payment_method_remove: 'enabled',
          },
        },
    },
  })
  {
    client_secret: intent.client_secret,
    customer_session_client_secret: customer_session.client_secret
  }.to_json
end
```

Tu instancia de Elements utiliza el *secreto de cliente* (A client secret is used with your publishable key to authenticate a request for a single object. Each client secret is unique to the object it's associated with) de CustomerSession para acceder a los métodos de pago guardados de ese cliente. [Gestiona errores](https://docs.stripe.com/error-handling.md) correctamente al crear la CustomerSession. Si se produce un error, no es necesario que proporciones el secreto de cliente de CustomerSession a la instancia de Elements, ya que es opcional.

Crea la instancia de Elements utilizando los secretos de cliente tanto para PaymentIntent como para CustomerSession. Luego, usa esta instancia de Elements para crear un Payment Element.

```javascript
// Create the CustomerSession and obtain its clientSecret
const res = await fetch("/create-intent-and-customer-session", {
  method: "POST"
});

const {
  customer_session_client_secret: customerSessionClientSecret
} = await res.json();

const elementsOptions = {
  clientSecret: '{{CLIENT_SECRET}}',customerSessionClientSecret,
  // Fully customizable with appearance API.
  appearance: {/*...*/},
};

// Set up Stripe.js and Elements to use in checkout form, passing the client secret
// and CustomerSession's client secret obtained in a previous step
const elements = stripe.elements(elementsOptions);

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

Al confirmar el PaymentIntent, Stripe.js controla automáticamente la configuración de [setup_future_usage](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-setup_future_usage) en el PaymentIntent y [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay) en el PaymentMethod, dependiendo de si el cliente marcó la casilla para guardar sus datos de pago.

### Exigir la recopilación del CVC

Opcionalmente, especifica `require_cvc_recollection` [al crear el PaymentIntent](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-card-require_cvc_recollection) para cumplir con la recopilación del CVC cuando un cliente está pagando con tarjeta.

### Cómo detectar la selección de un método de pago guardado

Para controlar el contenido dinámico cuando se selecciona un método de pago guardado, escucha el evento `change` del Payment Element, que se rellena con el método de pago seleccionado.

```javascript
paymentElement.on('change', function(event) {
  if (event.value.payment_method) {
    // Control dynamic content if a saved payment method is selected
  }
})
```

## Save only payment methods that support reuse [Lado del servidor]

You can’t make all payment methods [reusable](https://docs.stripe.com/payments/accept-a-payment.md#save-payment-method-details) by enabling `setup_future_usage` in the Payment Intent. See [Payment method support](https://docs.stripe.com/payments/payment-methods/payment-method-support.md#additional-api-supportability) to learn more about which payment methods are compatible with `setup_future_usage`.

Instead, you can save payment method details only when a customer selects a payment method that supports it. For example, if you accept both card payments and Giropay (which you can’t reuse), configure `setup_future_usage=off_session` on the `payment_method_options[card]` object.

Si el cliente rechaza que se guarden sus datos de pago, deshabilita `setup_future_usage` en el PaymentIntent en el lado del servidor. No admitimos este ajuste en el lado del cliente.

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

Puedes gestionar los métodos de pago desde el [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe maneja la devolución de métodos de pago elegibles en función de factores como el importe de la transacción, la moneda y el flujo de pago.

#### curl

```bash
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -d "amount"=1099 \
  -d "currency"="usd" \
  -d "automatic_payment_methods[enabled]"="true" \
  -d "payment_method_options[card][setup_future_usage]"="off_session"
```

#### Establecer métodos de pago manualmente

Como opción, puedes enumerar `card` y `giropay` usando [tipos de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_types) como en el siguiente ejemplo.

#### curl

```bash
curl https://api.stripe.com/v1/payment_intents \
  -u <<YOUR_SECRET_KEY>>: \
  -d "amount"=1099 \
  -d "currency"="usd" \
  -d "payment_method_types[]"="card" \
  -d "payment_method_types[]"="giropay" \
  -d "payment_method_options[card][setup_future_usage]"="off_session"
```

## Efectuar un cargo en el método de pago guardado más tarde [Lado del servidor]

> `bancontact`, `ideal` y `sofort` son, de forma predeterminada, métodos de pago únicos. Al configurar el consumo futuro, generan un tipo de método de pago `sepa_debit` reutilizable, por lo que debes usar `sepa_debit` para consultar los métodos de pago guardados.

> #### Cumplimiento de la normativa
> 
> Al guardar los datos de pago de un cliente, eres responsable del cumplimiento de todas las leyes, normativas y reglas de red aplicables. Cuando entregues métodos de pago anteriores a tu cliente final para futuras compras, asegúrate de incluir los métodos de pago para los que obtuviste el consentimiento del cliente para guardar los datos del método de pago para este uso futuro específico. Para diferenciar entre los métodos de pago adjuntos a los clientes que pueden y no pueden presentarse a tu cliente final como un método de pago guardado para futuras compras, usa el parámetro [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay).

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

> #### 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&nbsp;v2

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

#### Customers&nbsp;v1

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

Cuando tengas todo listo para aceptar pagos *fuera de la sesión* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information) de tu cliente, usa el ID del cliente y el ID del `PaymentMethod` para crear un `PaymentIntent` con el importe y las monedas del pago. Establece algunos otros parámetros con el fin de efectuar el pago fuera de la sesión:

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

#### Accounts&nbsp;v2

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

#### Customers&nbsp;v1

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

## Probar la integración

Usa datos de pago de prueba y la página de redireccionamiento de prueba para verificar tu integración. Haz click en las siguientes pestañas para ver los detalles de cada método de pago.

#### Tarjetas

| Método de pago     | Escenario                                                                                                                                                                                                                                                                                                                                | Cómo hacer la prueba                                                                                                                                    |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tarjeta de crédito | La configuración de la tarjeta se realiza correctamente y no requiere *autenticación* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase). | Completa nuestro formulario de tarjeta de crédito con el número de tarjeta `4242 4242 4242 4242` y la fecha de vencimiento, el CVC o el código postal.  |
| Tarjeta de crédito | La tarjeta requiere autenticación para la configuración inicial, pero no en los pagos sucesivos.                                                                                                                                                                                                                                         | Completa nuestro 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 requiere autenticación para la configuración inicial y también requiere autenticación para los pagos sucesivos.                                                                                                                                                                                                               | Completa nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0027 6000 3184` y cualquier fecha de vencimiento, CVC y código postal. |
| Tarjeta de crédito | La tarjeta es rechazada durante la configuración.                                                                                                                                                                                                                                                                                        | Completa nuestro formulario de tarjeta de crédito con el número de tarjeta `4000 0000 0000 9995` y la fecha de vencimiento, el CVC o el código postal.  |

#### Redireccionamientos bancarios

| Método de pago      | Escenario                                                                                                                                                 | Cómo hacer la prueba                                                                                                                                                         |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Bancontact          | Tu cliente configura correctamente un método de pago con débito directo SEPA para uso futuro con Bancontact.                                              | Usa cualquier nombre en el formulario de Bancontact y luego haz click en **Autorizar la configuración de prueba** en la página de redireccionamiento.                        |
| Bancontact          | Tu cliente no pasó la autenticación en la página de redireccionamiento de Bancontact.                                                                     | Usa cualquier nombre en el formulario de Bancontact y luego haz click en **Error en la configuración de prueba** en la página de redireccionamiento.                         |
| Débito directo BECS | Tu cliente paga correctamente con débito directo BECS.                                                                                                    | Completa el formulario con el número de cuenta `900123456`. El PaymentIntent confirmado pasa inicialmente 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`.                                                                                                                  |
| iDEAL               | Tu cliente configura correctamente un método de pago con [débito directo SEPA](https://docs.stripe.com/payments/sepa-debit.md) para uso futuro con iDEAL. | Usa cualquier nombre y banco en el formulario de iDEAL y luego haz click en **Autorizar configuración de prueba** en la página de redireccionamiento.                        |
| iDEAL               | Tu cliente no pasa la autenticación en la página de redireccionamiento de iDEAL.                                                                          | Selecciona cualquier banco y usa cualquier nombre en el formulario de iDEAL. Luego, haz click en **Error en la configuración de prueba** en la página de redireccionamiento. |

#### Débitos bancarios

| Método de pago      | Escenario                                                                                    | Cómo hacer la prueba                                                                                                                                                                   |
| ------------------- | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 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 del Payment Intent de tu cliente pasa de `processing` a `requires_payment_method`. | Completa el formulario con el número de cuenta `AT861904300235473202`.                                                                                                                 |

### Prueba de cargo a un PaymentMethod de débito SEPA guardado

La confirmación del PaymentIntent  usando iDEAL, Bancontact o Sofort genera un *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) con [débito directo SEPA](https://docs.stripe.com/payments/sepa-debit.md). El débito directo SEPA es un método de pago de [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification) que pasa a un estado `processing` intermedio antes de pasar a un estado `succeeded` o `requires_payment_method` varios días después.

#### Correo electrónico

Define `payment_method.billing_details.email` con uno de los siguientes valores para probar las transiciones de estado del `PaymentIntent`. Puedes incluir tu propio texto personalizado al inicio de la dirección de correo electrónico seguido de un guion bajo. Por ejemplo, `test_1_generatedSepaDebitIntentsFail@example.com` genera un PaymentMethod con débito directo SEPA que siempre da error cuando se usa con un `PaymentIntent`.

| Dirección de correo electrónico                                    | Descripción                                                                                                                |
| ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `generatedSepaDebitIntentsSucceed@example.com`                     | El estado del `PaymentIntent`pasa de `processing` a `succeeded`.                                                           |
| `generatedSepaDebitIntentsSucceedDelayed@example.com`              | El estado del `PaymentIntent` pasa de `processing` a `succeeded` después de, al menos, tres minutos.                       |
| `generatedSepaDebitIntentsFail@example.com`                        | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method`.                                            |
| `generatedSepaDebitIntentsFailDelayed@example.com`                 | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method` después de, al menos, tres minutos.         |
| `generatedSepaDebitIntentsSucceedDisputed@example.com`             | El estado del `PaymentIntent` pasa de `processing` a `succeeded`, pero se crea inmediatamente una disputa.                 |
| `generatedSepaDebitIntentsFailsDueToInsufficientFunds@example.com` | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method` con el código de error `inufficient_funds`. |

#### PaymentMethod

Usa estos PaymentMethods para probar que el `PaymentIntent` haga la transición. Estos tokens son útiles para que las pruebas automáticas adjunten un PaymentMethod al SetupIntent en el servidor.

| Método de pago                                                      | Descripción                                                                                                                |
| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `pm_bancontact_generatedSepaDebitIntentsSucceed`                    | El estado del `PaymentIntent`pasa de `processing` a `succeeded`.                                                           |
| `pm_bancontact_generatedSepaDebitIntentsSucceedDelayed`             | El estado del `PaymentIntent` pasa de `processing` a `succeeded` después de, al menos, tres minutos.                       |
| `pm_bancontact_generatedSepaDebitIntentsFail`                       | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method`.                                            |
| `pm_bancontact_generatedSepaDebitIntentsFailDelayed`                | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method` después de, al menos, tres minutos.         |
| `pm_bancontact_generatedSepaDebitIntentsSucceedDisputed`            | El estado del `PaymentIntent` pasa de `processing` a `succeeded`, pero se crea inmediatamente una disputa.                 |
| `pm_bancontact_generadoSepaDebitIntentsFailsDueToInsufficientFunds` | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method` con el código de error `inufficient_funds`. |

## See also

- [Guarda los datos del pago durante los pagos que se realizan en la aplicación](https://docs.stripe.com/payments/mobile/save-during-payment.md)
- [Guarda los detalles del pago en una sesión de Checkout](https://docs.stripe.com/payments/checkout/how-checkout-works.md#save-payment-methods)
- [Configurar pagos futuros](https://docs.stripe.com/payments/save-and-reuse.md)
- [Handle post-payment events](https://docs.stripe.com/webhooks/handling-payment-events.md)

