v1.0

Cleffo Payment Gateway

Complete API Integration Guide for Merchants. All communication is via JSON over HTTPS.

Development
https://apis-dev.cleffo.com
Production
https://apis.cleffo.com
API credentials: The API key and signature key differ between development and production. Production credentials will be provided after your integration is completed and approved in the development environment.

Authentication

All API requests require an API key. The signature header is only required when calling Create Payment Link. Cleffo provides your API key and signature key during onboarding.

Header Type Required Notes
x-api-key String YES The API key provided by Cleffo for authentication.
x-signature String YES An HMAC-SHA256 signature of the raw request body, generated using your signature key. Required for Create Payment Link only.
Signature generation: Compute hash_hmac('sha256', $rawBody, $signatureKey) where $rawBody is the exact JSON string sent in the request body.

APIs

Request Headers

Field Data Type Required Notes
x-api-key String YES The API key provided by Cleffo. Include it in the request header for authentication.
x-signature String YES A signature created by the client for verification.
Content-Type String YES Must be set to application/json.

Request Body Fields

Field Data Type Required Notes
merchant_order_id String YES A unique alphanumeric order tracking ID provided by the merchant.
customer_detail.name String YES The customer's full name.
customer_detail.email String YES Must not contain spaces.
customer_detail.phone_no String (Numeric) YES Must be 8–15 digits with no spaces.
products Array<Object> YES An array of product objects.
products[].name String YES The product name.
products[].product_id String YES A unique identifier for the product.
products[].quantity Number YES The total number of units for the product.
products[].price Number/Float YES The price per unit. Integers and decimals are accepted.
products[].image String (URL) YES A publicly accessible image URL.
price Object YES An object containing pricing details.
price.sub_total Number/Float YES The sum of (quantity × price) for all products. Integers and decimals are accepted.
price.tax Number/Float YES A decimal or integer value. Must be greater than or equal to 0.
price.total Number/Float YES The sum of sub_total and tax. Integers and decimals are accepted.
price.currency String YES An ISO 4217 currency code, e.g. USD.
metadata.source String YES Must be set to "api".
metadata.cleffo_client_key String YES The client key provided by Cleffo to identify your merchant account.
metadata.redirect_url String (URL) YES The URL to redirect the customer to after payment is completed.

Responses

200 OK Payment link created

{
    "status": true,
    "message": "Payment link created successfully.",
    "errors": null,
    "error_code": null,
    "data": {
        "payment_link": "https://app.cleffo.com/pay/api-checkout-session/yp60ty07qc",
        "transaction_reference_number": "yp60ty07qc",
        "merchant_order_id": "test123",
        "payment_source": "api"
    },
    "meta_params": null,
    "lang": "en"

}

400 Bad Request Validation error

{
    "status": false,
    "message": "Validation error",
    "errors": {
            "data.price.sub_total": "The sub_total must equal the sum of all products. Expected: 600",
            "metadata.cleffo_client_key": "The cleffo_client_key field is required in metadata.",
            "data.price.total": "The total must equal sub_total + tax. Expected: 601.2",
            "data.price.currency": "The provided currency (INR) does not match the business currency (USD)."
    },
    "error_code": null,
    "data": [],
    "meta_params": null,
    "lang": "en"
}

400 Bad Request Validation error(Invalid Json)

{
  "status": false,
  "message": "Validation error",
  "errors": {
      "request_body": "The request body contains invalid JSON syntax."
  },
  "error_code": null,
  "data": [],
  "meta_params": null,
  "lang": "en"
}

401 Unauthorized Invalid API key

{
  "status": false,
  "message": "Authorization error",
  "errors": {
      "authorization": "Invalid API key."
  },
  "error_code": null,
  "data": [],
  "meta_params": null,
  "lang": "en"
}

401 Unauthorized Invalid Signature

{
    "status": false,
    "message": "Authorization error",
    "errors": {
            "authorization": "invalid signature"
    },
    "error_code": null,
    "data": null,
    "meta_params": null,
    "lang": "en"
}

500 Internal Server Error Server error

{
  "status": false,
  "message": "An unexpected error occurred. Please try again later.",
  "errors": {
      "server": "Internal server error."
  },
  "error_code": null,
  "data": [],
  "meta_params": null,
  "lang": "en"
}

Example Codes

const crypto = require("crypto");
const axios = require("axios");

const apiKey = "YOUR_API_KEY";
const signatureKey = "YOUR_SIGNATURE_KEY";

const requestBody = {
    data: {
        merchant_order_id: "test123",
        customer_detail: {
            name: "test",
            email: "test@gmail.com",
            phone_no: "67823234234"
        },
        products: [
            {
                name: "product",
                product_id: "p3932",
                image: "ima_212.png",
                price: 200.00,
                quantity: 2
            }
        ],
        price: {
            sub_total: 400.00,
            tax: 1.5,
            total: 401.5,
            currency: "USD"
        }
    },
    metadata: {
        source: "api",
        cleffo_client_key: "sunnysides",
        redirect_url: "https://xyz.com/return/page"
    }
};

// Signature calculation (HMAC-SHA256):
// apiKey       = "ck_test_example_api_key_abc123"
// signatureKey = "my_signature_key_dev_12345"
// rawBody      = JSON.stringify(requestBody)   // must be the exact string sent as the POST body
//
// Example rawBody:
// {"data":{"merchant_order_id":"test123","customer_detail":{"name":"test","email":"test@gmail.com","phone_no":"67823234234"},"products":[{"name":"product","product_id":"p3932","image":"ima_212.png","price":200,"quantity":2}],"price":{"sub_total":400,"tax":1.5,"total":401.5,"currency":"USD"}},"metadata":{"source":"api","cleffo_client_key":"sunnysides","redirect_url":"https://xyz.com/return/page"}}
//
// signature = crypto.createHmac("sha256", signatureKey).update(rawBody).digest("hex")
//           = "b9d299025597b3bfd3a2834b4d3c756c0ea89e113c76fb8939d126fdac41ed3a"

