# Integrar con la API Invoicing Aprende a crear y enviar una factura con código. El [Dashboard](https://dashboard.stripe.com/invoices) es la vía más habitual para [crear facturas](https://docs.stripe.com/invoicing/dashboard.md#create-invoice). Si quieres automatizar este proceso, puedes hacer la integración con la API. Diseña una integración completa y funcional con Invoicing siguiendo nuestro [modelo de integración](https://docs.stripe.com/invoicing/integration/quickstart.md). ## Configurar Stripe Usa nuestras bibliotecas oficiales para acceder a la API de Stripe: #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` ## Crear un producto Para crear un producto, ingresa su nombre: ```curl curl https://api.stripe.com/v1/products \ -u "<>:" \ -d "name=Gold Special" ``` ## Crear un precio [Precios](https://docs.stripe.com/api.md#prices) define cuánto cobrar por los productos y con qué frecuencia. Esto incluye cuánto cuesta el producto, qué moneda usar y el intervalo de facturación (cuando el precio es de una suscripción). Al igual que sucede con los productos, si tienes pocos precios, es preferible gestionarlos en el Dashboard. Usa el importe unitario para expresar los precios en la unidad más baja de la moneda, en este caso, centavos (USD 10 son 1,000 centavos, por lo que el importe unitario es 1000). Como alternativa, si no necesitas crear un precio para tu producto, puedes usar el parámetro [amount](https://docs.stripe.com/api/invoiceitems/create.md#create_invoiceitem-amount) durante la creación de la partida de factura. Para crear el precio y asignarlo al producto, especifica el ID de producto, el importe unitario y la moneda. En el siguiente ejemplo, el precio del producto “Gold Special“ es de USD 10: ```curl curl https://api.stripe.com/v1/prices \ -u "<>:" \ -d "product={{PRODUCT_ID}}" \ -d unit_amount=1000 \ -d currency=usd ``` ## Crear un cliente Cuando creas una factura, necesitas un objeto que represente al cliente que compra tu producto. Este objeto puede ser una [cuenta](https://docs.stripe.com/api/v2/core/accounts/object.md#v2_account_object-configuration-customer) configurada por el cliente o un [cliente](https://docs.stripe.com/api/customers/object.md). > #### Usa la API Accounts v2 para representar a los clientes > > La API Accounts v2 suele estar disponible para usuarios Connect y en versión preliminar pública para otros usuarios de Stripe. Si eres parte de la versión preliminar Accounts v2, debes especificar una [versión preliminar](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) en tu código. > > Para solicitar el acceso a la versión preliminar Accounts v2, > > For most use cases, we recommend [modeling your customers as customer-configured Account objects](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md) instead of using [Customer](https://docs.stripe.com/api/customers.md) objects. #### Accounts v2 Crea una [cuenta](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer) configurada por el cliente con `display_name` y `contact_email`, como en el siguiente ejemplo: ```curl curl -X POST https://api.stripe.com/v2/core/accounts \ -H "Authorization: Bearer <>" \ -H "Stripe-Version: 2026-04-22.preview" \ --json '{ "contact_email": "jenny.rosen@example.com", "display_name": "Jenny Rosen", "configuration": { "customer": { "capabilities": {} } }, "include": [ "configuration.customer" ] }' ``` #### Customers v1 Crea un [cliente](https://docs.stripe.com/api/customers/create.md) con un `nombre`, un `correo electrónico` y una `descripción`, como en el siguiente ejemplo: ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ -d "name=Jenny Rosen" \ --data-urlencode "email=jenny.rosen@example.com" \ -d "description=My first customer" ``` Después de crear el cliente, guarda su `id` en tu base de datos para poder usarlo después. En el próximo paso, por ejemplo, el ID del cliente se utiliza para crear una factura. ## Crear una factura Establece el atributo [collection_method](https://docs.stripe.com/api/invoices/object.md#invoice_object-collection_method) en `send_invoice`. Para que Stripe marque una factura como vencida, debes agregar el parámetro [days_until_due](https://docs.stripe.com/api/invoices/create.md#create_invoice-days_until_due). Cuando envías una factura, Stripe se la envía al cliente por correo electrónico junto con las instrucciones de pago. #### Accounts v2 ```curl curl https://api.stripe.com/v1/invoices \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d collection_method=send_invoice \ -d days_until_due=30 ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/invoices \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d collection_method=send_invoice \ -d days_until_due=30 ``` A continuación, para crear una partida de factura, especifica el ID de cliente, el `price` del producto y el ID de la `invoice`. La cantidad máxima de ítems de factura es 250. #### Accounts v2 ```curl curl https://api.stripe.com/v1/invoiceitems \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "pricing[price]={{PRICE_ID}}" \ -d "invoice={{INVOICE_ID}}" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/invoiceitems \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "pricing[price]={{PRICE_ID}}" \ -d "invoice={{INVOICE_ID}}" ``` Si estableces `auto_advance` en `false`, puedes seguir modificando la factura hasta su [finalización](https://docs.stripe.com/invoicing/integration/workflow-transitions.md). Para finalizar una factura en borrador, usa el Dashboard, envíasela al cliente o págala. También puedes utilizar la API [Finalize](https://docs.stripe.com/api/invoices/finalize.md): ```curl curl -X POST https://api.stripe.com/v1/invoices/{{INVOICE_ID}}/finalize \ -u "<>:" ``` Si creas una factura por error, puedes [anularla](https://docs.stripe.com/invoicing/overview.md#void). También puedes marcarla como [incobrable](https://docs.stripe.com/invoicing/overview.md#uncollectible). ## Aceptar pago con factura #### Enviar una factura Envía la factura a la dirección de correo electrónico asociada al cliente. Stripe finaliza la factura tan pronto como la envías. Muchas jurisdicciones consideran las facturas finalizadas como un documento legal, por lo que algunos campos no pueden cambiarse. Si envías facturas que ya se pagaron, el correo electrónico no hará mención del pago. > Si envias facturas que ya se pagaron, el correo electrónico no hará mención del pago. Stripe envía las facturas a la dirección de correo electrónico asociada al cliente. ```curl curl -X POST https://api.stripe.com/v1/invoices/{{INVOICE_ID}}/send \ -u "<>:" ``` #### Stripe Elements Cuando se finaliza la factura, se genera 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) y se asocia con la factura. Usa [Stripe Elements](https://docs.stripe.com/payments/elements.md) para recopilar los datos de pago y confirmar el PaymentIntent de la factura. No puedes editar los valores monetarios ni el parámetro `collection_method` una vez finalizada una factura. Esta restricción también se aplica al PaymentIntent de la factura finalizada. Cuando actualizas el PaymentIntent de una factura con una llamada a [update](https://docs.stripe.com/api/payment_intents/update.md), solo puedes modificar los parámetros `setup_future_usage`, `metadata`, `payment_method`, `description`, `receipt_email`, `payment_method_data`, `payment_method_options` y `shipping`. #### Payment Element (recomendado) El [Payment Element](https://docs.stripe.com/payments/payment-element.md) recopila de forma segura todos los datos de pago necesarios para diferentes métodos de pago. Consulta el [Soporte para métodos de pago y productos](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) para determinar si los métodos de pago configurados son compatibles tanto con Invoicing como con Payment Element. ### Cómo especificar el secreto de cliente en el front-end Stripe.js utiliza el [client_secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) del PaymentIntent para completar el proceso de pago de forma segura. Obtén el secreto de cliente de la factura mediante la [expansión](https://docs.stripe.com/api/expanding_objects.md) de su atributo [confirmation_secret](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret), cuando [finalices](https://docs.stripe.com/api/invoices/finalize.md) la factura o cuando hagas otra llamada de API, como [recuperar](https://docs.stripe.com/api/invoices/retrieve.md) o [actualizar](https://docs.stripe.com/api/invoices/update.md), en la factura después de finalizarla. Devuelve el `client_secret` al front-end para completar el pago. ```curl curl https://api.stripe.com/v1/invoices/{{INVOICE_ID}}/finalize \ -u "<>:" \ -d "expand[]=confirmation_secret" ``` Después de devolver la factura, accede al secreto de cliente en el campo `confirmation_secret` expandido. #### cURL #### Stripe CLI #### Ruby ```ruby client_secret = invoice.confirmation_secret.client_secret ``` #### Python ```python client_secret = invoice.confirmation_secret.client_secret ``` #### PHP ```php $client_secret = $invoice->confirmation_secret->client_secret; ``` #### Java ```java String clientSecret = invoice.getConfirmationSecret().getClientSecret(); ``` #### Node.js ```javascript const client_secret = invoice.confirmation_secret.client_secret; ``` #### Ir ```go clientSecret := invoice.ConfirmationSecret.ClientSecret ``` #### .NET ```csharp var clientSecret = invoice.ConfirmationSecret.ClientSecret; ``` ### Configurar Stripe Elements El Payment Element se encuentra disponible automáticamente como función de Stripe.js. Incluye el script Stripe.js en tu página de finalización de compra agregándolo al `head` de tu archivo HTML. Carga siempre Stripe.js directamente desde js.stripe.com para cumplir con la normativa PCI. No incluyas el script en un paquete ni alojes una copia en tus sistemas. ```html Pay Invoice ``` 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('<>'); ``` ### Agregar el Payment Element a tu página El Payment Element necesita un lugar donde residir en tu página de pago. Crea un nodo DOM vacío (contenedor) con un ID único en tu formulario de pago. ```html
``` Cuando se cargue el formulario, crea una instancia de Payment Element y móntala en el nodo DOM del contenedor. Especifica el secreto de cliente de PaymentIntent como una opción al crear una instancia de Elements. ```javascript const options = { clientSecret: '{{CLIENT_SECRET}}', // Fully customizable with appearance API. appearance: {/*...*/}, }; // Set up Stripe.js and Elements to use in your checkout form, passing in the client secret. const elements = stripe.elements(options); // Create and mount the Payment Element const paymentElementOptions = { layout: 'accordion'}; const paymentElement = elements.create('payment', paymentElementOptions); paymentElement.mount('#payment-element'); ``` Payment Element renderiza un formulario dinámico que le permite a tu cliente elegir un método de pago. El formulario recopila automáticamente todos los datos de pago necesarios correspondientes al método de pago seleccionado por el cliente. Puedes personalizar el Payment Element para que combine con el diseño de tu sitio especificando el [objeto appearance](https://docs.stripe.com/elements/appearance-api.md) en `options` al crear una instancia de Elements. ### Completar pago Utiliza `stripe.confirmPayment` para completar el pago con los detalles del Payment Element. Esto crea un método de pago y confirma el Payment Intent de la factura, lo que genera un cargo. Si se requiere *autenticación reforzada de clientes* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) (SCA) para el pago, el Payment Element se encarga del proceso de autenticación antes de confirmar el Payment Intent. Proporciona una [return_url](https://docs.stripe.com/api/payment_intents/confirm.md#confirm_payment_intent-return_url) a la función `confirmPayment` para indicar a dónde redirige Stripe al usuario después de completar el pago. Tu usuario puede ser redirigido primero a un sitio intermedio, como una página de autorización bancaria, antes de ser redirigido a la `return_url`. Los pagos con tarjeta redirigen inmediatamente a la `return_url` cuando un pago se realiza correctamente. ```javascript const form = document.getElementById('payment-form'); form.addEventListener('submit', async (event) => { event.preventDefault(); const {error} = await stripe.confirmPayment({ //`Elements` instance that was used to create the Payment Element elements, confirmParams: { return_url: "https://example.com/order/123/complete", } }); if (error) { // This point will only be reached if there is an immediate error when // confirming the payment. Show error to your customer (for example, payment // details incomplete) const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message; } else { // Your customer will be redirected to your `return_url`. For some payment // methods like iDEAL, your customer will be redirected to an intermediate // site first to authorize the payment, then redirected to the `return_url`. } }); ``` Cuando tu cliente envía un pago, Stripe lo redirige a `return_url` e incluye los siguientes parámetros de consulta de URL. La página de retorno puede usarlos para obtener el estado del PaymentIntent a fin de mostrarle el estado del pago al cliente. Cuando especificas la `return_url`, también puedes adjuntar tus propios parámetros de consulta para usarlos en la página de retorno. | Parámetro | Descripción | | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `payment_intent` | El identificador único del `PaymentIntent`. | | `payment_intent_client_secret` | El [secreto de cliente](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) del objeto `PaymentIntent`. Para las integraciones de suscripciones, este client_secret también se expone en el objeto `Invoice` a través de [`confirmation_secret`](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret) | Cuando el cliente es redirigido a tu sitio, puedes usar el `payment_intent_client_secret` para consultar el PaymentIntent y mostrarle el estado de la transacción a tu cliente. > Si tienes herramientas que rastrean la sesión del navegador del cliente, es posible que debas agregar el dominio `stripe.com` a la lista de exclusión de referentes. Los redireccionamientos hacen que algunas herramientas creen nuevas sesiones, lo que te impide realizar un seguimiento de la sesión completa. Usa el parámetro de consulta `payment_intent_client_secret` para recuperar el PaymentIntent. Examina el [estado del PaymentIntent](https://docs.stripe.com/payments/paymentintents/lifecycle.md) para decidir qué mostrarás a tus clientes. También puedes adjuntar tus propios parámetros de consulta cuando proporciones la `return_url`, que se mantendrán durante el proceso de redireccionamiento. ```javascript // Initialize Stripe.js using your publishable key const stripe = Stripe('<>'); // Retrieve the "payment_intent_client_secret" query parameter appended to // your return_url by Stripe.js const clientSecret = new URLSearchParams(window.location.search).get( 'payment_intent_client_secret' ); // Retrieve the PaymentIntent stripe.retrievePaymentIntent(clientSecret).then(({paymentIntent}) => { const message = document.querySelector('#message') // Inspect the PaymentIntent `status` to indicate the status of the payment // to your customer. // // Some payment methods will [immediately succeed or fail][0] upon // confirmation, while others will first enter a `processing` state. // // [0]: https://stripe.com/docs/payments/payment-methods#payment-notification switch (paymentIntent.status) { case 'succeeded': message.innerText = 'Success! Payment received.'; break; case 'processing': message.innerText = "Payment processing. We'll update you when payment is received."; break; case 'requires_payment_method': message.innerText = 'Payment failed. Please try another payment method.'; // Redirect your user back to your payment page to attempt collecting // payment again break; default: message.innerText = 'Something went wrong.'; break; } }); ``` #### Card Element El Card Element recopila y valida de forma segura los datos de la tarjeta de crédito del usuario. ### Cómo especificar el secreto de cliente en el front-end Stripe.js utiliza el [client_secret](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-client_secret) del PaymentIntent para completar el proceso de pago de forma segura. Obtén el secreto de cliente de la factura mediante la [expansión](https://docs.stripe.com/api/expanding_objects.md) de su atributo [confirmation_secret](https://docs.stripe.com/api/invoices/object.md#invoice_object-confirmation_secret), cuando [finalices](https://docs.stripe.com/api/invoices/finalize.md) la factura o cuando hagas otra llamada de API, como [recuperar](https://docs.stripe.com/api/invoices/retrieve.md) o [actualizar](https://docs.stripe.com/api/invoices/update.md), en la factura después de finalizarla. Devuelve el `client_secret` al front-end para completar el pago. ```curl curl https://api.stripe.com/v1/invoices/{{INVOICE_ID}}/finalize \ -u "<>:" \ -d "expand[]=confirmation_secret" ``` Después de devolver la factura, accede al secreto de cliente en el campo `confirmation_secret` expandido. #### cURL #### Stripe CLI #### Ruby ```ruby client_secret = invoice.confirmation_secret.client_secret ``` #### Python ```python client_secret = invoice.confirmation_secret.client_secret ``` #### PHP ```php $client_secret = $invoice->confirmation_secret->client_secret; ``` #### Java ```java String clientSecret = invoice.getConfirmationSecret().getClientSecret(); ``` #### Node.js ```javascript const client_secret = invoice.confirmation_secret.client_secret; ``` #### Ir ```go clientSecret := invoice.ConfirmationSecret.ClientSecret ``` #### .NET ```csharp var clientSecret = invoice.ConfirmationSecret.ClientSecret; ``` ### Configurar Stripe Elements Stripe Elements está incluido dentro de Stripe.js. Para incluir el script de Stripe.js en tu página de finalización de compra, agrégalo al `head` de tu archivo HTML. Carga siempre Stripe.js directamente desde js.stripe.com para cumplir con la normativa PCI. No incluyas el script en un paquete ni alojes una copia en tus sistemas. ```html Subscription prices ``` Crea una instancia de Elements con el siguiente JavaScript: ```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 let stripe = Stripe('<>'); let elements = stripe.elements(); ``` ### Agrega Elements a tu página Elements necesita un lugar específico en tu formulario de pago. Crea nodos DOM (contenedores) vacíos con ID únicas en tu formulario de pago y luego especifica esas ID en Elements. ```html
``` Crea una instancia de un Element y móntalo en el contenedor del Element:Element ```javascript let card = elements.create('card', { style: style }); card.mount('#card-element'); ``` El `card` Element simplifica el formulario de pago y minimiza la cantidad de campos obligatorios insertando un único campo de entrada flexible que recopila de forma segura todos los datos necesarios de la tarjeta. Para ver la lista completa de tipos de Element aceptados, consulta nuestra documentación de [referencia sobre Stripe.js](https://docs.stripe.com/js.md#elements_create). Usa el número de una tarjeta de prueba **4242 4242 4242 4242**, cualquier número de CVC de tres dígitos, una fecha de vencimiento futura y cualquier código postal de cinco dígitos. Elements valida la entrada del usuario tal como aparece escrita. Para ayudar a los clientes a detectar errores, escucha los eventos `change` en el Element `card` y muestra cualquier error. ```javascript card.on('change', function (event) { displayError(event); }); function displayError(event) { changeLoadingStatePrices(false); let displayError = document.getElementById('card-element-errors'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } } ``` La [validación del código postal](https://docs.stripe.com/js.md#postal-code-formatting) depende del país de facturación del cliente. Utiliza nuestras [tarjetas de prueba internacionales](https://docs.stripe.com/testing.md#international-cards) para hacer pruebas con otros formatos de código postal. ### Completar pago Cuando tu cliente envíe el formulario Elements, llama a `stripe.confirmCardPayment` con 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)) que pasaste a tu frontend. Esto crea un método de pago y *confirma* (Confirming an intent indicates that the customer intends to use the current or provided payment method. Upon confirmation, the intent attempts to initiate the portions of the flow that have real-world side effects) el PaymentIntent de la factura que hace que se realice un cargo. Si se requiere *autenticación reforzada de clientes* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) (SCA) para el pago, Elements se encarga del proceso de autenticación antes de confirmar el PaymentIntent. ```javascript const btn = document.querySelector('#submit-payment-btn'); btn.addEventListener('click', async (e) => { e.preventDefault(); const nameInput = document.getElementById('name'); // Create payment method and confirm PaymentIntent. stripe.confirmCardPayment(clientSecret, { payment_method: { card: cardElement, billing_details: { name: nameInput.value, }, } }).then((result) => { if(result.error) { alert(result.error.message); } else { // Successful invoice payment } }); }); ``` ## Gestionar eventos posteriores al pago Stripe envía un evento [invoice.paid](https://docs.stripe.com/api/events/types.md?event_types-invoice.paid) cuando se completa el pago de una factura. Escucha este evento para garantizar un cumplimiento confiable. Si su integración se basa solo en una devolución de llamada del lado del cliente, el cliente podría perder la conexión antes de que se ejecute la devolución de llamada, lo que provocaría que se le cobre al cliente sin notificar a tu servidor. Si configuras tu integración para escuchar eventos asincrónicos, también podrás aceptar [diferentes tipos de métodos de pago](https://stripe.com/payments/payment-methods-guide) con una sola integración. Los pagos de facturas exitosos activan los eventos [invoice.paid](https://docs.stripe.com/api/events/types.md?event_types-invoice.paid) e [invoice.payment_succeeded](https://docs.stripe.com/api/events/types.md?event_types-invoice.payment_succeeded). Ambos tipos de eventos contienen los mismos datos de factura, por lo que solo es necesario escuchar a uno de ellos a fin de recibir una notificación de pagos de facturas exitosos. La diferencia es que los eventos `invoice.payment_succeeded` se envían con pagos de facturas exitosos, pero no se envían cuando marcas una factura como [paid_out_of_band](https://docs.stripe.com/api/invoices/pay.md#pay_invoice-paid_out_of_band). Por otro lado, los eventos `invoice.paid` se activan tanto para pagos exitosos como para pagos fuera de banda. Debido a que `invoice.paid` cubre ambas opciones, por lo general, recomendamos escuchar `invoice.paid` en lugar de `invoice.payment_succeeded`. Utiliza la [herramienta webhook del Dashboard](https://dashboard.stripe.com/webhooks) o sigue el [inicio rápido del webhook](https://docs.stripe.com/webhooks/quickstart.md) para recibir estos eventos y ejecutar acciones como, 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 un flujo de envío. Además de administrar el evento `invoice.paid`, recomendamos administrar otros dos eventos si se cobran pagos con el Payment Element: | Evento | Descripción | cliente | | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing) | Se envía cuando el cliente inició correctamente el pago, pero el pago aún no se ha completado. Este evento se envía con mayor frecuencia cuando se inicia un débito bancario. Más adelante, lo sigue un evento `invoice.paid` o `invoice.payment_failed`. | Envía al cliente una confirmación del pedido que indique que el pago está pendiente. En caso de productos digitales, quizá te convenga completar el pedido antes de esperar que se complete el pago. | | [invoice.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Se envía cuando el cliente intentó pagar una factura, pero el pago falló. | Si un pago pasó de `processing` a `payment_failed`, ofrécele al cliente otro intento de pago. | ## Optional: Personalizar una factura Puedes [personalizar facturas](https://docs.stripe.com/invoicing/customize.md) de varias maneras. Las opciones de personalización de Stripe te permiten agregar tu propia imagen de marca y modificar las facturas para ajustarlas a la normativa de las jurisdicciones en las que operas. ### Campos personalizados Agrega campos personalizados para mejorar los documentos PDF de tu factura y ayudarte a cumplir con tus obligaciones de prácticas comerciales y declaraciones fiscales. Los campos personalizados te permiten especificar hasta cuatro pares clave-valor que se muestran en el encabezado de la factura. Puedes configurar hasta cuatro pares clave-valor para los campos personalizados en el [editor de facturas](https://dashboard.stripe.com/invoices/create), con la [API Invoices](https://docs.stripe.com/api/invoices/create.md#create_invoice-custom_fields) o con [plantillas de facturas](https://docs.stripe.com/invoicing/invoice-rendering-template.md). Estos son algunos usos comunes de los campos personalizados: - Números de orden de compra - Números de contratista - Cumplimiento de la normativa fiscal Veamos un ejemplo de cómo crear una factura con un número de pedido y un impuesto al valor agregado (IVA) como campos personalizados: #### Accounts v2 ```curl curl https://api.stripe.com/v1/invoices \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d "custom_fields[0][name]=PO number" \ -d "custom_fields[0][value]=12345" \ -d "custom_fields[1][name]=VAT" \ -d "custom_fields[1][value]=123ABC" ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/invoices \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d "custom_fields[0][name]=PO number" \ -d "custom_fields[0][value]=12345" \ -d "custom_fields[1][name]=VAT" \ -d "custom_fields[1][value]=123ABC" ``` #### Herencia de campos personalizados Puedes configurar campos de factura personalizados en el objeto que utilizas para representar a tu cliente. Los campos personalizados que configuras a nivel del cliente se aplicarán a todas las facturas en borrador que generes para ese cliente. Tienes tiempo de modificar estos campos personalizados heredados mientras la factura esté en borrador. Si finalizas la factura, no podrás actualizar los campos personalizados. #### Accounts v2 A continuación, te explicamos con un ejemplo cómo agregar [campos_personalizados](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer-billing-invoice-custom_fields) a nivel del cliente que se aplicarán a todas las facturas en borrador que se generen en el futuro: ```curl curl -X POST https://api.stripe.com/v2/core/accounts \ -H "Authorization: Bearer <>" \ -H "Stripe-Version: 2026-04-22.preview" \ --json '{ "contact_email": "jenny.rosen@example.com", "display_name": "Jenny Rosen", "configuration": { "customer": { "billing": { "invoice": { "custom_fields": [ { "name": "PO number", "value": "12345" } ] } } } }, "include": [ "configuration.customer" ] }' ``` #### Customers v1 A continuación, te explicamos con un ejemplo cómo agregar [campos_personalizados](https://docs.stripe.com/api/customers/object.md#customer_object-invoice_settings-custom_fields) a nivel del cliente que se aplicarán a todas las facturas en borrador que se generen en el futuro: ```curl curl https://api.stripe.com/v1/customers \ -u "<>:" \ --data-urlencode "email=jenny.rosen@example.com" \ -d payment_method=pm_card_visa \ -d "invoice_settings[default_payment_method]=pm_card_visa" \ -d "invoice_settings[custom_fields][0][name]=PO number" \ -d "invoice_settings[custom_fields][0][value]=12345" \ -d "invoice_settings[custom_fields][1][name]=VAT" \ -d "invoice_settings[custom_fields][1][value]=123ABC" ``` ## See also - [Después de la finalización](https://docs.stripe.com/invoicing/integration/workflow-transitions.md#post-finalized) - [Usa webhooks entrantes para obtener actualizaciones en tiempo real](https://docs.stripe.com/webhooks.md)