Skip to main content
A payment intent represents a request to collect a card-present payment through a Compago POS terminal. Unlike one-time payments (which generate hosted checkout links for online use), payment intents are designed for in-person, terminal-based payment flows where your system orchestrates the transaction and a physical terminal handles card capture.

What You Can Do

With payment intents, you can:
  • Initiate Terminal Payments: Create a payment request that a POS terminal picks up and processes
  • Track Payment Status: Poll for real-time status updates as the terminal processes the card
  • Cancel Pending Payments: Cancel payment intents that haven’t been completed yet
  • Link to Your Systems: Use external IDs to correlate Compago payments with your internal records
  • Target Specific Terminals: Optionally route payment requests to a specific terminal by its serial number
  • Return to Your App: Optionally tell the Compago POS app which app to open once the payment finishes (same-device flow)

Use Cases

Payment intents are designed for:
  • Custom POS Integrations: Build your own point-of-sale system that uses Compago terminals for card processing
  • ERP Payment Modules: Add card-present payment capabilities to ERP systems (e.g., Odoo, SAP)
  • Kiosk Applications: Self-service kiosks that accept card payments through connected terminals
  • Restaurant/Retail Systems: Any in-person checkout flow where your software manages the transaction

How It Works

After creating a payment intent, there are two ways to handle the payment flow depending on your setup. Both start the same way (your backend creates the payment intent via the API), but differ in how the card payment is captured. Use this when the Compago POS app is installed on the same device as your integration (e.g., an Android tablet running both your POS app and the Compago app). Your app opens the Compago app via a deep link, and the Compago app handles the entire card capture flow. When the payment is complete, control returns to your app.
1

Your system creates a payment intent

POST /api/payment-intent with amount, currency, externalId, and optionally terminalCode. Include redirectAppId with your app’s Android application id so the Compago app automatically returns to your app when the payment finishes. Compago returns the payment intent with status: PENDING.
2

Your app opens the Compago POS app

Use the deep link compago-pos-app:///charge/payment-intent/{id} to hand off to the Compago app. The Compago app displays the payment screen and handles card capture.
3

The Compago app returns to your app

When the payment finishes (or is cancelled), the Compago app opens the app specified in redirectAppId, handing control back to your app.
4

Your system polls for status

While the Compago app handles the payment, your system polls GET /api/payment-intent/{id} every 3 seconds to detect when the payment completes.
5

Your system fulfills the order

Once paymentSummary.status is SUCCESS, mark the order as paid, print a receipt, update inventory, etc.

Separate-Device Flow (Polling Only)

Use this when the Compago POS terminal is a separate physical device from the one running your integration (e.g., your ERP runs on a desktop and the terminal sits on the counter). Your system simply polls for status while the terminal operator processes the card on the Compago device.
1

Your system creates a payment intent

POST /api/payment-intent with amount, currency, externalId, and terminalCode. Compago returns the payment intent with status: PENDING.
2

Compago notifies the POS terminal

The terminal automatically receives a notification alerting it that a new payment request is waiting.
3

The terminal processes the card

The terminal operator sees the incoming payment request on the Compago POS app and processes the customer’s card.
4

Your system polls for status

GET /api/payment-intent/{id} every 3 seconds. Once the terminal completes the payment, the response includes paymentSummary.status: "SUCCESS".
5

Your system fulfills the order

Mark the order as paid, print a receipt, update inventory, etc.
Both flows use the same API endpoints. The only difference is whether your client-side app opens the Compago POS app via deep link before polling. Choose based on whether your app and the Compago POS app run on the same device.

Prerequisites

Before creating payment intents, ensure you have:
  • An active Compago merchant account with API access
  • A valid API key (generate one at Configuraciones -> Desarrollador in your Compago Dashboard)
  • At least one Compago POS terminal registered to your organization
  • Your integration configured to use MXN currency
Payment intents currently support MXN (Mexican Peso) only. Transactions in other currencies will be rejected.

Creating a Payment Intent

Endpoint

API reference: POST /payment-intent

Authentication

Include your API key in the request headers:

Request Body

Field Descriptions

Response

Save the returned id. You will need it to poll for status, open the Compago app, or cancel the payment intent.

Example with cURL

Opening the Compago App (Same-Device Flow)

If the Compago POS app is installed on the same device as your integration, you can open it directly using a deep link. The Compago app will display the payment screen for the given payment intent and handle the full card capture flow.
Replace {id} with the payment intent ID returned from the create endpoint.

Implementation Example

