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

Descubre cómo 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

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

- añadir a tu sitio web o aplicación condiciones que indiquen cómo piensas guardar los datos del método de pago, por ejemplo:
  - el consentimiento del cliente que te permite iniciar un pago o una serie de pagos en su nombre para transacciones específicas.
  - El momento previsto y la frecuencia 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 que guardado solo para lo que figura en tus condiciones.
- Consigue el consentimiento explícito del cliente para este uso específico. Por ejemplo, incluye una casilla de verificación «Guardar mi método de pago para futuras compras».
- Guarda un registro de la aceptación por escrito de estas condiciones por parte de tu cliente.

> 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 pagos utilizado durante un pago, de modo que puedas recuperarlo para utilizarlo en futuros pagos del mismo cliente.

## Enable saved payment methods

> Las leyes internacionales en materia de privacidad son complejas y presentan muchos matices. Antes de implementar la función de almacenamiento de los datos de los métodos de pagos de los clientes, consulta con tu equipo jurídico para asegurarte de que cumple con tu marco normativo en materia de privacidad y cumplimiento de la normativa.

Para permitir que un cliente guarde su método de pagos para su uso futuro, especifica el parámetro [saved_pago_method_options.pago_method_save](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-saved_payment_method_options-payment_method_save) al crear el proceso de compra.

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

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

Después de crear Checkout Session, usa 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 proceso 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',
    }
  }
});
```

#### React

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 pagos guardado previamente

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',
    }
  }
});
```

#### React

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',
    },
  }
});
```

#### React

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 en materia de privacidad son complejas y presentan muchos matices. Antes de implementar la función de almacenamiento de los datos de los métodos de pagos de los clientes, consulta con tu equipo jurídico para asegurarte de que cumple con tu marco normativo en materia 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>
```

#### React

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

#### React

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

#### React

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

#### React

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

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

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

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

## Cumplimiento de la normativa

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

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

## 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 pagos utilizado durante un pago, de modo que puedas recuperarlo para 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 su 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 al Payment Element lo siguiente:

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

Guarda los 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.

### Permite que se guarde el método de pago en el Payment Element

Al crear un [PagoIntent](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 `cliente` para un objeto `Cliente` o `customer_account` para un objeto `Cuenta` 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é [funciones](https://docs.stripe.com/api/customer_sessions/create.md#create_customer_session-components-payment_element-features) de método para pagar guardadas 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 para pagar para su uso futuro.

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

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

#### Cuentas v2

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

#### Clientes 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 los errores](https://docs.stripe.com/error-handling.md) correctamente cuando crees 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 y para CustomerSession. A continuación, 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, en función de si el cliente ha marcado la casilla para guardar sus datos de pago.

### Exigir la recolección del CVC

Otra opción es especificar `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 garantizar que se recoja el CVC cuando un cliente paga con tarjeta.

### Detectar la elección de un método de pago guardado

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

```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 apoyamos hacer este ajuste en el lado del cliente.

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

Puedes administrar los métodos de pago desde el [Dashboard](https://dashboard.stripe.com/settings/payment_methods). Stripe gestiona la devolución de los métodos de pago que cumplan con los requisitos en función de factores como el importe de la transacción, la divisa 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"
```

#### Establece métodos de pago manualmente

Como otra 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"
```

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

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

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

#### Cuentas v2

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

#### Clientes v1

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

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

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

#### Cuentas v2

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

#### Clientes v1

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

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

#### Redireccionamientos bancarios

| Método de pago      | Situación                                                                                                                                                         | Cómo hacer la prueba                                                                                                                                                           |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Bancontact          | Tu cliente configura correctamente un método de pago con adeudo directo SEPA para usarlo en el futuro con Bancontact.                                             | Usa cualquier nombre en el formulario de Bancontact y después haz clic en **Autorizar la configuración de prueba** en la página de redireccionamiento.                         |
| Bancontact          | Tu cliente no pasa la autenticación en la página de redireccionamiento de Bancontact.                                                                             | Usa cualquier nombre en el formulario de Bancontact y después haz clic en **Error en la configuración de prueba** en la página de redireccionamiento.                          |
| Adeudo directo BECS | Tu cliente paga correctamente con adeudo 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 pasa a `succeeded`. |
| Adeudo directo BECS | El pago de tu cliente falla con un código de error `account_closed`.                                                                                              | Rellena el formulario con el número de cuenta `111111113`.                                                                                                                     |
| iDEAL               | Tu cliente configura correctamente un método de pago de [adeudo directo SEPA](https://docs.stripe.com/payments/sepa-debit.md) para usarlo en el futuro con iDEAL. | Usa cualquier nombre y banco en el formulario de iDEAL y después haz clic 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; después, haz clic en **Error en la configuración de prueba** en la página de redireccionamiento.  |

#### Adeudos bancarios

| Método de pago      | Situación                                                                                    | Cómo hacer la prueba                                                                                                                                                                 |
| ------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Adeudo directo SEPA | Tu cliente paga correctamente con adeudo directo SEPA.                                       | Rellena el formulario con el número de cuenta `AT321904300235473204`. El PaymentIntent confirmado pasa inicialmente al estado `processing` y, tres minutos más tarde, a `succeeded`. |
| Adeudo directo SEPA | El estado del Payment Intent de tu cliente pasa de `processing` a `requires_payment_method`. | Rellena 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  con iDEAL, Bancontact o Sofort genera un *PaymentMethod* (PaymentMethods represent your customer's payment instruments, used with the Payment Intents or Setup Intents APIs) [adeudo directo SEPA](https://docs.stripe.com/payments/sepa-debit.md). El adeudo 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 de `processing` intermedio antes de pasar a un estado `succeeded` o `requires_payment_method` varios días después.

#### Correo electrónico

Establece `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 principio de la dirección de correo electrónico seguido de un guion bajo. Por ejemplo, `test_1_generatedSepaDebitIntentsFail@example.com` genera un PaymentMethod de adeudo 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` al menos tres minutos después.                            |
| `generatedSepaDebitIntentsFail@example.com`                        | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method`.                                            |
| `generatedSepaDebitIntentsFailDelayed@example.com`                 | Una vez transcurridos tres minutos, el estado del `PaymentIntent` pasa de `processing` a `requires_payment_method`.        |
| `generatedSepaDebitIntentsSucceedDisputed@example.com`             | El estado del `PaymentIntent` pasa de `processing` a `succeeded`, pero se crea una disputa instantáneamente.               |
| `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 automatizadas vinculen al instante 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` al menos tres minutos después.                            |
| `pm_bancontact_generatedSepaDebitIntentsFail`                        | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method`.                                            |
| `pm_bancontact_generatedSepaDebitIntentsFailDelayed`                 | Una vez transcurridos tres minutos, el estado del `PaymentIntent` pasa de `processing` a `requires_payment_method`.        |
| `pm_bancontact_generatedSepaDebitIntentsSucceedDisputed`             | El estado del `PaymentIntent` pasa de `processing` a `succeeded`, pero se crea una disputa instantáneamente.               |
| `pm_bancontact_generatedSepaDebitIntentsFailsDueToInsufficientFunds` | El estado del `PaymentIntent` pasa de `processing` a `requires_payment_method` con el código de error `inufficient_funds`. |

## See also

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

