# Aceptar pagos con OXXO Cómo aceptar pagos con OXXO, un método de pago muy usado en México. # Checkout > This is a Checkout for when payment-ui is checkout. View the full page at https://docs.stripe.com/payments/oxxo/accept-a-payment?payment-ui=checkout. > Stripe puede mostrar automáticamente a tus clientes los métodos de pago relevantes, ya que considera la moneda, las restricciones de los métodos de pago y otros parámetros. > > - Sigue la guía [Aceptar un pago](https://docs.stripe.com/payments/accept-a-payment.md?payment-ui=checkout&ui=stripe-hosted) para crear una integración de Checkout que utilice [métodos de pago dinámicos](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md). - Si no quieres usar métodos de pago dinámicos, sigue los pasos a continuación para configurar manualmente los métodos de pago en tu integración de Checkout. OXXO es un método de pago de [uso único](https://docs.stripe.com/payments/payment-methods.md#usage) que solicita a los clientes [cumplir con más pasos](https://docs.stripe.com/payments/payment-methods.md#customer-actions) para efectivizar el pago. Los *Customers* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) pagan presentando el vale OXXO con un número generado y el pago en efectivo en una tienda OXXO. ## Determinar compatibilidad **Ubicaciones comerciales admitidas**: MX **Monedas admitidas**: `mxn` **Monedas de pago**: `mxn` **Modo de pago**: Yes **Modo configuración**: No **Modo suscripción**: No La sesión de Checkout debe cumplir con todas estas condiciones para aceptar pagos con OXXO: - Los *precios* (Prices define how much and how often to charge for products. This includes how much the product costs, what currency to use, and the interval if the price is for subscriptions) de todos los ítems de factura deben estar expresados en la misma moneda. Si tienes ítems en otras monedas, crea sesiones de Checkout separadas para cada moneda. - Solo puedes usar ítems de una sola vez (no se aceptan planes recurrentes de *suscripción* (A Subscription represents the product details associated with the plan that your customer subscribes to. Allows you to charge the customer on a recurring basis)). ## Aceptar un pago > Crea una integración para [aceptar un pago](https://docs.stripe.com/payments/accept-a-payment.md?integration=checkout) con Checkout antes de usar esta guía. Esto te orienta para habilitar OXXO y muestra las diferencias entre aceptar pagos con métodos de pago dinámicos y configurar métodos de pago manualmente. ### Habilitar OXXO como método de pago Al crear una nueva [sesión de Checkout](https://docs.stripe.com/api/checkout/sessions.md), debes: 1. Agrega `oxxo` a la lista de `payment_method_types`. 1. Asegúrate de que todos los `line_items` usen la moneda `mxn`. #### Página alojada por Stripe ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]"=mxn \ -d "line_items[0][price_data][product_data][name]"=T-shirt \ -d "line_items[0][price_data][unit_amount]"=2000 \ -d "line_items[0][quantity]"=1 \ -d mode=payment \ -d "payment_method_types[0]"=card \ -d "payment_method_types[1]"=oxxo \ --data-urlencode success_url="https://example.com/success" ``` #### Formulario integrado ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]"=mxn \ -d "line_items[0][price_data][product_data][name]"=T-shirt \ -d "line_items[0][price_data][unit_amount]"=2000 \ -d "line_items[0][quantity]"=1 \ -d mode=payment \ -d "payment_method_types[0]"=card \ -d "payment_method_types[1]"=oxxo \ --data-urlencode return_url="https://example.com/return" \ -d ui_mode=embedded ``` ### Opciones de métodos de pago adicionales Puedes especificar un parámetro opcional `expires_after_days` en las [opciones de métodos de pago](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-payment_method_options-oxxo-expires_after_days) de tu `Session` que define la cantidad de días calendario que deben pasar para que venza el vale OXXO. Por ejemplo, si creas un vale OXXO un lunes y defines `expires_after_days` en 2, el vale OXXO vencerá el miércoles a las 23:59, zona horaria de America/Mexico_City (UTC-6). El parámetro `expires_after_days` puede ser de 1 a 7 días. El valor predeterminado es 3 días. #### Página alojada por Stripe ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]"=mxn \ -d "line_items[0][price_data][product_data][name]"=T-shirt \ -d "line_items[0][price_data][unit_amount]"=2000 \ -d "line_items[0][quantity]"=1 \ -d mode=payment \ -d "payment_method_options[oxxo][expires_after_days]"=2 \ -d "payment_method_types[0]"=card \ -d "payment_method_types[1]"=oxxo \ --data-urlencode success_url="https://example.com/success" ``` #### Formulario integrado ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price_data][currency]"=mxn \ -d "line_items[0][price_data][product_data][name]"=T-shirt \ -d "line_items[0][price_data][unit_amount]"=2000 \ -d "line_items[0][quantity]"=1 \ -d mode=payment \ -d "payment_method_options[oxxo][expires_after_days]"=2 \ -d "payment_method_types[0]"=card \ -d "payment_method_types[1]"=oxxo \ --data-urlencode return_url="https://example.com/return" \ -d ui_mode=embedded ``` ### Redireccionamiento a la página del vale alojada por Stripe Después de enviar el formulario de Checkout correctamente, se redirige al cliente a la `hosted_voucher_url`. El cliente puede buscar el código de barras o imprimir el vale OXXO desde la página de vales alojada. Puedes localizar la `hosted_voucher_url` en [payment_intent.next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-hosted_voucher_url). Stripe permite la personalización de las interfaces de usuario del cliente en la página [configuración de imagen de marca](https://dashboard.stripe.com/account/branding). Se puede aplicar la siguiente configuración de imagen de marca al vale: - **Ícono**: tu imagen de marca y el nombre público de la empresa - \**Color de acento **: se usa como el color del botón Imprimir - **Color de la marca**: se utiliza como color de fondo ### Completa los pedidos Debido a que OXXO es un método de pago con notificación diferida, tienes que usar un método como los *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) para monitorear el estado del pago y gestionar *el cumplimiento del pedido* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected). Obtén más información sobre [cómo configurar webhooks y completar pedidos](https://docs.stripe.com/checkout/fulfillment.md). Los siguientes eventos se envían cuando cambia el estado del pago: | Nombre del evento | Descripción | Próximos pasos | | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | [checkout.session.completed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.completed) | El cliente ha enviado correctamente el formulario de Checkout. Stripe ha generado el vale OXXO. Puedes elegir enviar la `hosted_voucher_url` por correo electrónico a tu cliente en caso de que pierda el vale OXXO. | Espera a que el cliente pague el vale OXXO. | | [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) | El cliente ha pagado correctamente el vale OXXO. El `PaymentIntent` pasa a `succeeded`. | Entrega los bienes o servicios que el cliente compró. | | [checkout.session.async_payment_failed](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_failed) | El vale OXXO ha caducado o el pago ha fallado por algún otro motivo. El estado del `PaymentIntent` vuelve a ser `requires_payment_method`. | Ponte en contacto con el cliente por correo electrónico y solicítale que haga un nuevo pedido. | ## Prueba tu integración Al probar tu integración de Checkout, selecciona OXXO como método de pago y haz click en el botón **Pagar**. | Correo electrónico | Descripción | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | Simula un vale OXXO abonado por el cliente al cabo de 3 minutos con el webhook `payment_intent.succeeded` recibido después de 3 minutos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: fulano@test.com | | `{any_prefix}succeed_immediately@{any_domain}` | Simula un vale OXXO abonado por el cliente de inmediato con el webhook `payment_intent.succeeded` recibido después de unos segundos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: succeed_immediately@test.com | | `{any_prefix}expire_immediately@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de unos segundos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) está establecido en la hora actual, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_immediately@test.com | | `{any_prefix}expire_with_delay@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 3 minutos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) se establece en 3 minutos, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_with_delay@test.com | | `{any_prefix}fill_never@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 1 día hábil y 2 días calendario. En modo activo, este webhook llega a la misma hora que en modo de prueba. Ejemplo: fill_never@test.com | ## Optional: Enviar correos electrónicos con instrucciones de pago Puedes habilitar los correos electrónicos con instrucciones de pago con OXXO en la página de [configuración de correo electrónico](https://dashboard.stripe.com/settings/emails) en el Dashboard. Una vez habilitados, Stripe envía estos correos cuando se confirma el PaymentIntent. Los correos contienen el número de OXXO y un enlace a la página del vale alojada en Stripe. > En los entornos de prueba, los correos electrónicos con instrucciones solo se envían a las direcciones de correo vinculadas a la cuenta de Stripe. ## See also - [Cumplimiento del proceso de compra](https://docs.stripe.com/checkout/fulfillment.md) - [Cómo personalizar Checkout](https://docs.stripe.com/payments/checkout/customization.md) # Checkout Sessions API > This is a Checkout Sessions API for when payment-ui is elements and api-integration is checkout. View the full page at https://docs.stripe.com/payments/oxxo/accept-a-payment?payment-ui=elements&api-integration=checkout. Para determinar qué API satisface las necesidades de tu empresa, consulta la [guía comparativa](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md). Usa [Payment Element](https://docs.stripe.com/payments/payment-element.md) para integrar un formulario de pago de Stripe personalizado en tu sitio web o aplicación y ofrecer métodos de pago a los clientes. Para configuraciones y personalizaciones avanzadas, consulta la guía de integración [Aceptar un pago](https://docs.stripe.com/payments/accept-a-payment.md). ## Determinar compatibilidad **Ubicaciones comerciales admitidas**: MX **Monedas admitidas**: `mxn` **Monedas de pago**: `mxn` **Modo de pago**: Yes **Modo configuración**: No **Modo suscripción**: No La sesión de Checkout debe cumplir con todas estas condiciones para aceptar pagos con OXXO: - Los precios de todos los ítems de factura deben estar expresados en la misma moneda. Si tienes ítems en otras monedas, crea sesiones de Checkout separadas para cada moneda. - Solo puedes utilizar ítems puntuales (no se aceptan planes de suscripción recurrentes). ## Configurar el servidor [Lado del servidor] Usa las bibliotecas oficiales de Stripe para acceder a la API desde tu aplicación. #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Crear una sesión de Checkout [Lado del servidor] Agrega un punto de conexión en el servidor que cree una [sesión de Checkout](https://docs.stripe.com/api/checkout/sessions/create.md) y devuelva su [secreto de cliente](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-client_secret) al front-end. Una sesión de Checkout representa la sesión del cliente cuando paga por compras únicas o suscripciones. Las sesiones de Checkout vencen 24 horas después de su creación. Recomendamos usar [métodos de pago dinámicos](https://docs.stripe.com/payments/payment-methods/dynamic-payment-methods.md) para mostrar de manera dinámica los métodos de pago elegibles más relevantes para cada cliente y maximizar la conversión. También puedes [enumerar de forma manual los métodos de pago](https://docs.stripe.com/payments/payment-methods/integration-options.md#listing-payment-methods-manually), que deshabilitan los métodos de pago dinámicos. #### Gestionar los métodos de pago desde el Dashboard #### TypeScript ```javascript import express, {Express} from 'express'; const app: Express = express(); app.post('/create-checkout-session', async (req: Express.Request, res: Express.Response) => { const session = await stripe.checkout.sessions.create({ line_items: [ { price_data: { currency: 'mxn', product_data: { name: 'T-shirt', }, unit_amount: 1099, }, quantity: 1, }, ], mode: 'payment', ui_mode: 'custom', return_url: 'https://example.com/return?session_id={CHECKOUT_SESSION_ID}' }); res.json({checkoutSessionClientSecret: session.client_secret}); }); app.listen(3000, () => { console.log('Running on port 3000'); }); ``` #### Enumerar métodos de pago manualmente #### TypeScript ```javascript import express, {Express} from 'express'; const app: Express = express(); app.post('/create-checkout-session', async (req: Express.Request, res: Express.Response) => { const session = await stripe.checkout.sessions.create({ line_items: [ { price_data: { currency: 'mxn', product_data: { name: 'T-shirt', }, unit_amount: 1099, }, quantity: 1, }, ], mode: 'payment', ui_mode: 'custom', payment_method_types: ['oxxo'], return_url: 'https://example.com/return?session_id={CHECKOUT_SESSION_ID}' }); res.json({checkoutSessionClientSecret: session.client_secret}); }); app.listen(3000, () => { console.log('Running on port 3000'); }); ``` ## Configurar el front-end [Lado del cliente] #### HTML + JS Incluye el script de Stripe.js en tu página de confirmación de compra agregándolo al `head` del archivo HTML. Carga siempre Stripe.js directamente desde js.stripe.com para cumplir con la normativa PCI. No incluyas el guion en un paquete ni alojes una copia por tu cuenta. Asegúrate de tener la última versión de Stripe.js mediante la siguiente etiqueta de script ``. Obtén más información sobre [las versiones de Stripe.js](https://docs.stripe.com/sdks/stripejs-versioning.md). ```html Checkout ``` > Stripe proporciona un paquete npm que puedes usar para cargar Stripe.js como módulo. Ver el [proyecto en GitHub](https://github.com/stripe/stripe-js). Se requiere la versión [7.0.0](https://www.npmjs.com/package/%40stripe/stripe-js/v/7.0.0) o posterior. Inicia Stripe.js. ```js // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe( '<>', ); ``` #### React Instala [React Stripe.js](https://www.npmjs.com/package/@stripe/react-stripe-js) y el [cargador Stripe.js](https://www.npmjs.com/package/@stripe/stripe-js) desde el registro público npm. Necesitas al menos la versión 5.0.0 para React Stripe.js y la versión 8.0.0 para el cargador Stripe.js. ```bash npm install --save @stripe/react-stripe-js@^5.0.0 @stripe/stripe-js@^8.0.0 ``` Inicializa una instancia `stripe` en tu front-end con tu clave publicable. ```javascript import {loadStripe} from '@stripe/stripe-js'; const stripe = loadStripe("<>"); ``` ## Inicializar Checkout [Lado del cliente] #### HTML + JS Llama a [initCheckout](https://docs.stripe.com/js/custom_checkout/init), pasando `clientSecret`. `initCheckout` resuelve un objeto de [Checkout](https://docs.stripe.com/js/custom_checkout) que contiene datos de la Checkout Session y métodos para actualizarla. Lee el `total` y los `lineItems` de [actions.getSession()](https://docs.stripe.com/js/custom_checkout/session) y muéstralos en tu interfaz de usuario (IU). Esto te permite activar nuevas funcionalidades con cambios mínimos en el código. Por ejemplo, si agregas [precios manuales de monedas](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md), no es necesario hacer cambios en la interfaz de usuario (IU) si muestras el `total`. ```html
``` ```javascript const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const checkout = stripe.initCheckout({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const session = loadActionsResult.actions.getSession(); const checkoutContainer = document.getElementById('checkout-container'); checkoutContainer.append(JSON.stringify(session.lineItems, null, 2)); checkoutContainer.append(document.createElement('br')); checkoutContainer.append(`Total: ${session.total.total.amount}`); } ``` #### React Envuelve la solicitud con el componente [CheckoutProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider), pasando `clientSecret` y la instancia `stripe`. ```jsx import React from 'react'; import {CheckoutProvider} from '@stripe/react-stripe-js/checkout'; import CheckoutForm from './CheckoutForm'; const clientSecret = fetch('/create-checkout-session', {method: 'POST'}) .then((response) => response.json()) .then((json) => json.client_secret); const App = () => { return ( ); }; export default App; ``` Accede al objeto [Checkout](https://docs.stripe.com/js/custom_checkout) en el componente del formulario de confirmación de compra con el hook `useCheckout()`. El objeto `Checkout` contiene datos de la sesión de confirmación de compra y métodos para actualizarla. Lee el `total` y los `lineItems` del objeto `Checkout` y muéstralos en tu interfaz de usuario (IU). Esto te permite habilitar funcionalidades con cambios mínimos de código. Por ejemplo, agregar [precios manuales de monedas](https://docs.stripe.com/payments/custom/localize-prices/manual-currency-prices.md) no requiere cambios en la interfaz de usuario (IU) si muestras el `total`. ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => {const checkoutState = useCheckout(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount}
); }; ``` ## Recopilar correo electrónico del cliente [Lado del cliente] #### HTML + JS Debes proporcionar un correo electrónico del cliente válido cuando completas una sesión de Checkout. Estas instrucciones crean una entrada de correo electrónico y utilizan [updateEmail](https://docs.stripe.com/js/custom_checkout/update_email) desde el objeto de `Checkout`. Como alternativa, puedes hacer lo siguiente: - Especifica [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email) o el [cliente](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) cuando crees la sesión de Checkout. Stripe valida los correos electrónicos proporcionados de esta manera. - Especifica un correo electrónico que ya validaste en [checkout.confirm](https://docs.stripe.com/js/custom_checkout/confirm). ```html
``` ```javascript const checkout = stripe.initCheckout({clientSecret}); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; const emailInput = document.getElementById('email'); const emailErrors = document.getElementById('email-errors'); emailInput.addEventListener('input', () => { // Clear any validation errors emailErrors.textContent = ''; }); emailInput.addEventListener('blur', () => { const newEmail = emailInput.value;actions.updateEmail(newEmail).then((result) => { if (result.error) { emailErrors.textContent = result.error.message; } }); }); } ``` #### React Debes proporcionar un correo electrónico del cliente válido cuando completas una sesión de Checkout. Estas instrucciones crean una entrada de correo electrónico y utilizan [updateEmail](https://docs.stripe.com/js/react_stripe_js/checkout/update_email) desde el objeto de `Checkout`. Como alternativa, puedes hacer lo siguiente: - Especifica [customer_email](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer_email) o el [cliente](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-customer) cuando crees la sesión de Checkout. Stripe valida los correos electrónicos proporcionados de esta manera. - Especifica un correo electrónico que ya validaste en la [confirmación](https://docs.stripe.com/js/react_stripe_js/checkout/confirm). ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js/checkout'; const EmailInput = () => { const checkoutState = useCheckout(); const [email, setEmail] = React.useState(''); const [error, setError] = React.useState(null); if (checkoutState.type === 'loading') { return (
Loading...
); } else if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } const handleBlur = () => {checkoutState.checkout.updateEmail(email).then((result) => { if (result.type === 'error') { setError(result.error); } }) }; const handleChange = (e) => { setError(null); setEmail(e.target.value); }; return (
{error &&
{error.message}
}
); }; export default EmailInput; ``` ## Recopilar datos de pago [Lado del cliente] Recopila los datos de pago del cliente con el [Payment Element](https://docs.stripe.com/payments/payment-element.md). Payment Element es un componente de interfaz de usuario prediseñado que simplifica la recopilación de datos de pago para una variedad de métodos de pago. El Payment Element contiene un iframe que envía la información de pago a Stripe de manera segura mediante una conexión HTTPS. No coloques el Payment Element dentro de otro iframe porque, para algunos métodos de pago, se requiere la redirección a otra página para la confirmación del pago. Si optas por usar un iframe y quieres aceptar Apple Pay o Google Pay, el iframe debe tener el atributo [allow](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allowpaymentrequest) establecido en `«payment*»`. Para que la integración funcione, la dirección de la página del proceso de compra debe empezar con `https://` rather en lugar de `http://` for. Puedes probar tu integración sin usar HTTPS, pero recuerda [habilitarla](https://docs.stripe.com/security/guide.md#tls) cuando todo esté listo para aceptar pagos activos. #### HTML + JS En primer lugar, crea un elemento DOM contenedor para montar el [Payment Element](https://docs.stripe.com/payments/payment-element.md). Luego, crea una instancia del `Payment Element` usando [checkout.createPaymentElement](https://docs.stripe.com/js/custom_checkout/create_payment_element) y móntala llamando a [element.mount](https://docs.stripe.com/js/element/mount), proporcionando un selector CSS o el elemento DOM contenedor. ```html
``` ```javascript const paymentElement = checkout.createPaymentElement(); paymentElement.mount('#payment-element'); ``` Consulta la [documentación Stripe.js](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) para ver las opciones admitidas. Puedes [personalizar el aspecto](https://docs.stripe.com/payments/checkout/customization/appearance.md) de todos los Elements pasando [elementsOptions.appearance](https://docs.stripe.com/js/custom_checkout/init#custom_checkout_init-options-elementsOptions-appearance) al inicializar Checkout en el front-end. #### React Arma el componente [Payment Element](https://docs.stripe.com/payments/payment-element.md) dentro del [CheckoutProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider). ```jsx import React from 'react';import {PaymentElement, useCheckout} from '@stripe/react-stripe-js/checkout'; const CheckoutForm = () => { const checkoutState = useCheckout(); if (checkoutState.type === 'loading') { return (
Loading...
); } if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } return (
{JSON.stringify(checkoutState.checkout.lineItems, null, 2)} {/* A formatted total amount */} Total: {checkoutState.checkout.total.total.amount} ); }; export default CheckoutForm; ``` Consulta la [documentación Stripe.js](https://docs.stripe.com/js/custom_checkout/create_payment_element#custom_checkout_create_payment_element-options) para ver las opciones admitidas. Puedes [personalizar el aspecto](https://docs.stripe.com/payments/checkout/customization/appearance.md) de todos los Elements especificando [elementsOptions.appearance](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider#react_checkout_provider-options-elementsOptions-appearance) en el [CheckoutProvider](https://docs.stripe.com/js/react_stripe_js/checkout/checkout_provider). ## Envía el pago [Lado del cliente] #### HTML + JS Presenta un botón **Pagar** que llame a [confirmar](https://docs.stripe.com/js/custom_checkout/confirm) desde la instancia de `Checkout` para enviar el pago. ```html
``` ```js const checkout = stripe.initCheckout({clientSecret}); checkout.on('change', (session) => { document.getElementById('pay-button').disabled = !session.canConfirm; }); const loadActionsResult = await checkout.loadActions(); if (loadActionsResult.type === 'success') { const {actions} = loadActionsResult; const button = document.getElementById('pay-button'); const errors = document.getElementById('confirm-errors'); button.addEventListener('click', () => { // Clear any validation errors errors.textContent = ''; actions.confirm().then((result) => { if (result.type === 'error') { errors.textContent = result.error.message; } }); }); } ``` #### React Renderiza un botón **Pagar** que pase de[confirmar](https://docs.stripe.com/js/custom_checkout/confirm) a[useCheckout](https://docs.stripe.com/js/react_stripe_js/checkout/use_checkout) para enviar el pago. ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js/checkout'; const PayButton = () => { const checkoutState = useCheckout(); const [loading, setLoading] = React.useState(false); const [error, setError] = React.useState(null); if (checkoutState.type !== "success") { return null; } const handleClick = () => { setLoading(true);checkoutState.checkout.confirm().then((result) => { if (result.type === 'error') { setError(result.error) } setLoading(false); }) }; return (
{error &&
{error.message}
}
) }; export default PayButton; ``` ## Prueba tu integración Para probar tu integración, elige el método de pago y toca **Pagar**. En un *entorno de prueba* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes), esto te redirige a una página de pago de prueba donde puedes aprobar o rechazar el pago. En modo activo, cuando tocas **Pagar**, se te redirige al sitio web oxxo. No tienes la opción de aprobar o rechazar pagos con oxxo. # API Payment Intents > This is a API Payment Intents for when payment-ui is elements and api-integration is paymentintents. View the full page at https://docs.stripe.com/payments/oxxo/accept-a-payment?payment-ui=elements&api-integration=paymentintents. Para determinar qué API satisface las necesidades de tu empresa, consulta la [guía comparativa](https://docs.stripe.com/payments/checkout-sessions-and-payment-intents-comparison.md). Usa [Payment Element](https://docs.stripe.com/payments/payment-element.md) para integrar un formulario de pago de Stripe personalizado en tu sitio web o aplicación y ofrecer métodos de pago a los clientes. Para configuraciones y personalizaciones avanzadas, consulta la guía de integración [Aceptar un pago](https://docs.stripe.com/payments/accept-a-payment.md). ## Configurar Stripe [Lado del servidor] Para empezar, [crea una cuenta de Stripe](https://dashboard.stripe.com/register). Usa nuestras bibliotecas oficiales para acceder a la API de Stripe desde tu aplicación: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Recopilar datos de pago [Lado del cliente] Ya tienes todo listo para recopilar datos del pago del lado del cliente con Payment Element. El Payment Element es un componente de interfaz de usuario prediseñado que simplifica la recopilación de datos de pago para una amplia variedad de métodos de pago. El Payment Element contiene un iframe que envía la información de pago a Stripe de manera segura mediante una conexión HTTPS. No coloques el Payment Element dentro de otro iframe porque, para algunos métodos de pago, se requiere el redireccionamiento a otra página a fin de confirmar el pago. Para que la integración funcione, la dirección de la página de confirmación de compra debe empezar con `https://` en lugar de `http://`. Puedes probar tu integración sin usar HTTPS, pero recuerda [habilitarla](https://docs.stripe.com/security/guide.md#tls) cuando todo esté listo para aceptar pagos reales. #### HTML + JS ### Configurar Stripe.js El Payment Element se encuentra disponible automáticamente como funcionalidad de Stripe.js. Incluye el script de Stripe.js en tu página de confirmación de compra agregándolo al `head` de tu archivo HTML. Siempre debes cargar Stripe.js directamente desde js.stripe.com para cumplir con la normativa PCI. No incluyas el script en un paquete ni alojes una copia en tus sistemas. ```html Checkout ``` Crea una instancia de Stripe con el siguiente JavaScript en tu página de finalización de compra: ```javascript // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe('<>'); ``` ### Cómo agregar el Payment Element a tu página de finalización de compra Payment Element necesita un lugar en tu página de finalización de compra. Crea un nodo DOM vacío (contenedor) con un ID único en tu formulario de pago: ```html
``` #### Controla los métodos de pago desde el Dashboard Después de cargar el formulario que aparece arriba, crea una instancia de Elements con `mode`, `amount` y `currency`. Estos valores determinan qué métodos de pago ve tu cliente. Para proporcionar un nuevo método de pago en tu formulario, asegúrate de habilitarlo en el [Dashboard](https://dashboard.stripe.com/settings/payment_methods). ```javascript const options = {mode:'payment', amount:1099, currency: 'mxn', // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in checkout formconst elements = stripe.elements(options); // Create and mount the Payment Element const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element'); ``` #### Enumerar métodos de pago manualmente Para enumerar manualmente los métodos de pago que quieres que estén disponibles, agrega cada uno a `paymentMethodTypes`. Luego, crea una instancia de Payment Element y móntala en el nodo DOM del contenedor. ```javascript const options = {mode:'payment', amount:1099, currency: 'mxn', paymentMethodTypes: ['oxxo'], // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in checkout formconst elements = stripe.elements(options); // Create and mount the Payment Element const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element'); ``` #### React ### Configurar Stripe.js Instala [React Stripe.js](https://www.npmjs.com/package/@stripe/react-stripe-js) y el [cargador Stripe.js](https://www.npmjs.com/package/@stripe/stripe-js) desde el registro público npm. ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` ### Cómo agregar y configurar el proveedor Elements en tu página de finalización de compra Para usar el componente Payment Element, envuelve el componente de tu página de confirmación de compra con un [proveedor Elements](https://docs.stripe.com/sdks/stripejs-react.md#elements-provider). Llama a `loadStripe` con tu clave publicable y especifica el valor `Promise` devuelto en el proveedor `Elements`. #### Controla los métodos de pago desde el Dashboard El proveedor de `Elements` también acepta `mode`, `amount` y `currency`. Estos valores determinan qué métodos de pago ve tu cliente. Para proporcionar un nuevo método de pago en tu formulario, asegúrate de habilitarlo en el [Dashboard](https://dashboard.stripe.com/settings/payment_methods). ```jsx import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('<>'); function App() { const options = {mode:'payment', amount:1099, currency: 'mxn', // Fully customizable with appearance API. appearance: {/*...*/}, }; return ( ); }; ReactDOM.render(, document.getElementById('root')); ``` #### Enumerar métodos de pago manualmente ```jsx import React from 'react'; import ReactDOM from 'react-dom'; import {Elements} from '@stripe/react-stripe-js'; import {loadStripe} from '@stripe/stripe-js'; import CheckoutForm from './CheckoutForm'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('<>'); function App() { const options = {mode:'payment', amount:1099, currency: 'mxn', paymentMethodTypes: ['oxxo'], // Fully customizable with appearance API. appearance: {/*...*/}, }; return ( ); }; ReactDOM.render(, document.getElementById('root')); ``` ### Agregar el componente Payment Element Usa el componente `PaymentElement` para crear tu formulario. ```jsx import React from 'react'; import {PaymentElement} from '@stripe/react-stripe-js'; const CheckoutForm = () => { return (
); }; export default CheckoutForm; ``` Puedes personalizar el Payment Element para que coincida con el diseño de tu sitio especificando el [objeto appearance](https://docs.stripe.com/elements/appearance-api.md) en `options` al crear el proveedor `Elements`. ### Recopila las direcciones Por defecto, el Payment Element solo junta los detalles necesarios de la dirección de facturación. Algunos comportamientos, como el [cálculo de impuestos](https://docs.stripe.com/api/tax/calculations/create.md) o la introducción de datos de envío, requieren la dirección completa de tu cliente. Puedes realizar lo siguiente: - Utiliza el [Address Element](https://docs.stripe.com/elements/address-element.md) para aprovechar las funcionalidades de autocompletar y localizar para obtener la dirección completa de tu cliente. Esto ayuda a garantizar el cálculo de impuestos más preciso. - Recopila los datos de la dirección mediante tu propio formulario personalizado. ## Crear un PaymentIntent [Lado del servidor] > #### Ejecuta la lógica de negocio personalizada inmediatamente antes de la confirmación del pago > > Ve al [paso 5](https://docs.stripe.com/payments/finalize-payments-on-the-server.md?platform=web&type=payment#submit-payment) en la guía de finalización de pagos para ejecutar tu lógica empresarial personalizada inmediatamente antes de la confirmación del pago. De lo contrario, realiza los pasos que se describen a continuación para una integración más simple, que usa `stripe.confirmPayment` en el cliente para confirmar el pago y manejar las próximas acciones. #### Controla los métodos de pago desde el Dashboard Cuando el cliente envíe tu formulario de pago, usa un *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) para facilitar el proceso de confirmación y pago. Crea un PaymentIntent en tu servidor con `amount` y `currency`. Para evitar que clientes malintencionados puedan elegir sus propios precios, decide cuánto cobrar siempre del lado del servidor (un entorno de confianza) y no del lado del cliente. En un PaymentIntent se incluye un *secreto de cliente* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)). Devuelve este valor a tu cliente a fin de que Stripe.js lo use para completar el proceso de pago de forma segura. #### Ruby ```ruby require 'stripe' Stripe.api_key = '<>' post '/create-intent' do intent = Stripe::PaymentIntent.create({ # To allow saving and retrieving payment methods, provide the Customer ID. customer: customer.id, amount: 1099, currency: 'mxn', }) {client_secret: intent.client_secret}.to_json end ``` #### Enumerar métodos de pago manualmente Cuando el cliente envíe tu formulario de pago, usa un *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) para facilitar el proceso de confirmación y pago. Crea un PaymentIntent en tu servidor con `amount`, `currency` y uno o más métodos de pago usando `payment_method_types`. Para evitar que clientes malintencionados puedan elegir sus propios precios, decide cuánto cobrar siempre del lado del servidor (un entorno de confianza) y no del lado del cliente. En un PaymentIntent se incluye un *secreto de cliente* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)). Devuelve este valor a tu cliente a fin de que Stripe.js lo use para completar el proceso de pago de forma segura. #### Ruby ```ruby require 'stripe' Stripe.api_key = '<>' post '/create-intent' do intent = Stripe::PaymentIntent.create({ # To allow saving and retrieving payment methods, provide the Customer ID. customer: customer.id, amount: 1099, currency: 'mxn', payment_method_types: ['oxxo'], }) {client_secret: intent.client_secret}.to_json end ``` ## Enviar el pago a Stripe [Lado del cliente] Usa [stripe.confirmPayment](https://docs.stripe.com/js/payment_intents/confirm_payment) para completar el pago con los datos del Payment Element. Proporciona una [return_url](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-return_url) a esta función para indicar a dónde Stripe redirige al usuario después de completar el pago. Es posible que se redirija inicialmente al usuario a un sitio intermedio, como una página de autorización bancaria, antes de que se lo redirija a la `return_url`. Los pagos con tarjeta redirigen inmediatamente a la `return_url` cuando un pago se realiza correctamente. Si no quieres realizar el redireccionamiento de pagos con tarjeta una vez que se completan los pagos, puedes configurar el [redireccionamiento](https://docs.stripe.com/js/payment_intents/confirm_payment#confirm_payment_intent-options-redirect) en `if_required`. Esto solo redirigirá a los clientes que finalizan su compra con métodos de pago basados en redireccionamiento. #### HTML + JS ```javascript const form = document.getElementById('payment-form'); const submitBtn = document.getElementById('submit'); const handleError = (error) => { const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message; submitBtn.disabled = false; } form.addEventListener('submit', async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); // Prevent multiple form submissions if (submitBtn.disabled) { return; } // Disable form submission while loading submitBtn.disabled = true; // Trigger form validation and wallet collection const {error: submitError} = await elements.submit(); if (submitError) { handleError(submitError); return; } // Create the PaymentIntent and obtain clientSecret const res = await fetch("/create-intent", { method: "POST", }); const {client_secret: clientSecret} = await res.json(); // Confirm the PaymentIntent using the details collected by the Payment Element const {error} = await stripe.confirmPayment({ elements, clientSecret, confirmParams: { return_url: 'https://example.com/order/123/complete', }, }); if (error) { // This point is only reached if there's an immediate error when // confirming the payment. Show the error to your customer (for example, payment details incomplete) handleError(error); } else { // Your customer is redirected to your `return_url`. For some payment // methods like iDEAL, your customer is redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } }); ``` #### React ```jsx import React, {useState} from 'react'; import {useStripe, useElements, PaymentElement} from '@stripe/react-stripe-js'; export default function CheckoutForm() { const stripe = useStripe(); const elements = useElements(); const [errorMessage, setErrorMessage] = useState(); const [loading, setLoading] = useState(false); const handleError = (error) => { setLoading(false); setErrorMessage(error.message); } const handleSubmit = async (event) => { // We don't want to let default form submission happen here, // which would refresh the page. event.preventDefault(); if (!stripe) { // Stripe.js hasn't yet loaded. // Make sure to disable form submission until Stripe.js has loaded. return; } setLoading(true); // Trigger form validation and wallet collection const {error: submitError} = await elements.submit(); if (submitError) { handleError(submitError); return; } // Create the PaymentIntent and obtain clientSecret const res = await fetch("/create-intent", { method: "POST", }); const {client_secret: clientSecret} = await res.json(); // Confirm the PaymentIntent using the details collected by the Payment Element const {error} = await stripe.confirmPayment({ elements, clientSecret, confirmParams: { return_url: 'https://example.com/order/123/complete', }, }); if (error) { // This point is only reached if there's an immediate error when // confirming the payment. Show the error to your customer (for example, payment details incomplete) handleError(error); } else { // Your customer is redirected to your `return_url`. For some payment // methods like iDEAL, your customer is redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } }; return (
{errorMessage &&
{errorMessage}
} ); } ``` ## Optional: Gestionar eventos posteriores al pago Stripe envía un evento [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) cuando se completa el pago. Usa el Dashboard, un *webhook* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) personalizado o una solución de un socio para recibir estos eventos y ejecutar acciones como enviar un correo electrónico para confirmarle el pedido al cliente, registrar la venta en una base de datos o iniciar el flujo de envío. Recibe notificaciones de estos eventos en lugar de esperar una devolución de llamada del cliente. Del lado del cliente, este podría cerrar la ventana del navegador o salir de la aplicación antes de que se ejecute la devolución de llamada, y clientes malintencionados podrían manipular la respuesta. Si configuras tu integración para recibir notificaciones de estos eventos asincrónicos, también podrás aceptar más métodos de pago en el futuro. Descubre las [diferencias entre todos los métodos de pago admitidos](https://stripe.com/payments/payment-methods-guide). - **Gestionar eventos manualmente en el Dashboard** Usa el Dashboard para [ver tus pagos de prueba en el Dashboard](https://dashboard.stripe.com/test/payments), enviar recibos por correo electrónico, gestionar transferencias (a cuenta bancaria) o reintentar pagos con error. - **Crear un webhook personalizado** [Build a custom webhook](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) handler to listen for events and build custom asynchronous payment flows. Test and debug your webhook integration locally with the Stripe CLI. - **Integrar una aplicación prediseñada** Gestiona eventos empresariales comunes, como la [automatización](https://stripe.partners/?f_category=automation) o la [comercialización y las ventas](https://stripe.partners/?f_category=marketing-and-sales), integrando la aplicación de un socio. ## Prueba tu integración Para probar tu integración, elige el método de pago y toca **Pagar**. En un *entorno de prueba* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes), esto te redirige a una página de pago de prueba donde puedes aprobar o rechazar el pago. En modo activo, cuando tocas **Pagar**, se te redirige al sitio web oxxo. No tienes la opción de aprobar o rechazar pagos con oxxo. ## Códigos de error En la siguiente tabla se detallan los códigos de error más comunes y las acciones recomendadas: | Código de error | Acción recomendada | | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `payment_intent_invalid_currency` | Introduce una moneda admitida. | | `missing_required_parameter` | Consulta el mensaje de error para obtener más información sobre el parámetro requerido. | | `payment_intent_payment_attempt_failed` | Este código puede aparecer en el campo [last_payment_error.code](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-code) de un PaymentIntent. Revisa el mensaje de error para ver el motivo del error detallado y las sugerencias sobre cómo manejar los errores. | | `payment_intent_authentication_failure` | Este código puede aparecer en el campo [last_payment_error.code](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-last_payment_error-code) de un PaymentIntent. Comprueba el mensaje de error para ver el motivo del error detallado y sugerencias sobre el manejo de errores. Este error se produce cuando se activa manualmente un error al probar la integración. | | `payment_intent_redirect_confirmation_without_return_url` | Proporciona una `return_url` cuando confirmes un PaymentIntent. | # iOS > This is a iOS for when payment-ui is mobile and platform is ios. View the full page at https://docs.stripe.com/payments/oxxo/accept-a-payment?payment-ui=mobile&platform=ios. > Te recomendamos que sigas la guía [Cómo aceptar un pago](https://docs.stripe.com/payments/accept-a-payment.md) a menos que necesites usar la confirmación manual del lado del servidor o que tu integración requiera que presentes los métodos de pago por separado. Si ya te integraste con Elements, consulta la [guía de migración de Payment Element](https://docs.stripe.com/payments/payment-element/migration.md). Si aceptas OXXO en tu aplicación, se abrirá una vista web del vale OXXO. Los *clientes* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) abonan presentando un vale OXXO con un número y el pago en efectivo efectuado en una tienda OXXO de 24 horas. Stripe te notifica cuando se completa el pago. ## Configurar Stripe [Lado del servidor] [Lado del cliente] Primero, necesitas una cuenta de Stripe. [Inscríbete ahora](https://dashboard.stripe.com/register). ### Lado del servidor Esta integración necesita puntos de conexión en tu servidor que se comuniquen con la API de Stripe. Usa las bibliotecas oficiales para acceder a la API de Stripe desde tu servidor: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### Lado del cliente El [SDK para iOS de Stripe](https://github.com/stripe/stripe-ios) es de código abierto, está [plenamente documentado](https://stripe.dev/stripe-ios/index.html) y es compatible con aplicaciones que admiten iOS 13 o posterior. #### Swift Package Manager Para instalar el SDK, sigue estos pasos: 1. En Xcode, selecciona **Archivo** > **Agregar dependencias de paquetes…** e introduce `https://github.com/stripe/stripe-ios-spm` como URL del repositorio. 1. Selecciona el número de versión más reciente en nuestra [página de versiones](https://github.com/stripe/stripe-ios/releases). 1. Agrega el producto **StripePaymentsUI** al [objetivo de tu aplicación](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app). #### CocoaPods 1. Si aún no lo has hecho, instala la última versión de [CocoaPods](https://guides.cocoapods.org/using/getting-started.html). 1. Si no tienes un [Podfile](https://guides.cocoapods.org/syntax/podfile.html), crea uno al ejecutar el siguiente comando: ```bash pod init ``` 1. Agrega esta línea a tu `Podfile`: ```podfile pod 'StripePaymentsUI' ``` 1. Ejecuta el siguiente comando: ```bash pod install ``` 1. De ahora en adelante, no olvides usar el archivo `.xcworkspace` en lugar del archivo `.xcodeproj` para abrir tu proyecto en Xcode. 1. En el futuro, para actualizar a la última versión del SDK, ejecuta lo siguiente: ```bash pod update StripePaymentsUI ``` #### Carthage 1. Si aún no lo has hecho, instala la última versión de [Carthage](https://github.com/Carthage/Carthage#installing-carthage). 1. Agrega esta línea a tu `Cartfile`: ```cartfile github "stripe/stripe-ios" ``` 1. Sigue las [instrucciones de instalación de Carthage](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos). Asegúrate de incrustar todos los frameworks obligatorios enumerados [aquí](https://github.com/stripe/stripe-ios/tree/master/StripePaymentsUI/README.md#manual-linking). 1. En el futuro, para actualizar a la última versión del SDK, ejecuta el siguiente comando: ```bash carthage update stripe-ios --platform ios ``` #### Framework manual 1. Ve a nuestra [página de versiones de GitHub](https://github.com/stripe/stripe-ios/releases/latest) y descarga y descomprime **Stripe.xcframework.zip**. 1. Arrastra **StripePaymentsUI.xcframework** a la sección **Binarios incrustados** de la configuración **General** de tu proyecto en Xcode. Asegúrate de seleccionar **Copiar elementos si es necesario**. 1. Repite el paso 2 para todos los frameworks obligatorios enumerados [aquí](https://github.com/stripe/stripe-ios/tree/master/StripePaymentsUI/README.md#manual-linking). 1. En el futuro, para actualizar a la última versión de nuestro SDK, repite los pasos 1 a 3. > Para obtener más detalles sobre la última versión del SDK y las versiones anteriores, consulta la página [Versiones](https://github.com/stripe/stripe-ios/releases) en GitHub. Para recibir notificaciones cuando se publique una nueva versión, [mira las versiones](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository) del repositorio. Configura el SDK con tu [clave publicable](https://dashboard.stripe.com/test/apikeys) de Stripe al iniciar la aplicación. Esto permite que tu aplicación haga solicitudes a la API de Stripe. #### Swift ```swift import UIKitimportStripePaymentsUI @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {StripeAPI.defaultPublishableKey = "<>" // do any other necessary launch configuration return true } } ``` > Usa las [claves de prueba](https://docs.stripe.com/keys.md#obtain-api-keys) durante las pruebas y el desarrollo, y tus claves para [modo activo](https://docs.stripe.com/keys.md#test-live-modes) cuando publiques tu aplicación. ## Crear un PaymentIntent [Lado del servidor] [Lado del cliente] Un [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) es un objeto que representa tu intención de cobrar a un cliente y hace el seguimiento del ciclo de vida del proceso de pago en cada etapa. ### Lado del servidor Crea un PaymentIntent en tu servidor con un importe y la moneda `mxn` (OXXO no admite otras monedas). Si ya tienes una integración con la [API Payment Intents](https://docs.stripe.com/payments/payment-intents.md), agrega `oxxo` a la lista de [tipos de métodos](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_types) de pago para tu `PaymentIntent`. #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1099 \ -d "currency"="mxn" \ -d "payment_method_types[]"="oxxo" ``` ### Opciones de métodos de pago adicionales Puedes especificar un parámetro opcional `expires_after_days` en las [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days) de tu `PaymentIntent` que define la cantidad de días calendario que deben pasar para que venza el vale de OXXO. Por ejemplo, si creas un vale de OXXO un lunes y defines `expires_after_days` en 2, el vale vencerá el miércoles a las 23:59, hora de América/Sao_Paulo (UTC-3). El parámetro `expires_after_days` puede ser de 1 a 7 días. El valor predeterminado es de 3 días. ### Lado del cliente Del lado del cliente, solicita un PaymentIntent desde tu servidor y almacena el secreto de cliente. #### Swift ```swift class CheckoutViewController: UIViewController { var paymentIntentClientSecret: String? func startCheckout() { // Request a PaymentIntent from your server and store its client secret } } ``` ## Recopilar datos del método de pago [Lado del cliente] En tu aplicación, recopila los siguientes datos de facturación del cliente. Crea un [STPPaymentIntentParams](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentIntentParams.html) con los datos de facturación. | Campo | Valor | | ------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `name` | El nombre completo (nombre y apellido) del cliente. Tanto el nombre como el apellido deben tener al menos dos caracteres cada uno. | | `email` | La dirección de correo electrónico completa del cliente. | #### Swift ```swift let billingDetails = STPPaymentMethodBillingDetails() billingDetails.name = "Jane Doe" billingDetails.email = "test@example.com" EOF ) ``` ## Enviar el pago a Stripe [Lado del cliente] Recupera el secreto de cliente del PaymentIntent que creaste en el paso 2 y llama a [STPPaymentHandler confirmPayment](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentHandler.html#/c:@M@StripePayments@objc\(cs\)STPPaymentHandler\(im\)confirmPayment:withAuthenticationContext:completion:). Se abrirá una vista web para mostrar el vale OXXO. Al finalizar, se llama al bloque de finalización con el resultado del pago. #### Swift ```swift let paymentIntentParams = STPPaymentIntentParams(clientSecret: paymentIntentClientSecret) let oxxoParams = STPPaymentMethodOXXOParams(); paymentIntentParams.paymentMethodParams = STPPaymentMethodParams( oxxo: oxxoParams, billingDetails: billingDetails, metadata: nil ) STPPaymentHandler.shared().confirmPayment(paymentIntentParams, with: self) { (handlerStatus, paymentIntent, error) in switch handlerStatus { case .succeeded: // The OXXO voucher was displayed successfully. The customer can now pay the OXXO voucher at the OXXO convenience store. case .canceled: // Payment was canceled case .failed: // Payment failed @unknown default: fatalError() } } ``` ### Opcional: enviar al cliente el enlace del vale por correo electrónico Stripe envía un evento [payment_intent.requires_action](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.requires_action) cuando el vale de OXXO se crea correctamente. Si necesitas enviar a tus clientes el enlace del vale por correo electrónico, puedes [recuperar el PaymentIntent](https://docs.stripe.com/api/payment_intents/retrieve.md) para obtener el enlace al recibir el evento. El campo `hosted_voucher_url` en [payment_intent.next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-hosted_voucher_url) contiene el enlace para acceder al vale. ### Opcional: personalizar tu vale Stripe permite la personalización de las interfaces de usuario del cliente en la página de [configuración de imagen de marca](https://dashboard.stripe.com/account/branding). La siguiente configuración de marca puede aplicarse al vale: - **Ícono**: tu imagen de marca y el nombre público de la empresa - **Color de énfasis**: se utiliza como color del botón Copiar número - **Color de la marca**: se utiliza como color de fondo ## Gestionar eventos posteriores al pago [Lado del servidor] OXXO es un método de pago con [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification), de manera que los fondos no están disponibles de inmediato. Puede que el *Cliente* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) no pague el vale OXXO en una tienda de 24 horas inmediatamente después de realizar la compra. Stripe envía un evento [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) el siguiente día hábil (de lunes a viernes, excepto que sea día feriado en México) por cada vale de OXXO pagado. Utiliza el Dashboard o crea un controlador de *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) para recibir estos eventos y ejecutar acciones (por ejemplo, enviar un correo electrónico de confirmación del pedido a tu cliente, registrar la venta en una base de datos o iniciar el flujo de envío). Después de la fecha de vencimiento, el estado del PaymentIntent pasa a ser `processing`, y el cliente ya no puede pagar el vale OXXO vencido. Si el vale no se paga antes de las 23:59, hora de America/Mexico_City (UTC-6) del día del vencimiento, Stripe envía un evento [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) dentro de los 10 días calendario posteriores a la fecha de vencimiento (en la mayoría de los casos, el evento se envía en el término de 7 días calendario). Por ejemplo, si el vale OXXO vence el 1 de septiembre, el evento se envía el 10 de septiembre a más tardar. | Evento | Descripción | Próximos pasos | | -------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | `payment_intent.requires_action` | El vale OXXO se creó correctamente. | Espera a que el cliente pague el vale OXXO. | | `payment_intent.processing` | El cliente ya no puede pagar el vale OXXO. | Espera hasta saber si el pago se concreta o no. | | `payment_intent.succeeded` | El cliente pagó el vale OXXO antes del vencimiento. | Entrega los bienes o servicios que el cliente compró. | | `payment_intent.payment_failed` | El cliente no pagó el vale OXXO antes del vencimiento. | Comunícate con el cliente por correo electrónico o envía una notificación push y solicítale otro método de pago. | ### Recibir eventos y realizar operaciones comerciales #### Manualmente Utiliza el Dashboard de Stripe para ver todos tus pagos en Stripe, enviar recibos por correo electrónico, gestionar transferencias o reintentar pagos fallidos. - [Visualiza tus pagos de prueba en el Dashboard](https://dashboard.stripe.com/test/payments) #### Código personalizado Crea un controlador de webhooks para escuchar eventos y crear flujos de pago asincrónicos personalizados. Prueba y depura tu integración de webhooks en forma local con la CLI de Stripe. - [Build a custom webhook](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) ## Probar la integración En un *entorno de prueba* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes), establece [STPPaymentMethodBillingDetails email](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentMethodBillingDetails.html#/c:@M@StripePayments@objc\(cs\)STPPaymentMethodBillingDetails\(py\)email) en los siguientes valores cuando llames a [STPPaymentHandler confirmPayment](https://stripe.dev/stripe-ios/stripe-payments/Classes/STPPaymentHandler.html#/c:@M@StripePayments@objc\(cs\)STPPaymentHandler\(im\)confirmPayment:withAuthenticationContext:completion:) para probar diferentes escenarios. | Correo electrónico | Descripción | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | Simula un vale OXXO abonado por el cliente al cabo de 3 minutos con el webhook `payment_intent.succeeded` recibido después de 3 minutos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: fulano@test.com | | `{any_prefix}succeed_immediately@{any_domain}` | Simula un vale OXXO abonado por el cliente de inmediato con el webhook `payment_intent.succeeded` recibido después de unos segundos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: succeed_immediately@test.com | | `{any_prefix}expire_immediately@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de unos segundos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) está establecido en la hora actual, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_immediately@test.com | | `{any_prefix}expire_with_delay@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 3 minutos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) se establece en 3 minutos, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_with_delay@test.com | | `{any_prefix}fill_never@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 1 día hábil y 2 días calendario. En modo activo, este webhook llega a la misma hora que en modo de prueba. Ejemplo: fill_never@test.com | ## Vencimiento y cancelación Los vales OXXO vencen después de la marca de tiempo UNIX `expires_after`, y el cliente ya no puede pagar un vale una vez vencido. Los vales OXXO no se pueden cancelar antes de su vencimiento. Después del vencimiento del vale OXXO, el estado del PaymentIntent cambia a `requires_payment_method`. A estas alturas, puedes confirmar el PaymentIntent con otro método de pago o cancelarlo. # Android > This is a Android for when payment-ui is mobile and platform is android. View the full page at https://docs.stripe.com/payments/oxxo/accept-a-payment?payment-ui=mobile&platform=android. > Te recomendamos que sigas la guía [Cómo aceptar un pago](https://docs.stripe.com/payments/accept-a-payment.md) a menos que necesites usar la confirmación manual del lado del servidor o que tu integración requiera que presentes los métodos de pago por separado. Si ya te integraste con Elements, consulta la [guía de migración de Payment Element](https://docs.stripe.com/payments/payment-element/migration.md). Si aceptas OXXO en tu aplicación, se abrirá una vista web del vale OXXO. Los *clientes* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) abonan presentando un vale OXXO con un número y el pago en efectivo efectuado en una tienda OXXO de 24 horas. Stripe te notifica cuando se completa el pago. ## Configurar Stripe [Lado del servidor] [Lado del cliente] Primero, necesitas una cuenta de Stripe. [Inscríbete ahora](https://dashboard.stripe.com/register). ### Lado del servidor Esta integración necesita puntos de conexión en tu servidor que se comuniquen con la API de Stripe. Usa las bibliotecas oficiales para acceder a la API de Stripe desde tu servidor: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### Lado del cliente El [SDK para Android de Stripe](https://github.com/stripe/stripe-android) es de código abierto y está [completamente documentado](https://stripe.dev/stripe-android/). Para instalar el SDK, agrega `stripe-android` al bloque `dependencies` de tu archivo [app/build.gradle](https://developer.android.com/studio/build/dependencies): #### Kotlin ```kotlin plugins { id("com.android.application") } android { ... } dependencies { // ... // Stripe Android SDK implementation("com.stripe:stripe-android:23.0.2") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:23.0.2") } ``` > Para conocer detalles de la última versión y de versiones anteriores del SDK, consulta la página [Versiones](https://github.com/stripe/stripe-android/releases) en GitHub. Para recibir una notificación cuando se publique una nueva versión, [mira las versiones del repositorio](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository). Configura el SDK con tu [clave publicable](https://dashboard.stripe.com/apikeys) de Stripe para que pueda hacer solicitudes a la API de Stripe, así como en tu subclase `Application`: #### Kotlin ```kotlin import com.stripe.android.PaymentConfiguration class MyApp : Application() { override fun onCreate() { super.onCreate() PaymentConfiguration.init( applicationContext, "<>" ) } } ``` > Usa las [claves de prueba](https://docs.stripe.com/keys.md#obtain-api-keys) durante las pruebas y el desarrollo, y tus claves para [modo activo](https://docs.stripe.com/keys.md#test-live-modes) cuando publiques tu aplicación. Los ejemplos de Stripe también utilizan [OkHttp](https://github.com/square/okhttp) y [GSON](https://github.com/google/gson) para hacer solicitudes HTTP a un servidor. ## Crear un PaymentIntent [Lado del servidor] [Lado del cliente] Un [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) es un objeto que representa tu intención de cobrar a un cliente y hace el seguimiento del ciclo de vida del proceso de pago en cada etapa. ### Lado del servidor Crea un PaymentIntent en tu servidor con un importe y la moneda `mxn` (OXXO no admite otras monedas). Si ya tienes una integración con la [API Payment Intents](https://docs.stripe.com/payments/payment-intents.md), agrega `oxxo` a la lista de [tipos de métodos](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_types) de pago para tu `PaymentIntent`. #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1099 \ -d "currency"="mxn" \ -d "payment_method_types[]"="oxxo" ``` ### Opciones de métodos de pago adicionales Puedes especificar un parámetro opcional `expires_after_days` en las [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days) de tu `PaymentIntent` que define la cantidad de días calendario que deben pasar para que venza el vale de OXXO. Por ejemplo, si creas un vale de OXXO un lunes y defines `expires_after_days` en 2, el vale vencerá el miércoles a las 23:59, hora de América/Sao_Paulo (UTC-3). El parámetro `expires_after_days` puede ser de 1 a 7 días. El valor predeterminado es de 3 días. ### Lado del cliente Del lado del cliente, solicita un PaymentIntent desde tu servidor y almacena el secreto de cliente. #### Kotlin ```kotlin class OXXOActivity: AppCompatActivity() { private lateinit var paymentIntentClientSecret: String private fun startCheckout() { // Request a PaymentIntent from your server and store its client secret } } ``` ## Recopilar datos del método de pago [Lado del cliente] En tu aplicación, obtén del cliente los siguientes datos de facturación requeridos. Crea un [PaymentMethodCreateParams](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-payment-method-create-params/index.html) con los datos de facturación. | Campo | Valor | | ------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `name` | El nombre completo (nombre y apellido) del cliente. Tanto el nombre como el apellido deben tener al menos dos caracteres cada uno. | | `email` | La dirección de correo electrónico completa del cliente. | #### Kotlin ```kotlin val billingDetails = PaymentMethod.BillingDetails(email = "email@email.com", name = "Jenny Rosen") val paymentMethodCreateParams = PaymentMethodCreateParams.createOxxo(billingDetails) ``` ## Enviar el pago a Stripe [Lado del cliente] Recupera el secreto de cliente del PaymentIntent que creaste en el paso 2 y llama a [PaymentLauncher confirm](https://stripe.dev/stripe-android/payments-core/com.stripe.android.payments.paymentlauncher/-payment-launcher/index.html#74063765%2FFunctions%2F-1622557690). Se abrirá una vista web del vale OXXO. Luego, se llama a `onPaymentResult` con el resultado del pago. #### Kotlin ```kotlin class OXXOActivity : AppCompatActivity() { // ... private lateinit var paymentIntentClientSecret: String private val paymentLauncher: PaymentLauncher by lazy { val paymentConfiguration = PaymentConfiguration.getInstance(applicationContext) PaymentLauncher.Companion.create( this, paymentConfiguration.publishableKey, paymentConfiguration.stripeAccountId, ::onPaymentResult ) } private fun startCheckout() { // ... val confirmParams = ConfirmPaymentIntentParams .createWithPaymentMethodCreateParams( paymentMethodCreateParams = paymentMethodCreateParams, clientSecret = paymentIntentClientSecret ) paymentLauncher.confirm(confirmParams) } private fun onPaymentResult(paymentResult: PaymentResult) { when (paymentResult) { is PaymentResult.Completed -> { // The OXXO voucher was displayed successfully. // The customer can now pay the OXXO voucher at the OXXO convenience store. } is PaymentResult.Canceled -> { // handle cancel flow } is PaymentResult.Failed -> { // handle failures // (for example, the customer may need to choose a new payment // method) } } } } ``` ### Opcional: enviar al cliente el enlace del vale por correo electrónico Stripe envía un evento [payment_intent.requires_action](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.requires_action) cuando el vale de OXXO se crea correctamente. Si necesitas enviar a tus clientes el enlace del vale por correo electrónico, puedes [recuperar el PaymentIntent](https://docs.stripe.com/api/payment_intents/retrieve.md) para obtener el enlace al recibir el evento. El campo `hosted_voucher_url` en [payment_intent.next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-hosted_voucher_url) contiene el enlace para acceder al vale. ### Opcional: personalizar tu vale Stripe permite la personalización de las interfaces de usuario del cliente en la página de [configuración de imagen de marca](https://dashboard.stripe.com/account/branding). La siguiente configuración de marca puede aplicarse al vale: - **Ícono**: tu imagen de marca y el nombre público de la empresa - **Color de énfasis**: se utiliza como color del botón Copiar número - **Color de la marca**: se utiliza como color de fondo ## Gestionar eventos posteriores al pago [Lado del servidor] OXXO es un método de pago con [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification), de manera que los fondos no están disponibles de inmediato. Puede que el *Cliente* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) no pague el vale OXXO en una tienda de 24 horas inmediatamente después de realizar la compra. Stripe envía un evento [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) el siguiente día hábil (de lunes a viernes, excepto que sea día feriado en México) por cada vale de OXXO pagado. Utiliza el Dashboard o crea un controlador de *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) para recibir estos eventos y ejecutar acciones (por ejemplo, enviar un correo electrónico de confirmación del pedido a tu cliente, registrar la venta en una base de datos o iniciar el flujo de envío). Después de la fecha de vencimiento, el estado del PaymentIntent pasa a ser `processing`, y el cliente ya no puede pagar el vale OXXO vencido. Si el vale no se paga antes de las 23:59, hora de America/Mexico_City (UTC-6) del día del vencimiento, Stripe envía un evento [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) dentro de los 10 días calendario posteriores a la fecha de vencimiento (en la mayoría de los casos, el evento se envía en el término de 7 días calendario). Por ejemplo, si el vale OXXO vence el 1 de septiembre, el evento se envía el 10 de septiembre a más tardar. | Evento | Descripción | Próximos pasos | | -------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | `payment_intent.requires_action` | El vale OXXO se creó correctamente. | Espera a que el cliente pague el vale OXXO. | | `payment_intent.processing` | El cliente ya no puede pagar el vale OXXO. | Espera hasta saber si el pago se concreta o no. | | `payment_intent.succeeded` | El cliente pagó el vale OXXO antes del vencimiento. | Entrega los bienes o servicios que el cliente compró. | | `payment_intent.payment_failed` | El cliente no pagó el vale OXXO antes del vencimiento. | Comunícate con el cliente por correo electrónico o envía una notificación push y solicítale otro método de pago. | ### Recibir eventos y realizar operaciones comerciales #### Manualmente Utiliza el Dashboard de Stripe para ver todos tus pagos en Stripe, enviar recibos por correo electrónico, gestionar transferencias o reintentar pagos fallidos. - [Visualiza tus pagos de prueba en el Dashboard](https://dashboard.stripe.com/test/payments) #### Código personalizado Crea un controlador de webhooks para escuchar eventos y crear flujos de pago asincrónicos personalizados. Prueba y depura tu integración de webhooks en forma local con la CLI de Stripe. - [Build a custom webhook](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) ## Probar la integración En el entorno de prueba, establece [PaymentMethod.BillingDetails#email](https://stripe.dev/stripe-android/payments-core/com.stripe.android.model/-payment-method/-billing-details/index.html) en los siguientes valores cuando llames a [Stripe\# confirmPayment()](https://stripe.dev/stripe-android/payments-core/com.stripe.android/-stripe/confirm-payment.html) para probar diferentes escenarios. | Correo electrónico | Descripción | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | Simula un vale OXXO abonado por el cliente al cabo de 3 minutos con el webhook `payment_intent.succeeded` recibido después de 3 minutos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: fulano@test.com | | `{any_prefix}succeed_immediately@{any_domain}` | Simula un vale OXXO abonado por el cliente de inmediato con el webhook `payment_intent.succeeded` recibido después de unos segundos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: succeed_immediately@test.com | | `{any_prefix}expire_immediately@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de unos segundos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) está establecido en la hora actual, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_immediately@test.com | | `{any_prefix}expire_with_delay@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 3 minutos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) se establece en 3 minutos, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_with_delay@test.com | | `{any_prefix}fill_never@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 1 día hábil y 2 días calendario. En modo activo, este webhook llega a la misma hora que en modo de prueba. Ejemplo: fill_never@test.com | ## Vencimiento y cancelación Los vales OXXO vencen después de la marca de tiempo UNIX `expires_after`, y el cliente ya no puede pagar un vale una vez vencido. Los vales OXXO no se pueden cancelar antes de su vencimiento. Después del vencimiento del vale OXXO, el estado del PaymentIntent cambia a `requires_payment_method`. A estas alturas, puedes confirmar el PaymentIntent con otro método de pago o cancelarlo. # React Native > This is a React Native for when payment-ui is mobile and platform is react-native. View the full page at https://docs.stripe.com/payments/oxxo/accept-a-payment?payment-ui=mobile&platform=react-native. > Te recomendamos que sigas la guía [Cómo aceptar un pago](https://docs.stripe.com/payments/accept-a-payment.md) a menos que necesites usar la confirmación manual del lado del servidor o que tu integración requiera que presentes los métodos de pago por separado. Si ya te integraste con Elements, consulta la [guía de migración de Payment Element](https://docs.stripe.com/payments/payment-element/migration.md). Si aceptas OXXO en tu aplicación, se abrirá una vista web del vale OXXO. Los *clientes* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) abonan presentando un vale OXXO con un número y el pago en efectivo efectuado en una tienda OXXO de 24 horas. Stripe te notifica cuando se completa el pago. ## Configurar Stripe [Lado del servidor] [Lado del cliente] ### Lado del servidor Esta integración necesita puntos de conexión en tu servidor que se comuniquen con la API de Stripe. Usa nuestras bibliotecas oficiales para acceder a la API de Stripe desde tu servidor: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ### Lado del cliente El [SDK para React Native](https://github.com/stripe/stripe-react-native) es de código abierto y está plenamente documentado. Internamente, utiliza SDK para [iOS nativo](https://github.com/stripe/stripe-ios) y [Android](https://github.com/stripe/stripe-android). Para instalar el SDK para React Native de Stripe, ejecuta uno de los siguientes comandos en el directorio del proyecto (según el administrador de paquetes que utilices): #### hilado ```bash yarn add @stripe/stripe-react-native ``` #### npm ```bash npm install @stripe/stripe-react-native ``` A continuación, instala otras dependencias necesarias: - Para iOS, vaya al directorio **ios** y ejecute `pod install` para asegurarse de que también instala las dependencias nativas necesarias. - Para Android, no hay más dependencias para instalar. > Recomendamos seguir la [guía oficial de TypeScript](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project) para agregar soporte para TypeScript. ### Inicialización de Stripe Para inicializar Stripe en tu aplicación React Native, ajusta tu pantalla de pago con el componente `StripeProvider` o usa el método de inicialización `initStripe`. Solo se requiere la [clave publicable](https://docs.stripe.com/keys.md#obtain-api-keys) de la API en `publishableKey`. El siguiente ejemplo muestra cómo inicializar Stripe usando el componente `StripeProvider`. ```jsx import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( {/* Your app code here */} ); } ``` > Usa las [claves de prueba](https://docs.stripe.com/keys.md#obtain-api-keys) de la API durante las pruebas y el desarrollo, y tus claves para [modo activo](https://docs.stripe.com/keys.md#test-live-modes) cuando publiques tu aplicación. ## Crear un PaymentIntent [Lado del servidor] [Lado del cliente] Un [PaymentIntent](https://docs.stripe.com/api/payment_intents/object.md) es un objeto que representa tu intención de cobrar a un cliente y hace el seguimiento del ciclo de vida del proceso de pago en cada etapa. ### Lado del servidor Crea un PaymentIntent en tu servidor con un importe y la moneda `mxn` (OXXO no admite otras monedas). Si ya tienes una integración con la [API Payment Intents](https://docs.stripe.com/payments/payment-intents.md), agrega `oxxo` a la lista de [tipos de métodos](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_types) de pago para tu `PaymentIntent`. #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1099 \ -d "currency"="mxn" \ -d "payment_method_types[]"="oxxo" ``` ### Opciones de métodos de pago adicionales Puedes especificar un parámetro opcional `expires_after_days` en las [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days) de tu `PaymentIntent` que define la cantidad de días calendario que deben pasar para que venza el vale de OXXO. Por ejemplo, si creas un vale de OXXO un lunes y defines `expires_after_days` en 2, el vale vencerá el miércoles a las 23:59, hora de América/Sao_Paulo (UTC-3). El parámetro `expires_after_days` puede ser de 1 a 7 días. El valor predeterminado es de 3 días. ### Lado del cliente Del lado del cliente, solicita un PaymentIntent desde tu servidor y almacena el *secreto de cliente* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)). ```javascript const fetchPaymentIntentClientSecret = async () => { const response = await fetch(`${API_URL}/create-payment-intent`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, currency: 'mxn', payment_method_types: ['oxxo'], }), }); const {clientSecret, error} = await response.json(); return {clientSecret, error}; }; ``` ## Recopilar datos del método de pago [Lado del cliente] En tu aplicación, recopila el nombre completo y la dirección de correo electrónico del cliente. ```javascript export default function OxxoPaymentScreen() { const [name, setName] = useState(); const [email, setEmail] = useState(); const handlePayPress = async () => { // ... }; return ( setName(value.nativeEvent.text)} /> setEmail(value.nativeEvent.text)} /> ); } ``` ## Enviar el pago a Stripe [Lado del cliente] Recupera el secreto de cliente del PaymentIntent que creaste y llama a `confirmPayment`. Se abrirá una vista web para mostrar el vale OXXO. ```javascript export default function OxxoPaymentScreen() { const [name, setName] = useState(); const [email, setEmail] = useState(); const handlePayPress = async () => { const billingDetails: PaymentMethodCreateParams.BillingDetails = { name, email, }; const { error, paymentIntent } = await confirmPayment(clientSecret, { paymentMethodType: 'Oxxo', paymentMethodData: { billingDetails, } }); if (error) { Alert.alert(`Error code: ${error.code}`, error.message); console.log('Payment confirmation error', error.message); } else if (paymentIntent) { if (paymentIntent.status === PaymentIntents.Status.RequiresAction) { Alert.alert( 'Success', `The OXXO voucher was created successfully. Awaiting payment from customer.` ); } else { Alert.alert('Payment intent status:', paymentIntent.status); } } }; return ( setName(value.nativeEvent.text)} /> setEmail(value.nativeEvent.text)} /> ); } ``` ### Opcional: enviar al cliente el enlace del vale por correo electrónico Stripe envía un evento [payment_intent.requires_action](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.requires_action) cuando el vale de OXXO se crea correctamente. Si necesitas enviar a tus clientes el enlace del vale por correo electrónico, puedes [recuperar el PaymentIntent](https://docs.stripe.com/api/payment_intents/retrieve.md) para obtener el enlace al recibir el evento. El campo `hosted_voucher_url` en [payment_intent.next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-hosted_voucher_url) contiene el enlace para acceder al vale. ### Opcional: personalizar tu vale Stripe permite la personalización de las interfaces de usuario del cliente en la página de [configuración de imagen de marca](https://dashboard.stripe.com/account/branding). La siguiente configuración de marca puede aplicarse al vale: - **Ícono**: tu imagen de marca y el nombre público de la empresa - **Color de énfasis**: se utiliza como color del botón Copiar número - **Color de la marca**: se utiliza como color de fondo ## Gestionar eventos posteriores al pago [Lado del servidor] OXXO es un método de pago con [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification), de manera que los fondos no están disponibles de inmediato. Puede que el *Cliente* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) no pague el vale OXXO en una tienda de 24 horas inmediatamente después de realizar la compra. Stripe envía un evento [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) el siguiente día hábil (de lunes a viernes, excepto que sea día feriado en México) por cada vale de OXXO pagado. Utiliza el Dashboard o crea un controlador de *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) para recibir estos eventos y ejecutar acciones (por ejemplo, enviar un correo electrónico de confirmación del pedido a tu cliente, registrar la venta en una base de datos o iniciar el flujo de envío). Después de la fecha de vencimiento, el estado del PaymentIntent pasa a ser `processing`, y el cliente ya no puede pagar el vale OXXO vencido. Si el vale no se paga antes de las 23:59, hora de America/Mexico_City (UTC-6) del día del vencimiento, Stripe envía un evento [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) dentro de los 10 días calendario posteriores a la fecha de vencimiento (en la mayoría de los casos, el evento se envía en el término de 7 días calendario). Por ejemplo, si el vale OXXO vence el 1 de septiembre, el evento se envía el 10 de septiembre a más tardar. | Evento | Descripción | Próximos pasos | | -------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | `payment_intent.requires_action` | El vale OXXO se creó correctamente. | Espera a que el cliente pague el vale OXXO. | | `payment_intent.processing` | El cliente ya no puede pagar el vale OXXO. | Espera hasta saber si el pago se concreta o no. | | `payment_intent.succeeded` | El cliente pagó el vale OXXO antes del vencimiento. | Entrega los bienes o servicios que el cliente compró. | | `payment_intent.payment_failed` | El cliente no pagó el vale OXXO antes del vencimiento. | Comunícate con el cliente por correo electrónico o envía una notificación push y solicítale otro método de pago. | ### Recibir eventos y realizar operaciones comerciales #### Manualmente Utiliza el Dashboard de Stripe para ver todos tus pagos en Stripe, enviar recibos por correo electrónico, gestionar transferencias o reintentar pagos fallidos. - [Visualiza tus pagos de prueba en el Dashboard](https://dashboard.stripe.com/test/payments) #### Código personalizado Crea un controlador de webhooks para escuchar eventos y crear flujos de pago asincrónicos personalizados. Prueba y depura tu integración de webhooks en forma local con la CLI de Stripe. - [Build a custom webhook](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) ## Probar la integración En el entorno de prueba, usa los siguientes correos electrónicos cuando llames a `confirmPayment` para probar diferentes escenarios. | Correo electrónico | Descripción | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | Simula un vale OXXO abonado por el cliente al cabo de 3 minutos con el webhook `payment_intent.succeeded` recibido después de 3 minutos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: fulano@test.com | | `{any_prefix}succeed_immediately@{any_domain}` | Simula un vale OXXO abonado por el cliente de inmediato con el webhook `payment_intent.succeeded` recibido después de unos segundos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: succeed_immediately@test.com | | `{any_prefix}expire_immediately@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de unos segundos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) está establecido en la hora actual, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_immediately@test.com | | `{any_prefix}expire_with_delay@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 3 minutos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) se establece en 3 minutos, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_with_delay@test.com | | `{any_prefix}fill_never@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 1 día hábil y 2 días calendario. En modo activo, este webhook llega a la misma hora que en modo de prueba. Ejemplo: fill_never@test.com | ## Vencimiento y cancelación Los vales OXXO vencen después de la marca de tiempo UNIX `expires_after`, y el cliente ya no puede pagar un vale una vez vencido. Los vales OXXO no se pueden cancelar antes de su vencimiento. Después del vencimiento del vale OXXO, el estado del PaymentIntent cambia a `requires_payment_method`. A estas alturas, puedes confirmar el PaymentIntent con otro método de pago o cancelarlo. # Directo en las API > This is a Directo en las API for when payment-ui is direct-api. View the full page at https://docs.stripe.com/payments/oxxo/accept-a-payment?payment-ui=direct-api. > El contenido de esta sección se refiere a un producto *heredado* (Technology that's no longer recommended). En cambio, debes usar la guía [Aceptar un pago](https://docs.stripe.com/payments/accept-a-payment.md) para la ruta de integración más reciente. Si bien Stripe aún admite este producto, el soporte podría finalizar si el producto queda obsoleto. En México, los usuarios de Stripe pueden aceptar pagos OXXO de clientes en México usando las API Payment Intents y Payment Methods. Los *clientes* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) abonan presentando un vale OXXO con un número y el pago en efectivo efectuado en una tienda OXXO de 24 horas. Stripe te notifica cuando se completa el pago. ## Configurar Stripe [Lado del servidor] Primero, necesitas una cuenta de Stripe. [Inscríbete ahora](https://dashboard.stripe.com/test/register). Usa nuestras bibliotecas oficiales para acceder a la API de Stripe desde tu aplicación: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Crear un PaymentIntent [Lado del servidor] Stripe usa un objeto [PaymentIntent](https://docs.stripe.com/api/payment_intents.md) para representar tu intención de cobrar a un cliente y hace el seguimiento de los cambios de estado desde la creación del vale OXXO hasta que se completa el pago. Crea un PaymentIntent en tu servidor con un importe y la moneda `mxn` (OXXO no admite otras monedas). Si ya tienes una integración con la [API Payment Intents](https://docs.stripe.com/payments/payment-intents.md), agrega `oxxo` a la lista de [tipos de métodos](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_types) de pago para tu `PaymentIntent`. #### curl ```bash curl https://api.stripe.com/v1/payment_intents \ -u <>: \ -d "amount"=1099 \ -d "currency"="mxn" \ -d "payment_method_types[]"="oxxo" ``` ### Recuperar el secreto de cliente El PaymentIntent incluye un *secreto de cliente* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) que el lado del cliente usa para completar el proceso de pago de forma segura. Puedes usar diferentes métodos para pasar el secreto del cliente al lado del cliente. #### Aplicación de una sola página Recupera el secreto de cliente de un punto de conexión de tu servidor con la funcionalidad `fetch` del navegador. Este método es más conveniente si tu lado del cliente es una aplicación de una sola página, especialmente, si fue diseñada con un marco de front-end moderno como React. Crea el punto de conexión del servidor que se usa para el secreto de cliente: #### Ruby ```ruby get '/secret' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end ``` Luego recupera el secreto de cliente con JavaScript del lado del cliente: ```javascript (async () => { const response = await fetch('/secret'); const {client_secret: clientSecret} = await response.json(); // Render the form using the clientSecret })(); ``` #### Renderización del lado del servidor Especifica el secreto de cliente desde tu servidor al cliente. Este enfoque funciona mejor si tu aplicación genera contenido estático en el servidor antes de enviarlo al navegador. Agrega [client_secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) en tu formulario de finalización de compra. En el código del lado de tu servidor, recupera el secreto de cliente de PaymentIntent: #### Ruby ```erb
``` ```ruby get '/checkout' do @intent = # ... Fetch or create the PaymentIntent erb :checkout end ``` ### Opciones de métodos de pago adicionales Puedes especificar un parámetro opcional `expires_after_days` en las [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days) de tu `PaymentIntent` que define la cantidad de días calendario que deben pasar para que venza el vale de OXXO. Por ejemplo, si creas un vale de OXXO un lunes y defines `expires_after_days` en 2, el vale vencerá el miércoles a las 23:59, hora de América/Sao_Paulo (UTC-3). El parámetro `expires_after_days` puede ser de 1 a 7 días. El valor predeterminado es de 3 días. ## Recopilar datos del método de pago [Lado del cliente] Crea un formulario de pago del lado de tu cliente para recopilar los datos de facturación necesarios: | Campo | Valor | | ------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `name` | El nombre completo (nombre y apellido) del cliente. Tanto el nombre como el apellido deben tener al menos dos caracteres cada uno. | | `email` | La dirección de correo electrónico completa del cliente. | ```html
``` ## Enviar el pago a Stripe [Lado del cliente] Cuando el cliente hace clic para pagar con OXXO, usa Stripe.js para enviar el pago a Stripe. [Stripe.js](https://docs.stripe.com/payments/elements.md) es nuestra biblioteca principal de JavaScript para crear flujos de pago. Incluye el script de Stripe.js en tu página de finalización de compra agregándolo al `head` de tu archivo HTML. ```html Checkout ``` Crea una instancia de Stripe.js con el siguiente JavaScript en tu página de pago. ```javascript // Set your publishable key. Remember to switch to your live publishable key in production! // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe('<>'); ``` Usa [stripe.confirmOxxoPayment](https://docs.stripe.com/js/payment_intents/confirm_oxxo_payment) y el [secreto de cliente](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) del objeto `PaymentIntent` que creaste en el Paso 2 para enviar los datos de pagos del cliente. Una vez recibida la confirmación, Stripe abrirá automáticamente un cuadro de diálogo para mostrar el vale OXXO al cliente. ```javascript const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const result = await stripe.confirmOxxoPayment( '{{PAYMENT_INTENT_CLIENT_SECRET}}', { payment_method: { billing_details: { name: document.getElementById('name').value, email: document.getElementById('email').value, }, }, }); // Stripe.js will open a modal to display the OXXO voucher to your customer // This async function finishes when the customer closes the modal if (result.error) { // Display error to your customer const errorMsg = document.getElementById('error-message'); errorMsg.innerText = result.error.message; } }); ``` > `stripe.confirmOxxoPayment` puede tardar varios segundos en completarse. Durante ese tiempo, deshabilita tu formulario para no reenviarlo y muestra un indicador de espera, por ejemplo, un indicador giratorio. Si recibes un mensaje de error, muéstraselo al cliente, vuelve a habilitar el formulario y oculta el indicador de espera. Cuando se crea un vale OXXO correctamente, el valor de la propiedad `status` del PaymentIntent devuelto es `requires_action`. Comprueba el estado del PaymentIntent en el [Dashboard](https://dashboard.stripe.com/test/payments) o examina la propiedad de estado en el objeto. Si el vale OXXO no se creó correctamente, examina el mensaje de `error` que da el sistema para determinar la causa (p. ej., formato del correo electrónico no válido). ### Opcional: enviar al cliente el enlace del vale por correo electrónico Stripe envía un evento [payment_intent.requires_action](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.requires_action) cuando el vale de OXXO se crea correctamente. Si necesitas enviar a tus clientes el enlace del vale por correo electrónico, puedes [recuperar el PaymentIntent](https://docs.stripe.com/api/payment_intents/retrieve.md) para obtener el enlace al recibir el evento. El campo `hosted_voucher_url` en [payment_intent.next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-hosted_voucher_url) contiene el enlace para acceder al vale. ### Opcional: personalizar tu vale Stripe permite la personalización de las interfaces de usuario del cliente en la página de [configuración de imagen de marca](https://dashboard.stripe.com/account/branding). La siguiente configuración de marca puede aplicarse al vale: - **Ícono**: tu imagen de marca y el nombre público de la empresa - **Color de énfasis**: se utiliza como color del botón Copiar número - **Color de la marca**: se utiliza como color de fondo ## Gestionar eventos posteriores al pago [Lado del servidor] OXXO es un método de pago con [notificación diferida](https://docs.stripe.com/payments/payment-methods.md#payment-notification), de manera que los fondos no están disponibles de inmediato. Puede que el *Cliente* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) no pague el vale OXXO en una tienda de 24 horas inmediatamente después de realizar la compra. Stripe envía un evento [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded) el siguiente día hábil (de lunes a viernes, excepto que sea día feriado en México) por cada vale de OXXO pagado. Utiliza el Dashboard o crea un controlador de *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) para recibir estos eventos y ejecutar acciones (por ejemplo, enviar un correo electrónico de confirmación del pedido a tu cliente, registrar la venta en una base de datos o iniciar el flujo de envío). Después de la fecha de vencimiento, el estado del PaymentIntent pasa a ser `processing`, y el cliente ya no puede pagar el vale OXXO vencido. Si el vale no se paga antes de las 23:59, hora de America/Mexico_City (UTC-6) del día del vencimiento, Stripe envía un evento [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.payment_failed) dentro de los 10 días calendario posteriores a la fecha de vencimiento (en la mayoría de los casos, el evento se envía en el término de 7 días calendario). Por ejemplo, si el vale OXXO vence el 1 de septiembre, el evento se envía el 10 de septiembre a más tardar. | Evento | Descripción | Próximos pasos | | -------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | | `payment_intent.requires_action` | El vale OXXO se creó correctamente. | Espera a que el cliente pague el vale OXXO. | | `payment_intent.processing` | El cliente ya no puede pagar el vale OXXO. | Espera hasta saber si el pago se concreta o no. | | `payment_intent.succeeded` | El cliente pagó el vale OXXO antes del vencimiento. | Entrega los bienes o servicios que el cliente compró. | | `payment_intent.payment_failed` | El cliente no pagó el vale OXXO antes del vencimiento. | Comunícate con el cliente por correo electrónico o envía una notificación push y solicítale otro método de pago. | ### Recibir eventos y realizar operaciones comerciales #### Manualmente Utiliza el Dashboard de Stripe para ver todos tus pagos en Stripe, enviar recibos por correo electrónico, gestionar transferencias o reintentar pagos fallidos. - [Visualiza tus pagos de prueba en el Dashboard](https://dashboard.stripe.com/test/payments) #### Código personalizado Crea un controlador de webhooks para escuchar eventos y crear flujos de pago asincrónicos personalizados. Prueba y depura tu integración de webhooks en forma local con la CLI de Stripe. - [Build a custom webhook](https://docs.stripe.com/webhooks/handling-payment-events.md#build-your-own-webhook) ## Probar la integración En el entorno de prueba, establece `payment_method.billing_details.email` en los siguientes valores cuando llames a [stripe.confirmOxxoPayment](https://docs.stripe.com/js/payment_intents/confirm_oxxo_payment) para probar diferentes escenarios. | Correo electrónico | Descripción | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `{any_prefix}@{any_domain}` | Simula un vale OXXO abonado por el cliente al cabo de 3 minutos con el webhook `payment_intent.succeeded` recibido después de 3 minutos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: fulano@test.com | | `{any_prefix}succeed_immediately@{any_domain}` | Simula un vale OXXO abonado por el cliente de inmediato con el webhook `payment_intent.succeeded` recibido después de unos segundos. En modo activo, este webhook llega después de 1 día hábil. Ejemplo: succeed_immediately@test.com | | `{any_prefix}expire_immediately@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de unos segundos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) está establecido en la hora actual, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_immediately@test.com | | `{any_prefix}expire_with_delay@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 3 minutos. El campo `expires_after` en [next_action.oxxo_display_details](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after) se establece en 3 minutos, independientemente de cómo esté definido el parámetro `expires_after_days` en [opciones de métodos de pago](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-payment_method_options-oxxo-expires_after_days). Ejemplo: expire_with_delay@test.com | | `{any_prefix}fill_never@{any_domain}` | Simula un vale OXXO que venza antes de que pague el cliente con el webhook `payment_intent.payment_failed` recibido después de 1 día hábil y 2 días calendario. En modo activo, este webhook llega a la misma hora que en modo de prueba. Ejemplo: fill_never@test.com | ## Optional: Muestra los datos de OXXO a tu cliente [Lado del cliente] Te recomendamos que uses Stripe.js para mostrar en pantalla el vale OXXO con `confirmOxxoPayment`. No obstante, también puedes presentar manualmente el vale a tus clientes. Puedes especificar `handleActions: false` al llamar a `stripe.confirmOxxoPayment` en el paso 4 para indicar que te encargarás de la siguiente acción de mostrar los datos de OXXO a tu cliente. ```javascript const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const result = await stripe.confirmOxxoPayment( '{{PAYMENT_INTENT_CLIENT_SECRET}}', { payment_method: { billing_details: { name: document.getElementById('name').value, email: document.getElementById('email').value, }, }, }, {handleActions: false}, ); if (result.error) { // Display error to your customer const errorMsg = document.getElementById('error-message'); errorMsg.innerText = result.error.message; } else { // An OXXO voucher was successfully created const amount = result.paymentIntent.amount; const currency = result.paymentIntent.currency; const details = result.paymentIntent.next_action.oxxo_display_details; const number = details.number; const expires_after = details.expires_after; // Handle the next action by displaying the OXXO details to your customer // You can also use the generated hosted voucher const hosted_voucher_url = result.paymentIntent.next_action.oxxo_display_details.hosted_voucher_url; } }); ``` Incluye, como mínimo, lo siguiente: | Detalle | Descripción | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Logotipo de OXXO | [Descargar](https://stripe.com/img/docs/payments/oxxo.png) y mostrar el logotipo de OXXO en el vale. oxxo | | Número | Busca el número en el objeto `PaymentIntent` en [next_action.oxxo_display_details.number](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-number). | | Fecha de vencimiento | Busca la marca de tiempo UNIX después de la cual vence el vale OXXO en el `PaymentIntent` en [next_action.oxxo_display_details.expires_after](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-next_action-oxxo_display_details-expires_after). | | Importe | El importe que se cobrará. | | Moneda | Los vales OXXO siempre se expresan en pesos mexicanos. | | Código de barras | Genera el código de barras a partir del número con el [Código 128](https://en.wikipedia.org/wiki/Code_128). El código de barras debe tener aproximadamente 7.5 cm de ancho una vez impreso. Para las pantallas de dispositivos móviles, asegúrate de que el código de barras pueda ampliarse. De esta forma, el cajero de la tienda OXXO de 24 horas podrá escanearlo mejor. Puedes usar una biblioteca externa como [JSBarcode](https://lindell.me/JsBarcode/). | | Instrucciones de pago | Las instrucciones de pago para el cliente. A continuación, encontrarás las traducciones al inglés y al español. | ### Instrucciones de pago en tiendas OXXO #### Inglés OXXO payment instructions: 1. Give the voucher to the cashier to scan the barcode. 1. Provide cash payment to the cashier. 1. After the payment is complete, keep the receipt of your payment for your records. 1. Para cualquier duda o aclaración, ponte en contacto con la empresa. #### HTML ```html
MX
Expires
Instructions to pay your OXXO:
  1. Give the voucher to the cashier to scan the barcode.

  2. Provide cash payment to the cashier.

  3. After the payment is complete, keep the receipt of your payment for your records.

  4. For any questions or clarification, please contact the merchant.