On Android-based POS devices, you can trigger the deep link by navigating to the URL. For web-based integrations running on the same device, a common approach is using a hidden iframe:
The deep link requires the Compago POS app to be installed on the device. If the app is not installed, the deep link will have no effect. Your integration should still poll for status regardless, so the payment can also be processed from a separate device.
After opening the Compago app, your system should immediately begin polling for the payment status (see next section). The polling logic is identical for both flows.

Returning to Your App (redirectAppId)

In the same-device flow, you usually want the terminal to hand control back to your app once the payment finishes. Pass your app’s Android application id in the redirectAppId field when creating the payment intent:

Behavior

  • When the payment completes successfully, the Compago POS app opens the app identified by redirectAppId.
  • When the payment intent is cancelled, the Compago POS app also returns to that app.
  • redirectAppId takes precedence over the integration configured locally on the terminal (Settings, Integraciones). If the field is omitted, the terminal keeps using its local configuration.
  • The terminal’s local “Regresar automáticamente” setting controls the timing: when enabled, the app opens immediately; when disabled, the operator sees a confirmation screen with a button to return to your app.
  • If the app is not installed on the terminal device, the terminal shows its standard completion screen instead.
redirectAppId only has an effect in the same-device flow. In the separate-device flow there is no app to return to on the terminal, so the field is ignored unless the app happens to be installed on the terminal device.

Polling for Payment Status

After creating a payment intent (and optionally opening the Compago app via deep link), your system should poll the GET endpoint to detect when the terminal completes the payment.

Endpoint

API reference: GET /payment-intent/{id}

Response

When the payment is still being processed:
When the payment has been completed successfully:

How to Poll

The recommended approach is:
  1. Wait 3 seconds between each request
  2. Check the response for a terminal state:
    • paymentSummary.status is "SUCCESS": the payment was completed. Fulfill the order.
    • expired is true: the payment intent timed out. Prompt the user to retry.
    • status is "CANCELLED": the payment intent was cancelled. Handle accordingly.
  3. Repeat until one of the above conditions is met, or until a maximum timeout (e.g., 10 minutes)

Example

Cancelling a Payment Intent

You can cancel a pending payment intent before it is completed or expires. This is useful when the user changes their mind, navigates away, or the order is voided.

Endpoint

API reference: POST /payment-intent/{id}/cancel For the full cancel guide, see Cancel Payment Intent.

Example

Cancelling a payment intent also notifies the POS terminal that the payment request has been withdrawn.

Important Business Rules

Payment Intent Expiration

Payment intents expire 10 minutes after creation. If the terminal does not process the payment within this window, the payment intent becomes invalid. Create a new payment intent if needed.

Terminal Routing

When you provide a terminalCode:
  • The payment intent is routed to that specific terminal
  • Any other PENDING payment intents for that terminal are automatically cancelled
  • This ensures only one active payment intent exists per terminal at any time
When you omit terminalCode:
  • The payment intent is available to any terminal in your organization
  • This is useful when you don’t know which terminal will process the payment

External ID Uniqueness

The externalId must be unique within your organization. Attempting to create a payment intent with a duplicate externalId will result in an error. Use a combination of your internal identifiers with a timestamp or random suffix to ensure uniqueness across retries. For example: order-789_1710150000_a1b2c3.

Currency Restriction

Currently, only MXN (Mexican Peso) is supported. Requests with other currencies will be rejected.

Payment Intent Status

Payment intents have three statuses:

Error Handling

Common Errors

Example Error Response

Best Practices

When you know which terminal should process the payment, always provide the terminalCode. This ensures the payment intent is routed to the correct terminal and automatically cancels any stale pending intents on that terminal.
Payment intents expire after 10 minutes. Your integration should:
  1. Detect expiration in your polling loop (when expired is true)
  2. Offer the user the option to retry
  3. Create a new payment intent with a new externalId if they choose to retry
Combine your internal identifiers with a timestamp or random suffix to avoid collisions. For example: session-5_order-abc_1710150000. Avoid reusing the same ID for retries, since duplicate externalId values within the same organization will be rejected.
If the user navigates away from the payment screen or cancels the order, send a cancel request for the pending payment intent. This frees up the terminal and prevents stale intents from blocking new payments.
When your app runs on the same device as the Compago POS app, always send redirectAppId with your app’s application id. This guarantees a seamless round trip (your app, Compago app, your app) without relying on the terminal’s local integration configuration.

Support

If you encounter issues with payment intents:
  • Verify your API key is valid in Configuraciones -> Desarrollador at app.compago.com
  • Ensure you have at least one terminal registered to your organization
  • Check that the terminalCode matches your terminal’s serial number
  • Contact Compago support at help@compago.com for assistance