Ir a contenido
Crea una cuenta o inicia sesión
Logotipo de la documentación de Stripe
/
Pregúntale a la IA
Crear cuentaIniciar sesión
Empezar
Pagos
Ingresos
Plataformas y marketplaces
Gestión del dinero
Recursos para desarrolladores
API y SDKAyuda
ResumenAceptar un pagoActualiza tu integración
Pagos por Internet
ResumenEncuentra tu caso de uso
Utiliza Payment Links
Usa una página de proceso de compra prediseñada
Crea una integración personalizada con Elements
Desarrolla una integración en la aplicación
Usa Managed PaymentsPagos recurrentes
Pagos en persona
Terminal
    Resumen
    Acepta pagos en persona
    Disponibilidad internacional
    Diseño de la integración
    Selecciona tu lector
    Diseña una integración
    Inicio rápido
    Aplicaciones de ejemplo
    Pruebas
    Configuración de Terminal
    Configura tu integración
    Pagos a múltiples destinatarios con Connect
    Conectarse a un lector
    Aceptar un pago
    Cobrar pagos con tarjeta
    Otros métodos de pago
    Aceptar pagos sin conexión
    Pagos de pedidos telefónicos o pedidos por correo
    Consideraciones regionales
    Durante el proceso de compra
    Cobrar propinas
    Recopilar y guardar datos de pago para su uso en el futuro
    Autorizaciones flexibles
    Después del proceso de compra
    Reembolsar transacciones
    Solicitar recibos
    Personalizar Checkout
    Mostrar carrito
    Recopilar entradas en pantalla
    Recopilar datos deslizados
    Recopilar datos pulsados para los instrumentos de NFC
    Aplicaciones en dispositivos
    Gestionar lectores
    Pedir, devolver o sustituir lectores
    Registrar lectores
    Gestionar ubicaciones y zonas
    Configurar los lectores
    Seguimiento de los lectores
    Referencias
    Referencias de la API
    Lectores móviles
    Lectores inteligentes
    Lectores Tap to Pay
    Guía de migración de SDK
    Lista de verificación de la implementación
    Fichas de producto del lector de Stripe Terminal
Métodos de pago
Añadir métodos de pago
Gestiona los métodos de pago
Proceso de compra más rápido con Link
Aspectos básicos de las operaciones de pago
Análisis
Saldos y plazos de liquidación
Cumplimiento de la normativa y seguridad
Divisas
Pagos rechazados
Disputas
Prevención de fraude
Protección antifraude de Radar
Transferencias
RecibosReembolsos y cancelaciones
Integraciones avanzadas
Flujos de pagos personalizados
Capacidad adquirente flexible
Pagos fuera de la sesión
Orquestación de varios responsables del tratamiento
Más allá de los pagos
Constituye tu empresa
Criptomonedas
Comercio agéntico
Financial Connections
Climate
Verificar identidades
Estados Unidos
Español (España)
InicioPagosTerminal

Collect card payments

Prepare your application and back end to collect card payments using Stripe Terminal.

Más información

New to the Payment Intents API? Here are some helpful resources:

  • The Payment Intents API
  • The PaymentIntent object
  • More payment scenarios

Collecting payments with Stripe Terminal requires writing a payment flow in your application. Use the Stripe Terminal SDK to create and update a PaymentIntent, an object representing a single payment session.

Designed to be robust to failures, the Terminal integration splits the payment process into several steps, each of which can be retried safely:

  1. Create a PaymentIntent.
  2. Process the payment. Authorization on the customer’s card takes place when the SDK processes the payment.
  3. (Optional) Capture the payment

Create a PaymentIntent
Lado del clienteLado del servidor

The first step when collecting payments is to start the payment flow. When a customer begins checking out, your application must create a PaymentIntent object. This represents a new payment session on Stripe.

SDK Reference

  • createPaymentIntent (iOS)

You can create a PaymentIntent on the client or server.

Use test amounts to try producing different results. An amount ending in 00 results in an approved payment.

Don't recreate PaymentIntents for declined cards

Don’t recreate a PaymentIntent if a card is declined. Instead, re-use the same PaymentIntent to help avoid double charges.

Client-side

Create a PaymentIntent from your client:

Advertencia

If your app is connected to the Verifone P400, you can’t create a PaymentIntent from the iOS SDK. Instead, you must create the PaymentIntent server-side, and retrieve the PaymentIntent in your app using the Terminal.retrievePaymentIntent method in the SDK.

