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.

BASE URLhttps://apiserv.sggg.in/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.

Important: call us only when the payment has already succeeded. Do not call us before or during payment. Every record we hold is a completed donation — this is what keeps our receipt numbering free of gaps.

01Integration flow

Collect the details, take the payment, then tell us. One call.

1
Fill the form on your terminal. Donor name, address, purpose, amount, 80G, PAN / Aadhaar. Validate everything here, before taking money — see Rejections & refunds.
2
Take the payment. Card, UPI, QR, cash — however the donor pays. The middleware isn't involved.
3
Payment succeeded → 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.
4
Print the receipt using the 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

POST/api/reserve.php

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_numberrequiredYour own transaction number. Must be unique per terminal. This is the idempotency key — see Retries.
payment_moderequiredOne of: CREDITCARD, DEBITCARD, UPI, QR, CASH, CHEQUE, NETBANKING, OTHER.
payment_refrequired*Bank / gateway reference. Required for every mode except CASH (cash has no reference). For cheque, send the cheque number.
donor_namerequiredDonor's full name.
donor_phonerequiredDonor's 10-digit Indian mobile. +91, spaces and dashes are accepted and stripped. Used for receipts and follow-up.
purposerequiredWhat the donation is for.
amountrequiredIn rupees, e.g. 5000 or 500.50. Alternatively send amount_paise as an integer.
want_80goptionaltrue if the donor wants an 80G receipt. Makes pan and donor_address required.
donor_addressrequired if 80GDonor's address. Mandatory when want_80g is true.
panrequired if 80GFormat ABCDE1234F. Mandatory when want_80g is true. Aadhaar cannot substitute for PAN on an 80G receipt.
aadhaaroptional12 digits. Stored encrypted; only the last 4 are ever displayed.
extraoptionalAny 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.

Why we only issue numbers after payment. A receipt series must run without gaps for audit purposes. Because we're called only for successful payments, every number we issue is a real, completed donation — the series is gap-free by construction. This is why you must not call us before the payment completes.

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.

This matters most when the payment succeeded but our response was lost. Retry with the same 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.

Validate everything on your terminal BEFORE taking payment. If a required field is missing, we return 422 — but by then the donor has already paid. Client-side validation is what prevents this situation entirely.

If we do reject a submission:

1
Retry 2–3 times with backoff, reusing the same pos_txn_number — the failure may be transient.
2
If it still fails, refund the donor. The donation cannot be recorded and must not be kept.

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.

POST/api/attempt.php

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_namerequiredDonor's full name.
donor_phonerequired10-digit Indian mobile. Without this we cannot capture the lead — there would be no one to call.
amountrequiredRupees (or amount_paise).
purposerequiredWhat the donation was for.
pos_txn_numberoptionalIf sent, makes the call idempotent (a retry won't create a duplicate lead).
payment_modeoptionalHow they tried to pay.
failure_reasonoptionalWhy it failed (e.g. "Card declined"). Helps the follow-up call.
donor_addressoptionalIf you have it.
Validation here is deliberately lenient — the goal is to capture a callable lead, not to enforce receipt rules. Send what you have (name, phone, amount, purpose) and we'll store it.

09Error codes

All errors return {"ok": false, "error": "reason"}. Read the error field.

400Malformed JSONFix the request body.
401Missing / invalid API keyCheck the Authorization header.
403Terminal revoked / vendor suspendedContact SGGG.
422Validation errorRead error. Retry, then refund — see Rejections.
429Rate limit exceededWait the seconds given in the Retry-After header, then retry.
500Server errorSafe 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

Rate limit. Each terminal may send a limited number of requests per minute (default 60 — ample for normal use). If you exceed it you get a 429 with a 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.

1
Happy path. Take a payment, call the API, get a 201 with a sequence_no. Print it.
2
Idempotent retry. Send the exact same pos_txn_number again → you get the same sequence_no, not a new one.
3
80G without PAN. Send want_80g: true with no pan → expect 422.
4
80G without address. Send want_80g: true, a PAN, but no donor_address → expect 422.
5
Missing payment_ref. Send payment_mode: "UPI" with no payment_ref → expect 422. Then send CASH with no ref → expect 201.
6
Phone required. Send a donation with no donor_phone → expect 422 donor_phone is required.
7
Failed-attempt capture. POST to /api/attempt.php with name, phone, amount, purpose → expect 201 with an attempt_id. It must NOT get a receipt number.
6
Bad key. Use a wrong API key → expect 401.
7
Refund path. Confirm your terminal refunds the donor when we reject after your retries are exhausted.
8
Client-side validation. Confirm your form blocks payment until all required fields are present.

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:

OverviewYour terminals, their health, and daily totals.
UAT TransactionsYour 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 LogsEvery 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.
The portal shows only your data. You cannot see other organisations' terminals or donations, and production donor personal details stay out of the portal entirely.

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.