Startseite / Entwickler
Händler-Integrationsdokumentation

Payin- und Payout-API – in wenigen Schritten integriert

Einheitliche HTTP-/JSON-Schnittstelle, SHA-256-Signaturprüfung, asynchrone Benachrichtigungen und aktive Auftragsabfrage. Dieses Dokument behandelt die Signaturregeln, sämtliche Schnittstellenfelder und Anfragebeispiele.

Übersicht

India Payme bietet Händlern zwei zentrale Transaktionsfunktionen: Payin (Inkasso) – Zahlungseinzug vom Endkunden im Auftrag des Händlers; Payout (Auszahlung) – Auszahlung an ein angegebenes Konto im Auftrag des Händlers. Alle Schnittstellen sind POST + JSON und erfordern zwingend eine API-Signatur. Nach der Verarbeitung informiert die Plattform den Händler per asynchroner Benachrichtigung; zusätzlich ist eine aktive Auftragsabfrage möglich.

FunktionMethodePfad
Payin-Auftrag erstellenPOST/transaction/payin/v1/apply
Payin-Auftrag abfragenPOST/transaction/payin/v1/query
Payout-Auftrag erstellenPOST/transaction/payout/v1/apply
Payout-Auftrag abfragenPOST/transaction/payout/v1/query
KontostandsabfragePOST/transaction/payout/v1/balance

Basis-URL (die produktive Gateway-Domain wird nach Kontoeröffnung von der Plattform bereitgestellt):

https://{Gateway-Domain}

Vorbereitung

Melden Sie sich im Händler-Backend → App-Schlüssel an. Jede Anwendung besitzt ein Zugangsdaten-Paar: appKey und appSecret. Dabei ist der appKey identisch mit dem Header appId; appSecret ist der Signaturschlüssel, der ausschließlich lokal zur Signaturberechnung dient und nicht übertragen wird.

Alle Anfragen müssen folgende HTTP-Header enthalten, Content-Type ist application/json:

HeaderPflichtBeschreibung
appIdJaHändler-App-ID (entspricht appKey)
timestampJaUnix-Zeitstempel in Millisekunden
nonceJaZufallszeichenfolge, ≥10 Zeichen, einmalig verwendbar
signJaSignatur nach den Regeln im nächsten Abschnitt

Signaturregeln

Der Signaturalgorithmus ist reines SHA-256 (Hexadezimal, Kleinschreibung), kein HMAC. Der appSecret wird direkt an das Ende der zu signierenden Zeichenfolge angehängt, bevor SHA-256 berechnet wird. Schritte:

  1. Die „Top-Level-Felder des Request-Bodys (nur nicht leere)" plus die „Signatur-Header appId, timestamp, nonce" zu einer Map zusammenführen (sign selbst ist nicht enthalten);
  2. Nach Parameternamen ASCII-aufsteigend sortieren und zu key1=value1&key2=value2… zusammensetzen;
  3. Am Ende direkt appSecret anhängen (ohne Trennzeichen) und aus der gesamten Zeichenfolge den SHA-256-Hex-Wert (Kleinschreibung) bilden – das Ergebnis ist sign.
# Zu signierende Zeichenfolge signString = "key1=value1&key2=value2…&keyN=valueN" + appSecret sign = SHA256_HEX(signString) // Kleinschreibung, hexadezimal

Gültigkeit und Replay-Schutz:

  • Zeitstempel 30 Sekunden gültig: |Serverzeit − timestamp| ≤ 30s, andernfalls wird timestamp has expired zurückgegeben. Bitte sorgen Sie für eine Zeitsynchronisation (NTP) zwischen Client und Gateway.
  • Replay-Schutz per nonce: Dieselbe nonce darf nur einmal verwendet werden; bei Wiederverwendung erfolgt die Meldung nonce has been used (Fehlercode 900).
  • Leere Felder werden nicht signiert – die „für die Signatur verwendete Feldmenge" muss exakt mit den „tatsächlich gesendeten JSON-Feldern" übereinstimmen.

Node.js-Signaturbeispiel:

const crypto = require('crypto'); function buildSign(appId, appSecret, timestamp, nonce, body) { const params = { ...body, appId, timestamp, nonce }; const signString = Object.keys(params) .filter(k => params[k] !== null && params[k] !== undefined) .sort() .map(k => `${k}=${params[k]}`) .join('&') + appSecret; return crypto.createHash('sha256').update(signString, 'utf8').digest('hex'); }

Payin-Auftrag erstellen POST

POST /transaction/payin/v1/apply — Erstellt einen Zahlungseingangs-Auftrag und liefert den Bezahlseiten-Link payUrl zurück, über den der Nutzer die Zahlung abschließt.

