# Completa pedidos Aprende a ejecutar los pagos recibidos con la API Checkout Sessions. # Hosted page > This is a Hosted page for when payment-ui is stripe-hosted. View the full page at https://docs.stripe.com/checkout/fulfillment?payment-ui=stripe-hosted. When you receive a payment with the Checkout Sessions API (including Payment Links), you might need to take action to provide your customer with what they paid for. For example, you might need to grant them access to a service, or you might need to ship them physical goods. This process is known as fulfillment, and you have two ways to handle this process: - **Manual**: puedes completar los pedidos manualmente con la información que Stripe pone a tu disposición. Por ejemplo, puedes supervisar el [Dashboard](https://docs.stripe.com/dashboard/basics.md), verificar los correos electrónicos de notificación de pagos, consultar los informes y, luego, completar los pedidos. - **Automáticamente**: puedes crear un sistema de gestión logística automatizado. (Recommended) The first option works for low volume or experimental ventures, but for most situations we recommend automating fulfillment. The rest of this guide shows you how to build an automatic fulfillment system. ## Cumplimiento de ejecución de un pedido The automatic fulfillment system outlined below uses a combination of *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) and a redirect to your website to trigger fulfillment. You must use webhooks to make sure fulfillment happens for every payment, and redirects let your customers access services or fulfillment details immediately after paying. > Payment Links usa Checkout, por lo que toda la información que se encuentra a continuación se aplica tanto a Payment Links como a Checkout, a menos que se indique lo contrario. ## Crea una función de confirmación de pedido [Lado del servidor] Crea una función en tu servidor para completar los pagos efectuados correctamente. Los webhooks activan esta función, y se la llama cuando se remite a los clientes a tu sitio web después de completar el proceso de compra. Esta guía se refiere a esta función como `fulfill_checkout`, pero puedes nombrarla como quieras. Perform fulfillment only once per payment. Because of how this integration and the internet work, your `fulfill_checkout` function might be called multiple times, possibly concurrently, for the same Checkout Session. Performing checkout only once ensures this won’t cause undesired behavior. La función `fulfill_checkout` debe hacer lo siguiente: 1. Gestionar correctamente las llamadas múltiples con la mismo ID de la Checkout Session. 1. Aceptar un ID de *Checkout Session* (A Checkout Session represents your customer's session as they pay for one-time purchases or subscriptions through Checkout. After a successful payment, the Checkout Session contains a reference to the Customer, and either the successful PaymentIntent or an active Subscription) como argumento. 1. Recuperar la Checkout Session de la API con la propiedad [line_items](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-line_items) [expandida](https://docs.stripe.com/api/expanding_objects.md). 1. Comprobar la propiedad [payment_status](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-payment_status) para determinar si requiere gestión logística. 1. Realizar la gestión logística de las partidas. 1. Registrar el estado de la gestión logística para la Checkout Session proporcionada. Use the code below as a starting point for your `fulfill_checkout` function. The `TODO` comments indicate any functionality you must implement. > Los fragmentos de código que aparecen a continuación podrían denominar a la función `fulfill_checkout` `fulfillCheckout` o `FulfillCheckout` según el idioma seleccionado, pero todos representan la misma función. #### Ruby ```ruby def fulfill_checkout(session_id) # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' puts "Fullfilling Checkout Session #{session_id}" # TODO: Make this function safe to run multiple times, # even concurrently, with the same session ID # TODO: Make sure fulfillment hasn't already been # performed for this Checkout Session # Retrieve the Checkout Session from the API with line_items expanded checkout_session = Stripe::Checkout::Session.retrieve({ id: session_id, expand: ['line_items'], }) # Check the Checkout Session's payment_status property # to determine if fulfillment should be performed if checkout_session.payment_status != 'unpaid' # TODO: Perform fulfillment of the line items # TODO: Record/save fulfillment status for this # Checkout Session end end ``` > Si una Checkout Session tiene muchas partidas, usa la [paginación automática](https://docs.stripe.com/api/pagination/auto.md) con la [API de partidas de Checkout](https://docs.stripe.com/api/checkout/sessions/line_items.md) para recuperarlas todas. Según los métodos de pago que aceptes y las necesidades de tu empresa, es posible que te convenga que la función `fulfill_checkout` haga lo siguiente: - Proporcionar acceso a los servicios. - Activar el envío de mercancías. - Guardar una copia de los datos de pago y las partidas en tu propia base de datos. - Enviar al cliente un correo electrónico de recibo personalizado si no tienes habilitados los [recibos de Stripe](https://docs.stripe.com/receipts.md). - Conciliar las partidas y las cantidades compradas si permites que los clientes ajusten las cantidades en Checkout. - Actualizar el inventario o los registros de existencias. ## Crea un controlador de eventos de pago [Lado del servidor] Para activar la gestión logística, crea un controlador de eventos de webhooks que reciba notificaciones de los eventos de pago y active tu función `fulfill_checkout`. Cuando alguien te paga, se crea un evento `checkout.session.completed`. Configura un punto de conexión en tu servidor para aceptar, procesar y confirmar la recepción de estos eventos. ### Métodos de pago inmediatos versus métodos de pago diferidos Algunos métodos de pago no son [instantáneos](https://docs.stripe.com/payments/payment-methods.md#payment-notification), como el [ACH direct debit](https://docs.stripe.com/payments/ach-direct-debit.md) y otras transferencias bancarias. Esto significa que los fondos no estarán disponibles de inmediato cuando se complete el proceso de compra. Los métodos de pago diferidos generan un evento de [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) cuando el pago se realiza con éxito más tarde. El estado del objeto es en proceso hasta que el estado del pago se confirma o falla. > The webhook secret (`whsec_...`) shown in the code below comes from either the Stripe CLI or your webhook endpoint. You can use the Stripe CLI for local testing, and Stripe uses a webhook endpoint to send events to your handler when it’s running on a server. See the next section for more details. #### Ruby ```ruby require 'sinatra' # Use the secret provided by Stripe CLI for local testing # or your webhook endpoint's secret. endpoint_secret = 'whsec_...' post '/webhook' do event = nil # Verify webhook signature and extract the event # See https://stripe.com/docs/webhooks#verify-events for more information. begin sig_header = request.env['HTTP_STRIPE_SIGNATURE'] payload = request.body.read event = Stripe::Webhook.construct_event(payload, sig_header, endpoint_secret) rescue JSON::ParserError => e # Invalid payload return status 400 rescue Stripe::SignatureVerificationError => e # Invalid signature return status 400 end if event['type'] == 'checkout.session.completed' || event['type'] == 'checkout.session.async_payment_succeeded' fulfill_checkout(event['data']['object']['id']) end status 200 end ``` También es posible que quieras gestionar y recibir notificaciones de eventos `checkout.session.async_payment_failed`. Por ejemplo, puedes enviar un correo electrónico a tu cliente cuando falle un pago retrasado. ## Prueba el controlador de eventos a nivel local The quickest way to develop and test your webhook event handler is with the [Stripe CLI](https://docs.stripe.com/stripe-cli.md). If you don’t have the Stripe CLI, follow the [install guide](https://docs.stripe.com/stripe-cli/install.md) to get started. When the Stripe CLI is installed, you can test your event handler locally. Run your server (for example, on `localhost:4242`), then run the [stripe listen](https://docs.stripe.com/cli/listen) command to have the Stripe CLI forward events to your local server: ```bash stripe listen --forward-to localhost:4242/webhook Ready! Your webhook signing secret is 'whsec_' (^C to quit) ``` Agrega el secreto de webhooks (`whsec_...`) a tu código de gestión de eventos y, a continuación, prueba la gestión logística accediendo a Checkout como cliente: - Presiona el botón de confirmación de compra que te lleva a Checkout, o visita tu Payment Link - Proporciona los siguientes datos de prueba en Checkout: - Introduce `4242 4242 4242 4242` como número de tarjeta - Introduce cualquier fecha futura como fecha de vencimiento de la tarjeta - Introduce cualquier número de tres dígitos para el CVC - Introduce cualquier código postal de pagos (`90210`) - Presiona el botón **Paga** Cuando se efectivice el pago, verifica lo siguiente: - En la línea de comandos, donde se está ejecutando `stripe listen`, se muestra un evento `checkout.session.completed` reenviado a tu servidor local. - Los registros de tu servidor muestran el resultado esperado de tu función `fulfill_checkout`. ## Crea un punto de conexión de webhooks After testing locally, get your webhook event handler up and running on your server. Next, [create a webhook endpoint](https://docs.stripe.com/webhooks.md#register-webhook) to send `checkout.session.completed` events to your server, then test the Checkout flow again. ## Configura la URL de la página de destino [Recomendado] Configure Checkout to send your customer to a page on your website after they complete Checkout. Include the `{CHECKOUT_SESSION_ID}` placeholder in your page’s URL, which is replaced with the Checkout Session ID when your customer is redirected from Checkout. ### Proceso de compra alojado For Checkout Sessions with the default [ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) of `hosted_page`, set the `success_url`. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "success_url=https://example.com/after-checkout?session_id={CHECKOUT_SESSION_ID}" ``` When you have a webhook endpoint set up to listen for `checkout.session.completed` events and you set a `success_url`, Checkout waits up to 10 seconds for your server to respond to the webhook event delivery before redirecting your customer. If you use this approach, make sure your server responds to `checkout.session.completed` events as quickly as possible. If you’re using the Stripe CLI for local testing, Checkout redirects to the `success_url` immediately. Este comportamiento no se admite para los puntos de conexión de webhook registrados en una cuenta de [organización](https://docs.stripe.com/get-started/account/orgs.md). Stripe no espera a que los puntos de conexión de webhook de la organización que escuchan `checkout.session.completed` respondan cuando se redirige a los clientes de Checkout. ### Payment Links For Payment Links you create with the API, set the [after_completion.redirect.url](https://docs.stripe.com/api/payment-link/create.md#create_payment_link-after_completion-redirect-url). ```curl curl https://api.stripe.com/v1/payment_links \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d "after_completion[type]=redirect" \ --data-urlencode "after_completion[redirect][url]=https://example.com/after-checkout?session_id={CHECKOUT_SESSION_ID}" ``` Para Payment Links que [crees en el Dashboard](https://dashboard.stripe.com/payment-links/create): 1. Ve a la pestaña **Después del pago**. 1. Selecciona **No mostrar página de confirmación**. 1. Proporciona la URL de tu página de destino que incluya el marcador de posición `{CHECKOUT_SESSION_ID}` (por ejemplo, `https://example.com/after-checkout?session_id={CHECKOUT_SESSION_ID}`) ## Activa la ejecución del pedido en tu página de destino [Recomendado] [Listening to webhooks](https://docs.stripe.com/checkout/fulfillment.md#create-payment-event-handler) is required to make sure you always trigger fulfillment for every payment, but webhooks can sometimes be delayed. To optimize your payment flow and guarantee immediate fulfillment when your customer is present, trigger fulfillment from your landing page as well. Usa el ID de la Checkout Session de la URL que especificaste en el paso anterior para hacer lo siguiente: 1. Cuando tu servidor reciba una solicitud para tu página de inicio de Checkout, extraer el ID de la Checkout Session de la URL. 1. Ejecutar la función `fulfill_checkout` con el ID proporcionado. 1. Renderizar la página una vez completado el intento de gestión logística. Al renderizar la página de inicio, se puede mostrar lo siguiente: - Detalles del proceso de gestión logística. - Enlaces o información sobre los servicios a los que el cliente ahora tiene acceso. - Detalles logísticos o de envío de bienes físicos. > #### Los webhooks son obligatorios > > You can’t rely on triggering fulfillment only from your Checkout landing page, because your customers aren’t guaranteed to visit that page. For example, someone can pay successfully in Checkout and then lose their connection to the internet before your landing page loads. > > [Configura un controlador de eventos de webhooks](https://docs.stripe.com/checkout/fulfillment.md#create-payment-event-handler) para Stripe pueda enviar eventos de pago directamente a tu servidor sin pasar por el cliente. Los webhooks son la forma más confiable de confirmar cuándo recibes un pago. Si falla el envío de eventos de webhooks, Stripe [lo reintenta varias veces](https://docs.stripe.com/webhooks.md#automatic-retries). # Embedded page > This is a Embedded page for when payment-ui is embedded-form. View the full page at https://docs.stripe.com/checkout/fulfillment?payment-ui=embedded-form. When you receive a payment with the Checkout Sessions API (including Payment Links), you might need to take action to provide your customer with what they paid for. For example, you might need to grant them access to a service, or you might need to ship them physical goods. This process is known as fulfillment, and you have two ways to handle this process: - **Manual**: puedes completar los pedidos manualmente con la información que Stripe pone a tu disposición. Por ejemplo, puedes supervisar el [Dashboard](https://docs.stripe.com/dashboard/basics.md), verificar los correos electrónicos de notificación de pagos, consultar los informes y, luego, completar los pedidos. - **Automáticamente**: puedes crear un sistema de gestión logística automatizado. (Recommended) The first option works for low volume or experimental ventures, but for most situations we recommend automating fulfillment. The rest of this guide shows you how to build an automatic fulfillment system. ## Cumplimiento de ejecución de un pedido The automatic fulfillment system outlined below uses a combination of *webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) and a redirect to your website to trigger fulfillment. You must use webhooks to make sure fulfillment happens for every payment, and redirects let your customers access services or fulfillment details immediately after paying. ## Crea una función de confirmación de pedido [Lado del servidor] Crea una función en tu servidor para completar los pagos efectuados correctamente. Los webhooks activan esta función, y se la llama cuando se remite a los clientes a tu sitio web después de completar el proceso de compra. Esta guía se refiere a esta función como `fulfill_checkout`, pero puedes nombrarla como quieras. Perform fulfillment only once per payment. Because of how this integration and the internet work, your `fulfill_checkout` function might be called multiple times, possibly concurrently, for the same Checkout Session. Performing checkout only once ensures this won’t cause undesired behavior. La función `fulfill_checkout` debe hacer lo siguiente: 1. Gestionar correctamente las llamadas múltiples con la mismo ID de la Checkout Session. 1. Aceptar un ID de *Checkout Session* (A Checkout Session represents your customer's session as they pay for one-time purchases or subscriptions through Checkout. After a successful payment, the Checkout Session contains a reference to the Customer, and either the successful PaymentIntent or an active Subscription) como argumento. 1. Recuperar la Checkout Session de la API con la propiedad [line_items](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-line_items) [expandida](https://docs.stripe.com/api/expanding_objects.md). 1. Comprobar la propiedad [payment_status](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-payment_status) para determinar si requiere gestión logística. 1. Realizar la gestión logística de las partidas. 1. Registrar el estado de la gestión logística para la Checkout Session proporcionada. Use the code below as a starting point for your `fulfill_checkout` function. The `TODO` comments indicate any functionality you must implement. > Los fragmentos de código que aparecen a continuación podrían denominar a la función `fulfill_checkout` `fulfillCheckout` o `FulfillCheckout` según el idioma seleccionado, pero todos representan la misma función. #### Ruby ```ruby def fulfill_checkout(session_id) # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' puts "Fullfilling Checkout Session #{session_id}" # TODO: Make this function safe to run multiple times, # even concurrently, with the same session ID # TODO: Make sure fulfillment hasn't already been # performed for this Checkout Session # Retrieve the Checkout Session from the API with line_items expanded checkout_session = Stripe::Checkout::Session.retrieve({ id: session_id, expand: ['line_items'], }) # Check the Checkout Session's payment_status property # to determine if fulfillment should be performed if checkout_session.payment_status != 'unpaid' # TODO: Perform fulfillment of the line items # TODO: Record/save fulfillment status for this # Checkout Session end end ``` > Si una Checkout Session tiene muchas partidas, usa la [paginación automática](https://docs.stripe.com/api/pagination/auto.md) con la [API de partidas de Checkout](https://docs.stripe.com/api/checkout/sessions/line_items.md) para recuperarlas todas. Según los métodos de pago que aceptes y las necesidades de tu empresa, es posible que te convenga que la función `fulfill_checkout` haga lo siguiente: - Proporcionar acceso a los servicios. - Activar el envío de mercancías. - Guardar una copia de los datos de pago y las partidas en tu propia base de datos. - Enviar al cliente un correo electrónico de recibo personalizado si no tienes habilitados los [recibos de Stripe](https://docs.stripe.com/receipts.md). - Conciliar las partidas y las cantidades compradas si permites que los clientes ajusten las cantidades en Checkout. - Actualizar el inventario o los registros de existencias. ## Crea un controlador de eventos de pago [Lado del servidor] Para activar la gestión logística, crea un controlador de eventos de webhooks que reciba notificaciones de los eventos de pago y active tu función `fulfill_checkout`. Cuando alguien te paga, se crea un evento `checkout.session.completed`. Configura un punto de conexión en tu servidor para aceptar, procesar y confirmar la recepción de estos eventos. ### Métodos de pago inmediatos versus métodos de pago diferidos Algunos métodos de pago no son [instantáneos](https://docs.stripe.com/payments/payment-methods.md#payment-notification), como el [ACH direct debit](https://docs.stripe.com/payments/ach-direct-debit.md) y otras transferencias bancarias. Esto significa que los fondos no estarán disponibles de inmediato cuando se complete el proceso de compra. Los métodos de pago diferidos generan un evento de [checkout.session.async_payment_succeeded](https://docs.stripe.com/api/events/types.md#event_types-checkout.session.async_payment_succeeded) cuando el pago se realiza con éxito más tarde. El estado del objeto es en proceso hasta que el estado del pago se confirma o falla. > The webhook secret (`whsec_...`) shown in the code below comes from either the Stripe CLI or your webhook endpoint. You can use the Stripe CLI for local testing, and Stripe uses a webhook endpoint to send events to your handler when it’s running on a server. See the next section for more details. #### Ruby ```ruby require 'sinatra' # Use the secret provided by Stripe CLI for local testing # or your webhook endpoint's secret. endpoint_secret = 'whsec_...' post '/webhook' do event = nil # Verify webhook signature and extract the event # See https://stripe.com/docs/webhooks#verify-events for more information. begin sig_header = request.env['HTTP_STRIPE_SIGNATURE'] payload = request.body.read event = Stripe::Webhook.construct_event(payload, sig_header, endpoint_secret) rescue JSON::ParserError => e # Invalid payload return status 400 rescue Stripe::SignatureVerificationError => e # Invalid signature return status 400 end if event['type'] == 'checkout.session.completed' || event['type'] == 'checkout.session.async_payment_succeeded' fulfill_checkout(event['data']['object']['id']) end status 200 end ``` También es posible que quieras gestionar y recibir notificaciones de eventos `checkout.session.async_payment_failed`. Por ejemplo, puedes enviar un correo electrónico a tu cliente cuando falle un pago retrasado. ## Prueba el controlador de eventos a nivel local The quickest way to develop and test your webhook event handler is with the [Stripe CLI](https://docs.stripe.com/stripe-cli.md). If you don’t have the Stripe CLI, follow the [install guide](https://docs.stripe.com/stripe-cli/install.md) to get started. When the Stripe CLI is installed, you can test your event handler locally. Run your server (for example, on `localhost:4242`), then run the [stripe listen](https://docs.stripe.com/cli/listen) command to have the Stripe CLI forward events to your local server: ```bash stripe listen --forward-to localhost:4242/webhook Ready! Your webhook signing secret is 'whsec_' (^C to quit) ``` Agrega el secreto de webhooks (`whsec_...`) a tu código de gestión de eventos y, a continuación, prueba la gestión logística accediendo a Checkout como cliente: - Presiona el botón de confirmación de compra que te lleva a Checkout, o visita tu Payment Link - Proporciona los siguientes datos de prueba en Checkout: - Introduce `4242 4242 4242 4242` como número de tarjeta - Introduce cualquier fecha futura como fecha de vencimiento de la tarjeta - Introduce cualquier número de tres dígitos para el CVC - Introduce cualquier código postal de pagos (`90210`) - Presiona el botón **Paga** Cuando se efectivice el pago, verifica lo siguiente: - En la línea de comandos, donde se está ejecutando `stripe listen`, se muestra un evento `checkout.session.completed` reenviado a tu servidor local. - Los registros de tu servidor muestran el resultado esperado de tu función `fulfill_checkout`. ## Crea un punto de conexión de webhooks After testing locally, get your webhook event handler up and running on your server. Next, [create a webhook endpoint](https://docs.stripe.com/webhooks.md#register-webhook) to send `checkout.session.completed` events to your server, then test the Checkout flow again. ## Configura la URL de la página de destino [Recomendado] Configure Checkout to send your customer to a page on your website after they complete Checkout. Include the `{CHECKOUT_SESSION_ID}` placeholder in your page’s URL, which is replaced with the Checkout Session ID when your customer completes the checkout process. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ -d ui_mode=embedded_page \ --data-urlencode "return_url=https://example.com/after-checkout?session_id={CHECKOUT_SESSION_ID}" ``` ## Activa la ejecución del pedido en tu página de destino [Recomendado] [Listening to webhooks](https://docs.stripe.com/checkout/fulfillment.md#create-payment-event-handler) is required to make sure you always trigger fulfillment for every payment, but webhooks can sometimes be delayed. To optimize your payment flow and guarantee immediate fulfillment when your customer is present, trigger fulfillment from your landing page as well. Usa el ID de la Checkout Session de la URL que especificaste en el paso anterior para hacer lo siguiente: 1. Cuando tu servidor reciba una solicitud para tu página de inicio de Checkout, extraer el ID de la Checkout Session de la URL. 1. Ejecutar la función `fulfill_checkout` con el ID proporcionado. 1. Renderizar la página una vez completado el intento de gestión logística. Al renderizar la página de inicio, se puede mostrar lo siguiente: - Detalles del proceso de gestión logística. - Enlaces o información sobre los servicios a los que el cliente ahora tiene acceso. - Detalles logísticos o de envío de bienes físicos. > #### Los webhooks son obligatorios > > You can’t rely on triggering fulfillment only from your Checkout landing page, because your customers aren’t guaranteed to visit that page. For example, someone can pay successfully in Checkout and then lose their connection to the internet before your landing page loads. > > [Configura un controlador de eventos de webhooks](https://docs.stripe.com/checkout/fulfillment.md#create-payment-event-handler) para Stripe pueda enviar eventos de pago directamente a tu servidor sin pasar por el cliente. Los webhooks son la forma más confiable de confirmar cuándo recibes un pago. Si falla el envío de eventos de webhooks, Stripe [lo reintenta varias veces](https://docs.stripe.com/webhooks.md#automatic-retries).