Turbo Transactions API Documentation
This document provides detailed information about integrating with the Turbo Transactions API for processing payments and managing transactions.
Version: 1.0 | Last Updated: August 2025
1. API Security
All APIs in this document share common security measures:
- All API requests must use HTTPS protocol
- All API headers must include "secret-key" and "client-id" parameters
- Keys can be obtained from the Turbo Transactions developer portal
- The base URL will be provided by the Turbo Transactions team
- Request body format is JSON
- Encryption key (secretKey) will be provided by the team
2. Initiate Payment URL API
This API is used to initiate an intent transaction.
Endpoint: POST /turbo-svc/api/v1/transaction/ext/v2/amt/initiate-s2s
Request Parameters
| Key |
Description |
Mandatory |
| amount |
Amount to be sent to the customer (e.g. 300)
amount must be provided as an integer value only; decimal values are not allowed.
|
Yes |
| orderId |
Merchant-provided unique identifier |
Yes |
| returnUrl |
URL to redirect user after payment completion |
Yes |
Sample Request
{
"orderId": "tt00d0u049100",
"amount": 300,
"returnUrl": "https://example.com"
}
Sample Response
{
"statusCode": 200,
"message": "Order Created Successfully",
"status": "OK",
"success": true,
"timestamp": "2025-08-26T07:52:23.243989861Z",
"data": {
"txnId": "5NNGB2SVNBY0NOZ3G809SEM",
"orderId": "tt00d0u049100",
"amount":300.01,
"sdkUrl": "https://payment-sdk.turbotransactions.in/utr/payment?data=OLGQ7qcmzpuQjwUK3PBIZ_gbRhDd4DqjVoOZp..."
}
}
Note : The amount to be considered should be the one received in the response.
3. Check Transaction Status API
This API is used to check the current status of a transaction.
Endpoint: GET /turbo-svc/api/v1/transaction/ext/status-check
Request Parameters
| Key |
Description |
Example |
| order-id |
Order ID of the transaction (should be in the header) |
Test001 |
Sample Response
{
"statusCode": 200,
"message": "Txn details fetched successfully",
"status": "OK",
"success": true,
"timestamp": "2025-03-21T15:35:43.797919902Z",
"data": {
"utr": "",
"orderId": "TestTurboTxn001",
"txnStatus": "Initiated / Approved / Rejected / Pending",
"amount": 300.01
}
}
4. Webhook/Callback Format
Merchants need to provide a webhook URL to receive transaction status updates.
Callback Request Format
{
"encryptedData": "oRQPDxCyTU85s2NLjXd76VOrAjgMpFVG1QAOer846wzvbIsLULbMRk5CJsnLkGuTSpAKDyOk/cNzEtbp8ABfBah+9afSdlvu3vhHisPtgt1aen3cRCdPnIPcgQelKfNZ"
}
Decrypted Response Format
{
"utr": "402393486736",
"amount": 300.01,
"orderId": "Test123456789",
"txnStatus": "Approved / Rejected"
}
Note: Once the transaction status is updated, the merchant will receive the status. We expect a 200 status code with the message "OK" in response.
Important: Use the provided valid key to decrypt the callback you received.
5. Callback Decryption Logic
The callback data is encrypted using AES-256-CBC encryption with a 32-byte key. The first 16 bytes of the encrypted data contain the initialization vector (IV).
Code Examples
Below are code examples for decrypting callback data in various programming languages:
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class DecryptExample {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final int IV_LENGTH = 16;
private static final int KEY_LENGTH = 32;
public static void main(String[] args) {
String encryptedData = "YOUR_ENCRYPTED_DATA_HERE";
String secretKey = "Use the correct key for decryption";
try {
String decrypted = decrypt(encryptedData, secretKey);
System.out.println("Decrypted: " + decrypted);
} catch (Exception e) {
System.err.println("Decryption failed: " + e.getMessage());
}
}
public static String decrypt(String encryptedBase64, String base64Key) throws Exception {
byte[] key = Base64.getDecoder().decode(base64Key);
if (key.length != KEY_LENGTH) {
throw new IllegalArgumentException("Key must be 32 bytes after base64 decoding");
}
byte[] encryptedData = Base64.getDecoder().decode(encryptedBase64);
if (encryptedData.length < IV_LENGTH) {
throw new IllegalArgumentException("Encrypted data too short to contain IV");
}
IvParameterSpec iv = new IvParameterSpec(encryptedData, 0, IV_LENGTH);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
byte[] decrypted = cipher.doFinal(encryptedData, IV_LENGTH, encryptedData.length - IV_LENGTH);
return new String(decrypted, StandardCharsets.UTF_8);
}
}
const decryptAES = async (encryptedBase64, base64Key) => {
// Decode base64 inputs
const encryptedData = new Uint8Array(atob(encryptedBase64).split('').map(c => c.charCodeAt(0)));
const keyBytes = new Uint8Array(atob(base64Key).split('').map(c => c.charCodeAt(0)));
const cryptoKey = await crypto.subtle.importKey('raw', keyBytes, 'AES-CBC', false, ['decrypt']);
const decrypted = await crypto.subtle.decrypt(
{ name: 'AES-CBC', iv: encryptedData.subarray(0, 16) },
cryptoKey,
encryptedData.subarray(16)
);
return new TextDecoder().decode(decrypted);
};
const encryptedData = "YOUR_ENCRYPTED_DATA_HERE";
const secretKey = "Use the correct key for decryption";
decryptAES(encryptedData, secretKey)
.then(console.log)
.catch(console.error);
<?php
function decryptAES(string $encryptedBase64, string $base64Key): string {
$encryptedData = base64_decode($encryptedBase64);
$keyBytes = base64_decode($base64Key);
strlen($keyBytes) === 32 || throw new Exception('Invalid key: must be 32 bytes');
strlen($encryptedData) >= 16 || throw new Exception('Invalid encrypted data: too short');
$decrypted = openssl_decrypt(
substr($encryptedData, 16),
'AES-256-CBC',
$keyBytes,
OPENSSL_RAW_DATA,
substr($encryptedData, 0, 16)
);
return $decrypted !== false ? $decrypted : throw new Exception('Decryption failed: '. openssl_error_string());
}
// Usage
$encryptedData = "YOUR_ENCRYPTED_DATA_HERE";
$secretKey = "Use the correct key for decryption";
try {
echo "Decrypted: ". decryptAES($encryptedData, $secretKey) . "\n";
} catch (Exception $e) {
echo "Error: ". $e->getMessage(). "\n";
}
?>