const rawBody = JSON.stringify(requestBody);
const signature = crypto
    .createHmac("sha256", signatureKey)
    .update(rawBody)
    .digest("hex");

axios.post("https://apis.cleffo.com/api/payment-link", requestBody, {
    headers: {
        "Content-Type": "application/json",
        "x-api-key": apiKey,
        "x-signature": signature
    }
})
.then(response => { console.log(response.data); })
.catch(error => { console.error(error.response?.data || error.message); });
<?php
$apiKey = 'YOUR_API_KEY';
$signatureKey = 'YOUR_SIGNATURE_KEY';

$requestBody = [
    "data" => [
        "merchant_order_id" => "test123",
        "customer_detail" => [
            "name" => "test",
            "email" => "test@gmail.com",
            "phone_no" => "67823234234"
        ],
        "products" => [
            [
                "name" => "product",
                "product_id" => "p3932",
                "image" => "ima_212.png",
                "price" => 200.00,
                "quantity" => 2
            ]
        ],
        "price" => [
            "sub_total" => 400.00,
            "tax" => 1.5,
            "total" => 401.5,
            "currency" => "USD"
        ]
    ],
    "metadata" => [
        "source" => "api",
        "cleffo_client_key" => "sunnysides",
        "redirect_url" => "https://xyz.com/return/page"
    ]
];

// Signature calculation (HMAC-SHA256):
// $apiKey       = 'ck_test_example_api_key_abc123';
// $signatureKey = 'my_signature_key_dev_12345';
// $rawBody        = json_encode($requestBody);  // must be the exact string sent as the POST body
//
// Example $rawBody (PHP escapes slashes in URLs):
// {"data":{"merchant_order_id":"test123",...,"redirect_url":"https:\/\/xyz.com\/return\/page"}}
//
// $signature = hash_hmac('sha256', $rawBody, $signatureKey);
//           = '0498e01acd186e302c746d201bd323ebf6dae8c6d52431d7648ea081b8c56050';

$rawBody = json_encode($requestBody);
$signature = hash_hmac('sha256', $rawBody, $signatureKey);

$ch = curl_init('https://apis.cleffo.com/api/payment-link');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $rawBody,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'x-api-key: ' . $apiKey,
        'x-signature: ' . $signature,
    ],
]);
$response = curl_exec($ch);
curl_close($ch);

echo $response;

Get Payment Link Status

Poll the payment status using the transaction reference number returned from Create Payment Link API.

GET /api/payment-link/status/{transaction_reference_number}

Request Headers

Header Data Type Required Notes
x-api-key String YES The API key provided by Cleffo. Include it in the request header for authentication.
Note: The x-signature header is not required for this endpoint. Only x-api-key is needed.

Request Body

Parameter Data Type Required Notes
transaction_reference_number String YES The transaction reference number returned from Create Payment Link (e.g. yp60ty07qc). Passed as a path parameter in the URL.

Responses

200 OK Payment status retrieved

{
"status": true,
"message": "Payment status retrieved successfully.",
"errors": null,
"error_code": null,
"data": {
    "payment_status": "completed",
    "total_amount": "505.50",
    "currency": "usd",
    "merchant_order_id": "test123",
    "transaction_reference_number": "4pp4zf2m3k",
    "payment_gateway": "stripe",
    "payment_gateway_intent_id": "pi_3TezF4Et1y0SmqPj01N7sePE",
    "date_time": "2026-06-05 20:31:02"
},
"meta_params": null,
"lang": "en"
}

404 Not Found Required transaction reference

{
  "status": false,
  "message": "Validation error",
  "errors": {
      "transaction_reference_number": "Transaction reference number is required."
  },
  "error_code": null,
  "data": [],
  "meta_params": null,
  "lang": "en"
}

401 Unauthorized Invalid API key

{
  "status": false,
  "message": "Authorization error",
  "errors": {
      "Authorization": "Invalid API key"
  },
  "error_code": null,
  "data": [],
  "meta_params": null,
  "lang": "en"
}

500 Internal Server Error Server error

{
  "status": false,
  "message": "An unexpected error occurred. Please try again later.",
  "errors": {
      "server": "Internal server error."
  },
  "error_code": null,
  "data": [],
  "meta_params": null,
  "lang": "en"
}

Payment Status Values

The payment_status field in the response can have the following values:

Status Description
completed The payment was completed successfully.
pending The payment is in progress or has not been completed yet.
failed The payment failed or was aborted.

Example Codes

const axios = require("axios");

const apiKey = "YOUR_API_KEY";
const transactionRef = "4thzvlb5hc";

const url = `https://apis.cleffo.com/api/payment-link/${transactionRef}/status`;

axios.get(url, {
    headers: {
        "x-api-key": apiKey
    }
})
.then(response => { console.log(response.data); })
.catch(error => { console.error(error.response?.data || error.message); });
<?php
$apiKey = 'YOUR_API_KEY';
$transactionRef = '4thzvlb5hc';

$url = 'https://apis.cleffo.com/api/payment-link/' . $transactionRef . '/status';

$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'x-api-key: ' . $apiKey,
    ],
]);
$response = curl_exec($ch);
curl_close($ch);

echo $response;