FeldTypPflichtBeschreibung
merchantOrderNostringJaHändler-Auftragsnummer, muss eindeutig sein
amountnumberJaAuftragsbetrag, Dezimalzahl (z. B. 100.02)
namestringJaName des Nutzers. Nur lateinische Buchstaben, ≥3 Zeichen, Leerzeichen erlaubt, keine Symbole oder Ziffern
phonestringJaTelefonnummer
emailstringJaE-Mail-Adresse
currencystringJaWährung: INR / PKR / USDT / BDT
productstringJaProduktcode, von der Plattform gemäß Vertrag vergeben
notifyUrlstringNeinAdresse für asynchrone Benachrichtigung; ohne Angabe wird die Standardadresse des Händlers verwendet
returnUrlstringNeinWeiterleitungsseite nach erfolgreicher Zahlung
payTypestringNeinDirektzahlung per Wallet: JAZZCASH / EASYPAISA / BKASH / NAGAD
POST /transaction/payin/v1/apply { "merchantOrderNo": "ORD1751731200123", "amount": "600.00", "currency": "INR", "product": "{Produktcode}", "name": "John Doe", "phone": "9910099100", "email": "john@example.com", "notifyUrl": "https://shop.example/pay/notify" }
// Antwort { "code": 0, "msg": "Success", "data": { "orderNo": "P1751731200999", "merchantOrderNo": "ORD1751731200123", "amount": 600, "currency": "INR", "payUrl": "https://{Kassa-Domain}/cashier/xxxx", "payStatus": 0 } }

Leiten Sie den Nutzer nach Erhalt der payUrl zur Zahlung weiter; das endgültige Ergebnis wird ausschließlich über die asynchrone Benachrichtigung bestätigt.

Payout-Auftrag erstellen POST

POST /transaction/payout/v1/apply — Löst eine Auszahlung an ein angegebenes Konto aus. Asynchrone Verarbeitung: Die Schnittstelle prüft und sperrt zunächst das Konto, danach erfolgt die Kanalzuordnung asynchron. Die Rückgabe lautet in der Regel payStatus=0 (Annahme erfolgreich); maßgeblich ist die spätere Abfrage oder Benachrichtigung.

FeldTypPflichtBeschreibung
merchantOrderNostringJaHändler-Auftragsnummer
amountnumberJaAuszahlungsbetrag, mindestens 100.00
accountNamestringJaName des Zahlungsempfängers. Nur lateinische Buchstaben, ≥3 Zeichen, Leerzeichen erlaubt
accountstringJaEmpfängerkonto
phonestringJaTelefonnummer
emailstringJaE-Mail-Adresse
currencystringJaWährung: INR / PKR / USDT / BDT
bizCodestringJaAuszahlungsart: IMPS / UPI / BANK / JAZZCASH / EASYPAISA / BKASH / NAGAD / ECARD
payCodestringJaZahlungsart: CARD / WALLET / NBK / ITT / VC
branchCodestringJaClearing-Code: für Indien IFSC; für Pakistan bankcode; für Bangladesch gemäß bizCode
productstringJaZahlungsprodukt-Code, von der Plattform vergeben
bankNamestringNeinName der Bank
swiftCodestringNeinSWIFT-Code (für grenzüberschreitende ITT-Überweisungen)
POST /transaction/payout/v1/apply { "merchantOrderNo": "PO1751731200123", "amount": "1500.00", "currency": "INR", "product": "{Produktcode}", "accountName": "John Doe", "account": "1234567890", "bizCode": "IMPS", "payCode": "NBK", "branchCode": "HDFC0000001", "bankName": "HDFC", "phone": "9910099100", "email": "john@example.com" }

Auftragsabfrage POST

Payin: POST /transaction/payin/v1/query, Payout: POST /transaction/payout/v1/query. Übergeben Sie merchantOrderNo oder orderNo zur Auftragsidentifikation. Rate-Limit: 5 Anfragen/Sekunde.

POST /transaction/payin/v1/query { "merchantOrderNo": "ORD1751731200123" }
// Rückgabe data { "orderNo": "P1751731200999", "merchantOrderNo": "ORD1751731200123", "amount": 600, "realAmount": 600, "currency": "INR", "payStatus": 1 // 0 in Bearbeitung / 1 bezahlt / -1 storniert }

Kontostandsabfrage POST

POST /transaction/payout/v1/balance — Fragt den Kontostand des Händlers ab. Rate-Limit: 5 Anfragen/Sekunde.

POST /transaction/payout/v1/balance { "currency": "INR" }
// Rückgabe data { "accountNo": "ACC0001", "currency": "INR", "balance": 100000.00, // Gesamtguthaben "balanceActive": 98500.00, // Verfügbares Guthaben "balanceFreeze": 1500.00 // Gesperrtes Guthaben }

Asynchrone Benachrichtigung

