POS Integration Guide
Collect donations through the SGGG middleware
Your POS terminal reserves a receipt number, runs the card payment on your switch, then tells us whether it succeeded or failed. Three calls, one key per machine. This page has everything your integrator needs.
00What this does
The middleware issues a unique receipt sequence number for every donation and records the final payment outcome so our books match your receipts. Card data never touches us — payment stays entirely on your side.
A donation captures: donor name, address, purpose, amount, an 80G checkbox, and optionally PAN / Aadhaar. You send those when you reserve; we hand back a sequence number to print on the receipt.
01Integration flow
Call reserve first so the sequence number is ready to print, run the payment, then call confirm or fail.
Reserve
Send donor + amount details to /reserve.php. Get back a sequence_no and status RESERVED.
Run the payment
Your POS / switch charges the card or QR. The middleware isn't involved.
Confirm or fail
On success call /confirm.php → SUCCESS. On failure call /fail.php → FAILED. Print the sequence number on the receipt for successful donations.
txn_reference across all three calls for one donation, so every call points at the same record.02Authentication
Every request carries the terminal's API key as a bearer token. One key per physical machine.
| Detail | Value |
|---|---|
| Header | Authorization: Bearer <key> (or X-API-Key: <key>) |
| Scope | One key = one terminal. The key maps to a machine number (e.g. POS007) that appears in every sequence it issues. |
| Content-Type | application/json on every request |
| Method | All endpoints are POST |
03Reserve a sequence
Validates the donation, issues a receipt sequence number, and records it as RESERVED.
Request body
| Field | Type | Notes |
|---|---|---|
| txn_reference | string required | Your unique id for this attempt. The idempotency key. |
| donor_name | string required | — |
| purpose | string required | Fund / purpose of donation. |
| amount | number required* | Rupees, e.g. 501.00. |
| amount_paise | integer alt | *Send this or amount, not both. |
| donor_address | string optional | — |
| want_80g | boolean optional | If true, pan becomes required. |
| pan | string optional | Format ABCDE1234F. |
| aadhaar | string optional | 12 digits. |
| extra | object optional | Any future fields; stored as-is. |
Example request
Response 201
txn_reference returns the same sequence_no — no duplicate is created.04Confirm a payment
Marks a reserved donation as SUCCESS after the payment clears.
Request body
| Field | Type | Notes |
|---|---|---|
| txn_reference | string one of† | Same reference used in reserve. |
| sequence_no | string one of† | †Send txn_reference or sequence_no. |
| payment_ref | string optional | Bank / POS payment id, for reconciliation. |
05Report a failure
Marks a reserved donation as FAILED. The sequence number is burned — kept for audit, never reused.
Request body
| Field | Type | Notes |
|---|---|---|
| txn_reference | string one of† | — |
| sequence_no | string one of† | †Send either one. |
| failure_reason | string optional | Free text. |
06Sequence number
Print this exactly as returned on the receipt. Don't reformat or pad it.
MACHINE | The terminal's machine number, tied to its API key. |
YYYY-MM-DD | Service date (IST). |
NNNN | Counter that resets to 0001 each day, per machine. |
07Retries & idempotency
POS networks time out. Every endpoint is safe to retry as long as you reuse the same txn_reference.
| txn_reference rule | Why |
|---|---|
| Generate once per attempt | Before the reserve call. A UUID or your internal txn id works. |
| Unique per terminal | Two donations must never share one reference. |
| Reuse across all 3 calls | So reserve → confirm/fail all resolve to the same record. |
Retry policy
| Timeout / 5xx | Retry the same request up to 3× with backoff (1s, 2s, 4s). |
| 4xx | Don't blindly retry — fix the request. It's a data or auth problem, not a glitch. |
| Lost result | If a payment succeeds but the confirm never lands, the record stays RESERVED. Send confirm later with the same reference — it still works. |
08Error codes
All errors share one shape: { "ok": false, "error": "message" }
| HTTP | Meaning | What to do |
|---|---|---|
| 400 | Bad request / invalid JSON | Check the body is valid JSON. |
| 401 | Missing / invalid API key | Check the Authorization header and key. |
| 403 | Terminal revoked or vendor suspended | Contact SGGG. |
| 404 | Transaction not found | The reference/sequence doesn't exist for this terminal. |
| 409 | Conflicting status | Outcome already recorded — reconcile, don't retry. |
| 422 | Validation error | Read error; fix the field (e.g. 80G without PAN). |
| 500 | Server error | Safe to retry with the same txn_reference. |
09Request builder
Fill these in to generate a ready-to-run curl command for a reserve call. Nothing is sent from this page — it only builds the command for you to run.
10Go-live checklist
Run these against your test key before asking SGGG for production keys.
Happy path
reserve → confirm. You get a sequence_no and a final SUCCESS.
Failed payment
reserve → fail. Status is FAILED and the number isn't reissued to the next donation.
Idempotent reserve
Send the same txn_reference twice — identical sequence_no, one record.
80G without PAN
Confirm you get a 422 and your UI blocks it before submit.
Bad key
A wrong key returns 401 and the device handles it gracefully.