Sign In

Refund Initiate

Refund all or part of a successful payment.

POST/v1/route/refund-initiate/

Initiates a full or partial refund against a successful payment, referenced by its GrowthBnk transaction_id. Multiple partial refunds are supported until the refundable balance is exhausted.

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|transaction_id|refund_amount|salt), joined with the | character. Your salt is a server-side secret — see the Authentication guide.

Headers

HeaderTypeRequiredDescription
X-API-KeystringRequiredYour merchant API key.
HashstringRequiredSHA-256 auth hash (see Authentication).
Content-TypestringRequiredMust be application/json.

Request Parameters

ParameterTypeRequiredDescription
transaction_idstringRequiredGrowthBnk transaction id of the original payment (not your merchant reference).
Non-empty, ≤ 255 chars.
refund_amountstring / numberRequiredAmount to refund, in rupees.
Decimal > 0, two decimals; ≤ remaining refundable balance.
refund_reasonstringOptionalFree-text reason for the refund.
Optional.

Responses

A successful call returns HTTP 201 Created. Response fields:

FieldTypeDescription
successbooleantrue on success.
refund_idstringGrowthBnk refund id (RFD<YYYYMMDD><epoch_ms>) — use it for status lookups.
transaction_idstringOriginal payment id.
merchant_transaction_idstringYour reference for the original payment.
refund_amountstringRefund amount (two decimals).
refund_statusstringOne of INITIATED, PROCESSING, SUCCESS, FAILURE.

Example responses

Success
201 Created
{
    "success": true,
    "refund_id": "RFD20260707180512345",
    "transaction_id": "TXN20260707172038123",
    "merchant_transaction_id": "ORDER-2026-0001",
    "refund_amount": "150.00",
    "refund_status": "INITIATED"
}
Not refundable
400 Bad Request
{
    "success": false,
    "message": "Refund is allowed only for successful transactions.",
    "data": null
}
Over cap
400 Bad Request
{
    "success": false,
    "message": "Refund amount exceeds refundable balance. Remaining refundable: 50.00",
    "data": null
}
Not found
404 Not Found
{
    "success": false,
    "message": "Transaction not found.",
    "data": null
}

Status Codes

StatusMeaning
201 CreatedRefund created.
400 Bad RequestValidation failed / not a successful txn / exceeds refundable balance.
401 UnauthorizedBad API key or hash mismatch.
404 Not FoundOriginal transaction not found.

Error Codes

StatusMessageReason
400Refund is allowed only for successful transactions.Original payment is not SUCCESS.
400Refund amount exceeds refundable balance. Remaining refundable: {amt}Refund + prior refunds > original amount.
404Transaction not found.transaction_id not found for this merchant.

Validation Rules

  • transaction_id — required, non-empty, ≤ 255 chars.
  • refund_amount — required decimal > 0, two decimals.
  • Original transaction must be SUCCESS and owned by you.
  • Sum of non-failed refunds + this amount must not exceed the original amount.

Notes

  • Reference the payment by its GrowthBnk transaction_id, not merchant_transaction_id.
  • The hash includes the amount: SHA256(key|transaction_id|refund_amount|salt). Send refund_amount exactly as hashed.
  • No refund-specific webhook is emitted — poll Refund Status for completion.

Best Practices

  • Store the returned refund_id and reconcile with Refund Status.
  • For partial refunds, track the remaining refundable balance on your side to avoid over-cap errors.
Request · POST
# 1. Compute the auth hash: sha256(key|transaction_id|refund_amount|salt)
API_KEY="YOUR_API_KEY"
API_SALT="YOUR_API_SALT"
HASH=$(printf '%s' "$API_KEY|TXN20260707172038123|150.00|$API_SALT" | openssl dgst -sha256 | awk '{print $2}')

# 2. Call the API
curl -X POST "https://api.growthbnk.com/v1/route/refund-initiate/" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -H "Hash: $HASH" \
  -d '{
    "transaction_id": "TXN20260707172038123",
    "refund_amount": "150.00",
    "refund_reason": "Customer requested cancellation"
}'
import hashlib
import requests

