Skip to main content

POS Terminal Integration

This guide walks through integrating Stable Genius payments into a physical point-of-sale terminal. By the end, your terminal will display a QR code, detect payment, and confirm the sale — all through two API calls.

Overview

The integration pattern for POS terminals is:
  1. Your terminal creates a payment intent when the cashier finalizes an order
  2. The terminal displays the QR code on screen
  3. The customer scans and pays from their wallet
  4. Your terminal receives a webhook and shows a success screen

Prerequisites

  • Stable Genius API key (sk_test_* for development)
  • A merchant onboarded via the dashboard
  • A terminal with a screen capable of displaying QR codes
  • Network connectivity (WiFi or cellular) for API calls and webhooks

Step 1: Create Payment Intent at Checkout

When the cashier presses “Pay” or “Charge,” your terminal calls the API:

Step 2: Display QR Code

Render the QR code on the terminal screen. You have two options: Option A: Render from payload (recommended for terminals with QR libraries)
Option B: Display hosted image (simpler, no QR library needed)

Step 3: Wait for Payment Confirmation

Your backend receives the webhook when the customer pays. Push the confirmation to the terminal:

Step 4: Show Success on Terminal

When the terminal receives the confirmation push:

Terminal-to-Server Communication

The webhook fires to your backend, not directly to the terminal. You need a way to push updates from your backend to the terminal. Common patterns:
Need the lowest latency? Contact us about direct integration options for real-time payment notifications on your terminals.

Handling Edge Cases

Customer sends wrong amount: The payment intent tracks the expected amount. If the customer sends more or less, the transaction.created webhook fires with the actual amount. Your system should reconcile and handle over/underpayments per your business logic. Network disconnection: If the terminal loses connectivity after displaying the QR code, the payment still works — the customer’s on-chain transaction is independent of your terminal’s connection. When connectivity resumes, the webhook will be retried and delivered. Terminal reboot mid-payment: Store the active payment_intent_id locally. On reboot, call GET /v1/payment-intents/{id} to check if payment was received while offline.
Building on Android? Our first-party POS terminal (Genie) runs on Android. Contact us about licensing the terminal software or building on our hardware platform.