PaymentViewController.swift
Swift
Objective-C
No results
import UIKit import StripeTerminal class PaymentViewController: UIViewController { // ... // Action for a "Checkout" button func checkoutAction() throws { let params = try PaymentIntentParametersBuilder(amount: 1000, currency: "usd").build() Terminal.shared.createPaymentIntent(params) { createResult, createError in if let error = createError { print("createPaymentIntent failed: \(error)") } else if let paymentIntent = createResult { print("createPaymentIntent succeeded") // ... } } } // ... }

Server-side

You can create the PaymentIntent on your server if the information required to start a payment isn’t readily available in your app.

The following example shows how to create a PaymentIntent on your server:

Command Line
curl
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl https://api.stripe.com/v1/payment_intents \ -u
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:
\ -d "amount"=1000 \ -d "currency"="usd" \ -d "payment_method_types[]"="card_present" \ -d "capture_method"="manual"

For Terminal payments, the payment_method_types parameter must include card_present.

You can control the payment flow as follows:

  • To fully control the payment flow for card_present payments, set the capture_method to manual. This allows you to add a reconciliation step before finalizing the payment.
  • To authorize and capture payments in one step, set the capture_method to automatic.

To accept payments in Australia, you need to set capture_method to automatic or manual_preferred. For more details, visit our Australia documentation. To accept Interac payments in Canada, you must also include interac_present in payment_method_types. For more details, visit our Canada documentation.

The PaymentIntent contains a client secret, a key that’s unique to the individual PaymentIntent. To use the client secret, you must obtain it from the PaymentIntent on your server and pass it to the client side.

Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
post '/create_payment_intent' do intent = # ... Create or retrieve the PaymentIntent {client_secret: intent.client_secret}.to_json end

SDK Reference

  • retrievePaymentIntent (iOS)

To retrieve a PaymentIntent, use the client secret to call retrievePaymentIntent.

After you retrieve the PaymentIntent, use it to call processPaymentIntent.

PaymentViewController.swift
Swift
Objective-C
No results
func checkoutButtonAction() { // ... Fetch the client secret from your backend Terminal.shared.retrievePaymentIntent(clientSecret: clientSecret) { retrieveResult, retrieveError in if let error = retrieveError { print("retrievePaymentIntent failed: \(error)") } else if let paymentIntent = retrieveResult { print("retrievePaymentIntent succeeded: \(paymentIntent)") // ... } } }

Procesar el pago
Lado del cliente

You can process a payment immediately with the card presented by a customer, or instead inspect card details before proceeding to process the payment. For most use cases, we recommend processing immediately, because it’s a simpler integration with fewer API calls. However, if you want to insert your own business logic before authorizing the card, use the two-step collect-and-confirm flow.

After you create a PaymentIntent, the next step is to process the payment. The reader prompts the customer to insert or tap their card and then attempts to authorize the payment.

SDK Reference

  • processPaymentIntent (iOS)

While processing a payment, cardholder might take a few seconds to get their card from their wallet or pose a question to the operator during payment.

PaymentViewController.swift
Swift
Objective-C
No results
// Action for a "Checkout" button func checkoutAction() throws { let params = try PaymentIntentParametersBuilder(amount: 1000, currency: "usd").build() Terminal.shared.createPaymentIntent(params) { createResult, createError in if let error = createError { print("createPaymentIntent failed: \(error)") } else if let paymentIntent = createResult { print("createPaymentIntent succeeded") self.processCancelable = Terminal.shared.processPaymentIntent(paymentIntent, collectConfig: nil, confirmConfig: nil) { processResult, processError in if let error = processError { print("processPaymentIntent failed: \(error)") } else if let processedPaymentIntent = processResult { print("processPaymentIntent succeeded") // Notify your backend to capture the PaymentIntent if let stripeId = processedPaymentIntent.stripeId { APIClient.shared.capturePaymentIntent(stripeId) { captureError in if let error = captureError { print("capturePaymentIntent failed: \(error)") } else { print("capturePaymentIntent succeeded") } } } else { print("Payment processed offline"); } } } } } }

Cancel collection

Programmatic cancellation

SDK Reference

  • Cancelable (iOS)

You can cancel processing a PaymentIntent using the Cancelable object returned by the iOS SDK.

Customer-initiated cancellation

SDK Reference

  • setCustomerCancellation (iOS)
  • CustomerCancellation (iOS)

Smart readers show customers a cancel button by default. You can disable this by setting customerCancellation to .disableIfAvailable.

Tapping the cancel button cancels the active transaction.

PaymentViewController.swift
Swift
Objective-C
No results
let collectConfig = try CollectPaymentIntentConfigurationBuilder() .setCustomerCancellation(.disableIfAvailable) // turn OFF the cancel button, ON by default .build() Terminal.shared.collectPaymentMethod(paymentIntent: paymentIntent, collectConfig: collectConfig) { intentWithPaymentMethod, attachError in }

Handle events

SDK Reference

  • ReaderDisplayDelegate (iOS)

When collecting a payment method using a reader such as the Stripe M2, without a built-in display, your app must be able to display events from the payment method collection process to users. These events help users successfully collect payments (for example, retrying a card, trying a different card, or using a different read method).

When a transaction begins, the SDK passes a ReaderInputOptions value to your app’s reader display handler, denoting the acceptable types of input (for example, Swipe, Insert, or Tap). In your app’s checkout UI, prompt the user to present a card using one of these options.

During the transaction, the SDK might request your app to display additional prompts (for example, Retry Card) to your user by passing a ReaderDisplayMessage value to your app’s reader display handler. Make sure your checkout UI displays these messages to the user.

ReaderViewController.swift
Swift
Objective C
No results
// MARK: MobileReaderDelegate - only needed for Bluetooth readers, this is the delegate set during connectReader func reader(_ reader: Reader, didRequestReaderInput inputOptions: ReaderInputOptions = []) { readerMessageLabel.text = Terminal.stringFromReaderInputOptions(inputOptions) } func reader(_ reader: Reader, didRequestReaderDisplayMessage displayMessage: ReaderDisplayMessage) { readerMessageLabel.text = Terminal.stringFromReaderDisplayMessage(displayMessage) }

Collect payments with Tap to Pay on iPhone

When your application is ready to collect a payment, the Stripe iOS SDK takes over the display to handle the collection process. After calling the process payment method, your application remains running, but the iPhone displays a full-screen prompt to the cardholder, instructing them to present their card or NFC-based mobile wallet. If there’s an error reading the card, a prompt for retry displays. A successful presentation returns a success indication, and then control returns to your application.

Tap to pay on iPhone

Cobro de pagos

  • For manual capture of payments, a successful processPaymentIntent call results in a PaymentIntent with a status of requires_capture.
  • For automatic capture of payments, the PaymentIntent transitions to a succeeded state.

You must manually capture a PaymentIntent within 2 days or the authorization expires and funds are released to the customer.

Handle failures

SDK Reference

  • ConfirmPaymentIntentError (iOS)

When processing a payment fails, the SDK returns an error that includes the updated PaymentIntent if it was declined by stripe. Your application needs to inspect the PaymentIntent to decide how to deal with the error.

PaymentIntent statusSignificadoResolución
requires_payment_methodPayment method declinedTry collecting a different payment method by calling processPaymentIntent again with the same PaymentIntent.
requires_confirmationTemporary connectivity problemCall processPaymentIntent again with the same PaymentIntent to retry the request.
PaymentIntent is nilRequest to Stripe timed out, unknown PaymentIntent statusRetry processing the original PaymentIntent. Don’t create a new one, because that might result in multiple authorizations for the cardholder.

If you encounter multiple, consecutive timeouts, there might be a problem with your connectivity. Make sure that your app can communicate with the internet.

Avoid double charges

The PaymentIntent object enables money movement at Stripe—use a single PaymentIntent to represent a transaction.

Re-use the same PaymentIntent after a card is declined (for example, if it has insufficient funds), so your customer can try again with a different card.

If you edit the PaymentIntent, you must call processPaymentIntent to update the payment information on the reader.

A PaymentIntent must be in the requires_payment_method state before Stripe can process it. An authorized, captured, or canceled PaymentIntent can’t be processed by a reader.

Capture the payment
Lado del servidor

If you defined capture_method as manual during PaymentIntent creation in Step 1, the SDK returns an authorized but not captured PaymentIntent to your application. Learn more about the difference between authorization and capture.

When your app receives a confirmed PaymentIntent from the SDK, make sure it notifies your backend to capture the payment. Create an endpoint on your backend that accepts a PaymentIntent ID and sends a request to the Stripe API to capture it:

Command Line
cURL
Stripe CLI
Ruby
Python
PHP
Java
Node.js
Go
.NET
No results
curl -X POST https://api.stripe.com/v1/payment_intents/{{PAYMENT_INTENT_ID}}/capture \ -u "
sk_test_BQokikJOvBiI2HlWgH4olfQ2
:"

A successful capture call results in a PaymentIntent with a status of succeeded.

To make sure the application fee captured is correct for connected accounts, inspect each PaymentIntent and modify the application fee, if needed, before manually capturing the payment.

Reconcile payments

To monitor the payments activity of your business, you might want to reconcile PaymentIntents with your internal orders system on your server at the end of a day’s activity.

A PaymentIntent that retains a requires_capture status might represent two things:

Unnecessary authorization on your customer’s card statement

  • Cause: User abandons your app’s checkout flow in the middle of a transaction
  • Solution: If the uncaptured PaymentIntent isn’t associated with a completed order on your server, you can cancel it. You can’t use a canceled PaymentIntent to perform charges.

Incomplete collection of funds from a customer

  • Cause: Failure of the request from your app notifying your backend to capture the payment
  • Solution: If the uncaptured PaymentIntent is associated with a completed order on your server, and no other payment has been taken for the order (for example, a cash payment), you can capture it.

Collect tips Solo para EE. UU.

In the US, eligible users can collect tips when capturing payments.

¿Te ha sido útil la página?
SíNo
  • ¿Necesitas ayuda? Ponte en contacto con el equipo de soporte.
  • Echa un vistazo a nuestro registro de cambios.
  • ¿Tienes alguna pregunta? Ponte en contacto con el equipo de ventas.
  • ¿LLM? Lee llms.txt.
  • Con tecnología de Markdoc