Sobald ein Auftrag einen Endstatus erreicht, benachrichtigt die Plattform per POST (JSON) die notifyUrl des Händlers (ohne Angabe wird die Standardadresse verwendet) und sendet dabei dieselben Signatur-Header (appId/timestamp/nonce/sign) mit. Der Händler sollte mit dem eigenen appSecret nach denselben Regeln die Signatur neu berechnen und vergleichen, um die Echtheit der Benachrichtigung zu prüfen.

Die Payin-Benachrichtigung enthält: merchantOrderNo, orderNo, currency, product, amount, realAmount, status (bei erfolgreichem Zahlungseingang "1"). Die Payout-Benachrichtigung enthält zusätzlich utr (Bank-Transaktionsnummer) und statusDes (Statusbeschreibung); status ist "1" für erfolgreich / "2" für fehlgeschlagen.

// Beispiel für Payin-Benachrichtigungs-Body { "merchantOrderNo": "ORD1751731200123", "orderNo": "P1751731200999", "currency": "INR", "product": "{Produktcode}", "amount": "600.00", "realAmount": "600.00", "status": "1" }

Der Händler muss den reinen Text OK oder success zurückgeben (Groß-/Kleinschreibung unerheblich). Andernfalls stellt die Plattform die Zustellung in eine Wiederholungswarteschlange: maximal 5 Versuche, mit steigenden Intervallen in Minuten (1 / 2 / 5 / 10 / 30 / 60 / 120). Die Händlerschnittstelle muss daher idempotent sein (dieselbe orderNo kann mehrfach benachrichtigt werden).

Auftragsstatus

Für die Integration maßgeblich sind die folgenden öffentlichen Statuswerte (die interne Zustandsmaschine ist feingranularer und wird nicht direkt offengelegt):

SzenarioFeldWerte
Rückgabe bei AuftragsannahmepayStatus0 erstellt / 1 erfolgreich / 2 fehlgeschlagen / 3 storniert
Payin-AbfragepayStatus0 in Bearbeitung / 1 bezahlt / -1 storniert
Payout-AbfragepayStatus0 ausstehend / 1 ausgezahlt / -1 storniert
Asynchrone BenachrichtigungstatusPayin erfolgreich "1"; Payout "1" erfolgreich / "2" fehlgeschlagen

Fehlercodes

Ist code != 0 in der Antwort, ist die Anfrage fehlgeschlagen; msg enthält den Hinweistext. Häufige Fehlercodes:

codeBeschreibung
0Erfolgreich
400Parameterfehler / Signaturprüfung fehlgeschlagen (Sign invalid)
900Doppelte Anfrage / nonce erneut verwendet
10000 / 10001App existiert nicht / App nicht verfügbar
10002Währung nicht unterstützt
10003 / 10007Händler nicht verfügbar / Händlerkonto nicht verfügbar
10004Produkt nicht freigeschaltet oder Vertrag abgelaufen
10005 / 10009Kein Kanal verfügbar / Kanal vorübergehend nicht verfügbar
10008Kontoguthaben unzureichend
10010IP nicht in der Whitelist
10011 / 10012Produkt ungültig / Zahlungsart ungültig
10020Händler-Auftragsnummer bereits vergeben
30001 / 30002Auftragsnummer fehlerhaft / Währung fehlerhaft oder Konto nicht aktiviert

Vollständiger Integrationsablauf

Am Beispiel eines Payin-Auftrags:

  1. Fachlichen Request-Body zusammenstellen (siehe Felder unter „Payin-Auftrag erstellen").
  2. timestamp (Millisekunden) und nonce (Zufallsstring ≥10 Zeichen) generieren.
  3. sign gemäß „Signaturregeln" berechnen.
  4. Mit den 4 Signatur-Headern + JSON-Body POST /transaction/payin/v1/apply aufrufen.
  5. Bei code==0 aus data.payUrl die Zahlung des Nutzers einleiten.
  6. Auf asynchrone Benachrichtigung warten; zusätzlich kann der Endstatus aktiv abgefragt werden.
  7. Nach Erhalt der Benachrichtigung Signatur prüfen, Geschäftslogik verarbeiten und reinen Text OK zurückgeben.

Hinweis: Die in diesem Dokument genannten Schnittstellenpfade, Felder und Statuscodes entsprechen der Produktivimplementierung; die produktive Gateway-Domain, verfügbare product-Produktcodes sowie die IP-Whitelist-Richtlinie werden nach Kontoeröffnung von der Plattform bereitgestellt.

Schlüssel erhalten, direkt loslegen

Eröffnen Sie Ihr Konto online und erhalten Sie Testzugangsdaten sowie Produktcodes – nach erfolgreichem Sandbox-Test wechseln Sie mit einem Klick in die Produktivumgebung.