Initiate Payment
Create a payment and get a hosted checkout link.
POST
/v1/route/initiate_paymentCreates a transaction and returns a hosted payment_link to redirect your customer to. GrowthBnk routes the payment to the best-fit payment aggregator/gateway server-side based on your configured routing rules — you never choose the gateway yourself.
Authentication
This endpoint is authenticated with your API key plus a per-request SHA-256 hash. Send the key in X-API-Key and the hash in Hash:
Hash formula
Hash = SHA256(key|merchant_transaction_id|transaction_amount|salt), joined with the | character. Your salt is a server-side secret — see the Authentication guide.
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| X-API-Key | string | Required | Your merchant API key. |
| Hash | string | Required | SHA-256 auth hash (see Authentication). |
| Content-Type | string | Required | Must be application/json. |
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchant_transaction_id | string | Required | Your own unique reference for this payment. Also feeds the auth hash. Non-empty, ≤ 255 chars. Must be unique per merchant. |
| transaction_amount | string / number | Required | Amount in rupees (INR). Decimal, minimum 1.00, two-decimal precision. |
| currency | string | Optional | ISO currency code. Defaults to INR. |
| customer_details | object | Required | Nested customer object (see below). Must include at least one of email or phone. |
| customer_details.customer_email | string | Optional | Customer email. Valid email. Required if phone absent. |
| customer_details.customer_phone | string | Optional | Customer phone. Digits only, 7–15 chars. Required if email absent. |
| customer_details.customer_name | string | Optional | Customer name. |
| payment_method | string | Optional | Preferred payment method used in routing. One of CC, DC, NB, UPI, CASH, EMI, PAY_LATER. |
| surl | string (URL) | Optional | Success redirect URL. Absolute URL. |
| furl | string (URL) | Optional | Failure redirect URL. Absolute URL. |
Responses
A successful call returns HTTP 201 Created. Response fields:
| Field | Type | Description |
|---|---|---|
| success | boolean | Always true on success. |
| payment_link | string | Hosted checkout URL — redirect the customer here. |
| transaction_id | string | GrowthBnk transaction id (TXN<YYYYMMDD><epoch_ms>). |
| merchant_transaction_id | string | Echo of your supplied reference. |
| message | string | Human-readable status message. |
Example responses
Success
201 Created
{
"success": true,
"payment_link": "https://api.growthbnk.com/v1/route/pay/8f14e45fceea167a5a36dedd4bea2543",
"transaction_id": "TXN20260707172038123",
"merchant_transaction_id": "ORDER-2026-0001",
"message": "Payment Initiated Successfully"
}Validation error
400 Bad Request
{
"success": false,
"message": [
{
"transaction_amount": "Invalid amount or less than 1 rupee"
}
]
}Invalid hash
401 Unauthorized
{
"detail": "Invalid authentication hash."
}Status Codes
| Status | Meaning |
|---|---|
| 201 Created | Payment created successfully. |
| 400 Bad Request | Missing or invalid parameters / no routing rule matched. |
| 401 Unauthorized | Bad API key or hash mismatch. |
| 500 Internal Server Error | Gateway selection or transaction creation failed. |
Error Codes
| Status | Message | Reason |
|---|---|---|
| 400 | Invalid amount or less than 1 rupee | transaction_amount below ₹1.00. |
| 400 | Already exists | Duplicate merchant_transaction_id. |
| 401 | Invalid authentication hash. | Computed hash does not match. |
| 400 | No Routing Rule found for this amount. | No active rule covers the amount. |
Validation Rules
merchant_transaction_id— required, unique per merchant, ≤ 255 chars.transaction_amount— required decimal in rupees, ≥ 1.00, two decimals.customer_details— required object; at least one of email / phone.payment_method— optional; one of the allowed method codes.
Notes
- The hash is computed over your
merchant_transaction_idandtransaction_amount— not the returnedtransaction_id. - Send
transaction_amountexactly as you hashed it (e.g."1499.00"): a different string like"1499.0"produces a different hash. - On a gateway-init failure the API may return
200/201withsuccess: falseand nopayment_link— always branch on thesuccessflag.
Best Practices
- Generate an idempotent
merchant_transaction_idper order and store it before calling the API. - Redirect the customer to
payment_link; confirm the final outcome server-side via Transaction Status or the webhook — never trust the browser redirect alone. - Keep your
saltserver-side only; never expose it to the browser or mobile app.
Request · POST
# 1. Compute the auth hash: sha256(key|merchant_transaction_id|transaction_amount|salt)
API_KEY="YOUR_API_KEY"
API_SALT="YOUR_API_SALT"
HASH=$(printf '%s' "$API_KEY|ORDER-2026-0001|1499.00|$API_SALT" | openssl dgst -sha256 | awk '{print $2}')
# 2. Call the API
curl -X POST "https://api.growthbnk.com/v1/route/initiate_payment" \
-H "Content-Type: application/json" \
-H "X-API-Key: $API_KEY" \
-H "Hash: $HASH" \
-d '{
"merchant_transaction_id": "ORDER-2026-0001",
"transaction_amount": "1499.00",
"currency": "INR",
"payment_method": "UPI",
"surl": "https://merchant.example.com/payment/success",
"furl": "https://merchant.example.com/payment/failure",
"customer_details": {
"customer_name": "Jane Doe",
"customer_email": "jane.doe@example.com",
"customer_phone": "9876543210"
}
}'import hashlib
import requests
API_KEY = "YOUR_API_KEY"
API_SALT = "YOUR_API_SALT"
BASE_URL = "https://api.growthbnk.com"
payload = {
'merchant_transaction_id': 'ORDER-2026-0001',
'transaction_amount': '1499.00',
'currency': 'INR',
'payment_method': 'UPI',
'surl': 'https://merchant.example.com/payment/success',
'furl': 'https://merchant.example.com/payment/failure',
'customer_details': {
'customer_name': 'Jane Doe',
'customer_email': 'jane.doe@example.com',
'customer_phone': '9876543210'
}
}
# Auth hash: sha256(key|merchant_transaction_id|transaction_amount|salt)
signing = f"{API_KEY}|ORDER-2026-0001|1499.00|{API_SALT}"
auth_hash = hashlib.sha256(signing.encode("utf-8")).hexdigest()
response = requests.post(
f"{BASE_URL}/v1/route/initiate_payment",
json=payload,
headers={
"Content-Type": "application/json",
"X-API-Key": API_KEY,
"Hash": auth_hash,
},
timeout=30,
)
response.raise_for_status()
print(response.json())<?php
$apiKey = 'YOUR_API_KEY';
$apiSalt = 'YOUR_API_SALT';
$baseUrl = 'https://api.growthbnk.com';
$payload = [
'merchant_transaction_id' => 'ORDER-2026-0001',
'transaction_amount' => '1499.00',
'currency' => 'INR',
'payment_method' => 'UPI',
'surl' => 'https://merchant.example.com/payment/success',
'furl' => 'https://merchant.example.com/payment/failure',
'customer_details' => [
'customer_name' => 'Jane Doe',
'customer_email' => 'jane.doe@example.com',
'customer_phone' => '9876543210'
]
];
// Auth hash: sha256(key|merchant_transaction_id|transaction_amount|salt)
$signing = "{$apiKey}|ORDER-2026-0001|1499.00|{$apiSalt}";
$authHash = hash('sha256', $signing);
$ch = curl_init("{$baseUrl}/v1/route/initiate_payment");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"X-API-Key: {$apiKey}",
"Hash: {$authHash}",
],
CURLOPT_POSTFIELDS => json_encode($payload),
]);
$response = curl_exec($ch);
curl_close($ch);
echo $response;const crypto = require('crypto');
const API_KEY = 'YOUR_API_KEY';
const API_SALT = 'YOUR_API_SALT';
const BASE_URL = 'https://api.growthbnk.com';
const payload = {
'merchant_transaction_id': 'ORDER-2026-0001',
'transaction_amount': '1499.00',
'currency': 'INR',
'payment_method': 'UPI',
'surl': 'https://merchant.example.com/payment/success',
'furl': 'https://merchant.example.com/payment/failure',
'customer_details': {
'customer_name': 'Jane Doe',
'customer_email': 'jane.doe@example.com',
'customer_phone': '9876543210'
}
};
// Auth hash: sha256(key|merchant_transaction_id|transaction_amount|salt)
const signing = `${API_KEY}|ORDER-2026-0001|1499.00|${API_SALT}`;
const authHash = crypto.createHash('sha256').update(signing).digest('hex');
const response = await fetch(`${BASE_URL}/v1/route/initiate_payment`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY,
'Hash': authHash,
},
body: JSON.stringify(payload),
});
console.log(await response.json());import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
public class GrowthBnkExample {
public static void main(String[] args) throws Exception {
String apiKey = "YOUR_API_KEY";
String apiSalt = "YOUR_API_SALT";
String baseUrl = "https://api.growthbnk.com";
String payload = """
{
"merchant_transaction_id": "ORDER-2026-0001",
"transaction_amount": "1499.00",
"currency": "INR",
"payment_method": "UPI",
"surl": "https://merchant.example.com/payment/success",
"furl": "https://merchant.example.com/payment/failure",
"customer_details": {
"customer_name": "Jane Doe",
"customer_email": "jane.doe@example.com",
"customer_phone": "9876543210"
}
}
""";
// Auth hash: sha256(key|merchant_transaction_id|transaction_amount|salt)
String signing = apiKey + "|ORDER-2026-0001|1499.00|" + apiSalt;
String authHash = sha256Hex(signing);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/v1/route/initiate_payment"))
.header("Content-Type", "application/json")
.header("X-API-Key", apiKey)
.header("Hash", authHash)
.method("POST", HttpRequest.BodyPublishers.ofString(payload))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
private static String sha256Hex(String input) throws Exception {
byte[] digest = MessageDigest.getInstance("SHA-256")
.digest(input.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : digest) sb.append(String.format("%02x", b));
return sb.toString();
}
}using System;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
class GrowthBnkExample
{
static async Task Main()
{
var apiKey = "YOUR_API_KEY";
var apiSalt = "YOUR_API_SALT";
var baseUrl = "https://api.growthbnk.com";
var payload = """
{
"merchant_transaction_id": "ORDER-2026-0001",
"transaction_amount": "1499.00",
"currency": "INR",
"payment_method": "UPI",
"surl": "https://merchant.example.com/payment/success",
"furl": "https://merchant.example.com/payment/failure",
"customer_details": {
"customer_name": "Jane Doe",
"customer_email": "jane.doe@example.com",
"customer_phone": "9876543210"
}
}
""";
// Auth hash: sha256(key|merchant_transaction_id|transaction_amount|salt)
var signing = $"{apiKey}|ORDER-2026-0001|1499.00|{apiSalt}";
var authHash = Convert.ToHexString(
SHA256.HashData(Encoding.UTF8.GetBytes(signing))).ToLowerInvariant();
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
client.DefaultRequestHeaders.Add("Hash", authHash);
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await client.PostAsync($"{baseUrl}/v1/route/initiate_payment", content);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}package main
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"fmt"
"io"
"net/http"
)
func main() {
apiKey := "YOUR_API_KEY"
apiSalt := "YOUR_API_SALT"
baseURL := "https://api.growthbnk.com"
payload := []byte(`{
"merchant_transaction_id": "ORDER-2026-0001",
"transaction_amount": "1499.00",
"currency": "INR",
"payment_method": "UPI",
"surl": "https://merchant.example.com/payment/success",
"furl": "https://merchant.example.com/payment/failure",
"customer_details": {
"customer_name": "Jane Doe",
"customer_email": "jane.doe@example.com",
"customer_phone": "9876543210"
}
}`)
// Auth hash: sha256(key|merchant_transaction_id|transaction_amount|salt)
signing := apiKey + "|ORDER-2026-0001|1499.00|" + apiSalt
sum := sha256.Sum256([]byte(signing))
authHash := hex.EncodeToString(sum[:])
req, _ := http.NewRequest("POST", baseURL+"/v1/route/initiate_payment", bytes.NewReader(payload))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-API-Key", apiKey)
req.Header.Set("Hash", authHash)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}require 'digest'
require 'json'
require 'net/http'
require 'uri'
api_key = 'YOUR_API_KEY'
api_salt = 'YOUR_API_SALT'
base_url = 'https://api.growthbnk.com'
payload = {
'merchant_transaction_id' => 'ORDER-2026-0001',
'transaction_amount' => '1499.00',
'currency' => 'INR',
'payment_method' => 'UPI',
'surl' => 'https://merchant.example.com/payment/success',
'furl' => 'https://merchant.example.com/payment/failure',
'customer_details' => {
'customer_name' => 'Jane Doe',
'customer_email' => 'jane.doe@example.com',
'customer_phone' => '9876543210'
}
}
# Auth hash: sha256(key|merchant_transaction_id|transaction_amount|salt)
signing = "#{api_key}|ORDER-2026-0001|1499.00|#{api_salt}"
auth_hash = Digest::SHA256.hexdigest(signing)
uri = URI("#{base_url}/v1/route/initiate_payment")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri, {
'Content-Type' => 'application/json',
'X-API-Key' => api_key,
'Hash' => auth_hash
})
request.body = payload.to_json
response = http.request(request)
puts response.bodyRequest body
{
"merchant_transaction_id": "ORDER-2026-0001",
"transaction_amount": "1499.00",
"currency": "INR",
"payment_method": "UPI",
"surl": "https://merchant.example.com/payment/success",
"furl": "https://merchant.example.com/payment/failure",
"customer_details": {
"customer_name": "Jane Doe",
"customer_email": "jane.doe@example.com",
"customer_phone": "9876543210"
}
}Response
201 Created
{
"success": true,
"payment_link": "https://api.growthbnk.com/v1/route/pay/8f14e45fceea167a5a36dedd4bea2543",
"transaction_id": "TXN20260707172038123",
"merchant_transaction_id": "ORDER-2026-0001",
"message": "Payment Initiated Successfully"
}