``` #### Español Instrucciones de pago en OXXO: 1. Entregue el código al cajero en cualquier OXXO para que lo escanee. 1. Proporcione el pago en efectivo al cajero. 1. Una vez completado el pago, guarde el recibo de su pago para sus archivos. 1. Para cualquier duda o aclaración, por favor contacte al comerciante. #### HTML ```html
MX
Expira el
Instrucciones de pago en OXXO:
  1. Entregue el código al cajero en cualquier OXXO para que lo escanee.

  2. Proporcione el pago en efectivo al cajero.

  3. Una vez completado el pago, guarde el recibo de su pago para sus archivos.

  4. Para cualquier duda o aclaración, por favor contacte al comerciante.

``` Los *clientes* (Customer objects represent customers of your business. They let you reuse payment methods and give you the ability to track multiple payments) suelen imprimir el vale OXXO para llevarlo a la tienda OXXO. Puedes ofrecerles un botón para que lo impriman o enviarles el vale por correo electrónico. Haz la prueba de imprimir un vale OXXO para verificar el tamaño del código de barras (que debe tener aproximadamente 7.5 cm de ancho). ## Optional: Enviar correos electrónicos con instrucciones de pago Puedes habilitar los correos electrónicos con instrucciones de pago con OXXO en la página de [configuración de correo electrónico](https://dashboard.stripe.com/settings/emails) en el Dashboard. Una vez habilitados, Stripe envía estos correos cuando se confirma el PaymentIntent. Los correos contienen el número de OXXO y un enlace a la página del vale alojada en Stripe. > En los entornos de prueba, los correos electrónicos con instrucciones solo se envían a las direcciones de correo vinculadas a la cuenta de Stripe. ## Vencimiento y cancelación Los vales OXXO vencen después de la marca de tiempo UNIX `expires_after`, y el cliente ya no puede pagar un vale una vez vencido. Los vales OXXO no se pueden cancelar antes de su vencimiento. Después del vencimiento del vale OXXO, el estado del PaymentIntent cambia a `requires_payment_method`. A estas alturas, puedes confirmar el PaymentIntent con otro método de pago o cancelarlo.