Integration Guide
Collect donations through the SGGG middleware
Take the payment on your side. Once it has succeeded, make one API call with the donation details — we record it and return the official receipt number to print. One call, one key per terminal. POS terminals are the typical integrator, but any system that collects donations can use this API.
00What this does
The middleware records every completed donation and issues its official receipt sequence number, so our books match your receipts exactly. Card data never touches us — payment stays entirely on your side.
A donation captures: donor name, address, purpose, amount, how it was paid, an 80G checkbox, and PAN / Aadhaar where applicable. You send all of it in a single call after the payment has succeeded, and we return the receipt number.
01Integration flow
Collect the details, take the payment, then tell us. One call.
reserve. Send the donation details plus your transaction number, the payment reference and the payment mode.
If the payment failed, don't call us at all — there's nothing to record.
sequence_no we return.
02Authentication
Every request carries the terminal's API key as a bearer token. One key per terminal or integration point (for POS, that's one key per physical machine).
Authorization: Bearer sggg_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx Content-Type: application/json
One key = one terminal / integration point. The key maps to a terminal code (e.g. POS007) that appears in every sequence it issues. Keys are shared with you separately over a secure channel — never in email or in this page.
03Record a donation
Call once, after the payment has succeeded. Records the donation and returns the official receipt number.
{
"pos_txn_number": "POS-TXN-99881",
"payment_mode": "CREDITCARD",
"payment_ref": "HDFC8891234",
"donor_name": "Ramesh Kumar",
"donor_phone": "9876543210",
"donor_address": "12 MG Road, Delhi",
"purpose": "Gou Sewa",
"amount": 5000,
"want_80g": true,
"pan": "ABCDE1234F",
"aadhaar": "123456789012"
}Response — 201 Created
{
"ok": true,
"data": {
"sequence_no": "POS007-2026-07-10-0042",
"pos_txn_number": "POS-TXN-99881",
"donor_phone": "9876543210",
"payment_mode": "CREDITCARD",
"payment_ref": "HDFC8891234",
"status": "SUCCESS",
"amount": "5000.00",
"service_date": "2026-07-10",
"is_test": false
}
}Print sequence_no on the donor's receipt. is_test tells you whether this key is a UAT key (true) or production (false).
04Fields
pos_txn_number | required | Your own transaction number. Must be unique per terminal. This is the idempotency key — see Retries. |
payment_mode | required | One of: CREDITCARD, DEBITCARD, UPI, QR, CASH, CHEQUE, NETBANKING, OTHER. |
payment_ref | required* | Bank / gateway reference. Required for every mode except CASH (cash has no reference). For cheque, send the cheque number. |
donor_name | required | Donor's full name. |
donor_phone | required | Donor's 10-digit Indian mobile. +91, spaces and dashes are accepted and stripped. Used for receipts and follow-up. |
purpose | required | What the donation is for. |
amount | required | In rupees, e.g. 5000 or 500.50. Alternatively send amount_paise as an integer. |
want_80g | optional | true if the donor wants an 80G receipt. Makes pan and donor_address required. |
donor_address | required if 80G | Donor's address. Mandatory when want_80g is true. |
pan | required if 80G | Format ABCDE1234F. Mandatory when want_80g is true. Aadhaar cannot substitute for PAN on an 80G receipt. |
aadhaar | optional | 12 digits. Stored encrypted; only the last 4 are ever displayed. |
extra | optional | Any additional JSON you want stored with the donation. |
05Sequence number
The receipt number we return, e.g. POS007-2026-07-10-0042.
POS007 - 2026-07-10 - 0042 | | | terminal date counter
Terminal code — tied to your API key. Date — the service date. Counter — resets to 0001 each day, per terminal.
06Retries & idempotency
Networks time out. Retrying is safe — as long as you reuse the same pos_txn_number.
The pos_txn_number is the idempotency key. If you send the same one twice, we return the original record with the original sequence_no. We never create a second donation or a second receipt number for it.
pos_txn_number and you'll get the receipt number back safely. Never generate a new pos_txn_number for a retry — that would create a duplicate donation.
Please back off between retries — e.g. wait 1s, then 2s, then 4s, capped at 3–4 attempts. Rapid-fire retries can trip the rate limit unnecessarily.
07Rejections & refunds
Because you call us after taking the money, a rejection needs handling carefully.
If we do reject a submission:
pos_txn_number — the failure may be transient.A pattern of 422 responses means your form validation is letting incomplete data through — we can see these in our logs and will flag them.
08Failed payments & follow-up
When a payment fails, tell us — so we can follow up with the donor and help them complete their gift.
Call this when a payment fails on your terminal, sending the details you already collected on the form. This is not a donation — no receipt number is issued, and it never appears in donation totals or 80G exports. It is stored only as a follow-up lead.
{
"pos_txn_number": "POS-TXN-99882",
"donor_name": "Ramesh Kumar",
"donor_phone": "9876543210",
"amount": 5000,
"purpose": "Gou Sewa",
"payment_mode": "CREDITCARD",
"failure_reason": "Card declined"
}Response — 201 Created
{
"ok": true,
"data": {
"attempt_id": 1,
"status": "CAPTURED",
"pos_txn_number": "POS-TXN-99882",
"donor_phone": "9876543210",
"amount": "5000.00",
"is_test": false
}
}donor_name | required | Donor's full name. |
donor_phone | required | 10-digit Indian mobile. Without this we cannot capture the lead — there would be no one to call. |
amount | required | Rupees (or amount_paise). |
purpose | required | What the donation was for. |
pos_txn_number | optional | If sent, makes the call idempotent (a retry won't create a duplicate lead). |
payment_mode | optional | How they tried to pay. |
failure_reason | optional | Why it failed (e.g. "Card declined"). Helps the follow-up call. |
donor_address | optional | If you have it. |
09Error codes
All errors return {"ok": false, "error": "reason"}. Read the error field.
| 400 | Malformed JSON | Fix the request body. |
| 401 | Missing / invalid API key | Check the Authorization header. |
| 403 | Terminal revoked / vendor suspended | Contact SGGG. |
| 422 | Validation error | Read error. Retry, then refund — see Rejections. |
| 429 | Rate limit exceeded | Wait the seconds given in the Retry-After header, then retry. |
| 500 | Server error | Safe to retry with the same pos_txn_number. |
Common 422 reasons: pos_txn_number is required · payment_mode is required · payment_ref is required for payment_mode UPI · donor_name is required · amount must be greater than zero · Invalid PAN format · PAN is required when 80G receipt is requested · donor_address is required when 80G receipt is requested
Retry-After header. If a terminal legitimately needs a higher limit, ask SGGG to raise it.10Request builder
Fill this in to generate a ready-to-run curl command.
Fill the fields above…
11Go-live checklist
Run these against your UAT key before asking for production keys.
sequence_no. Print it.pos_txn_number again → you get the same sequence_no, not a new one.want_80g: true with no pan → expect 422.want_80g: true, a PAN, but no donor_address → expect 422.payment_mode: "UPI" with no payment_ref → expect 422. Then send CASH with no ref → expect 201.donor_phone → expect 422 donor_phone is required./api/attempt.php with name, phone, amount, purpose → expect 201 with an attempt_id. It must NOT get a receipt number.12Your partner portal
You can see your own activity any time — no need to ask us. Log in at:
https://apiserv.sggg.in/partner/login.php
Your login is created when your organisation is set up; credentials are shared with you separately. Inside, scoped to your terminals only, you can see:
| Overview | Your terminals, their health, and daily totals. |
| UAT Transactions | Your test (UAT) donations with full details — donor, amount, payment mode, PAN, 80G, status — so you can confirm your integration is sending data correctly. Production donor details are not shown in the portal. |
| API Logs | Every API call your terminals made — both successful and rejected — with the HTTP status and the exact reason for any rejection. This is the fastest way to debug a 422 during integration: hover a row to see what was sent and why it was refused. |
13Support
When reporting an issue, include the terminal code and the pos_txn_number involved — that's everything we need to trace it in our logs.