API_KEY = "YOUR_API_KEY"
API_SALT = "YOUR_API_SALT"
BASE_URL = "https://api.growthbnk.com"

payload = {
    'transaction_id': 'TXN20260707172038123',
    'refund_amount': '150.00',
    'refund_reason': 'Customer requested cancellation'
}

# Auth hash: sha256(key|transaction_id|refund_amount|salt)
signing = f"{API_KEY}|TXN20260707172038123|150.00|{API_SALT}"
auth_hash = hashlib.sha256(signing.encode("utf-8")).hexdigest()

response = requests.post(
    f"{BASE_URL}/v1/route/refund-initiate/",
    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 = [
    'transaction_id' => 'TXN20260707172038123',
    'refund_amount' => '150.00',
    'refund_reason' => 'Customer requested cancellation'
];

// Auth hash: sha256(key|transaction_id|refund_amount|salt)
$signing = "{$apiKey}|TXN20260707172038123|150.00|{$apiSalt}";
$authHash = hash('sha256', $signing);

$ch = curl_init("{$baseUrl}/v1/route/refund-initiate/");
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 = {
    'transaction_id': 'TXN20260707172038123',
    'refund_amount': '150.00',
    'refund_reason': 'Customer requested cancellation'
};

// Auth hash: sha256(key|transaction_id|refund_amount|salt)
const signing = `${API_KEY}|TXN20260707172038123|150.00|${API_SALT}`;
const authHash = crypto.createHash('sha256').update(signing).digest('hex');

const response = await fetch(`${BASE_URL}/v1/route/refund-initiate/`, {
  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 = """
{
    "transaction_id": "TXN20260707172038123",
    "refund_amount": "150.00",
    "refund_reason": "Customer requested cancellation"
}
""";

        // Auth hash: sha256(key|transaction_id|refund_amount|salt)
        String signing = apiKey + "|TXN20260707172038123|150.00|" + apiSalt;
        String authHash = sha256Hex(signing);

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(baseUrl + "/v1/route/refund-initiate/"))
            .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 = """
{
    "transaction_id": "TXN20260707172038123",
    "refund_amount": "150.00",
    "refund_reason": "Customer requested cancellation"
}
""";

        // Auth hash: sha256(key|transaction_id|refund_amount|salt)
        var signing = $"{apiKey}|TXN20260707172038123|150.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/refund-initiate/", 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(`{
    "transaction_id": "TXN20260707172038123",
    "refund_amount": "150.00",
    "refund_reason": "Customer requested cancellation"
}`)

	// Auth hash: sha256(key|transaction_id|refund_amount|salt)
	signing := apiKey + "|TXN20260707172038123|150.00|" + apiSalt
	sum := sha256.Sum256([]byte(signing))
	authHash := hex.EncodeToString(sum[:])

	req, _ := http.NewRequest("POST", baseURL+"/v1/route/refund-initiate/", 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 = {
    'transaction_id' => 'TXN20260707172038123',
    'refund_amount' => '150.00',
    'refund_reason' => 'Customer requested cancellation'
}

# Auth hash: sha256(key|transaction_id|refund_amount|salt)
signing = "#{api_key}|TXN20260707172038123|150.00|#{api_salt}"
auth_hash = Digest::SHA256.hexdigest(signing)

uri = URI("#{base_url}/v1/route/refund-initiate/")
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.body
Request body
{
    "transaction_id": "TXN20260707172038123",
    "refund_amount": "150.00",
    "refund_reason": "Customer requested cancellation"
}
Response
201 Created
{
    "success": true,
    "refund_id": "RFD20260707180512345",
    "transaction_id": "TXN20260707172038123",
    "merchant_transaction_id": "ORDER-2026-0001",
    "refund_amount": "150.00",
    "refund_status": "INITIATED"
}