Installation
This document covers how to get started with saga pay
All API request must come through POST call. The base POST URL
is:
https://app.sagapay.net/api/v2
API Rate limit: 5 Calls Per Second. It is scalable and will
Increase automatically if your application demands more.
https://app.sagapay.net/api/v2
Deposit
This document covers how to receive payment from customers using
a deposit address
POST /deposit
To deposit token (eg: USDT, BUSD) you wallet must have sufficient Gas fee to cover incoming transactions.
Else your deposit may fail. For BEP-20: it is 0.005 BNB, for TRC-20: it is 40 TRX and for ERC-20, it is
0.017 ETH. However for native crypto transfer (eg: BNB, TRX, ETH) no gas fee required. Gas fee will be
deducted from the incoming balance itself.
Description
Generate a new deposit address of the given token ID.
Request
Headers:
Content-Type: application/json
Parameters
- api_key (required): Your API key with 'CREATE_WITHDRAWAL' permission.
- amount (required): The amount to be withdrawn in crypto.
- ipn_url (required): The IPN URL to be notified when the withdrawal is
processed.
- token_id (required): The token ID of the cryptocurrency to be withdrawn.
- udf (optional): Any user-defined field for additional information.
Body:
{
"api_key": "your_api_key",
"amount": 100.0, // in crypto
"ipn_url": "https://example.com/ipn",
"token_id": "USDT.BEP20",
"udf": "optional_user_defined_field" // will be sent back with IPN notification
}
Get the Token
IDs
here
→
Response
Success:
{
"status": true,
"message": "receiving_address",
"timeout": 86400, // in seconds
"qrcodeurl": "https://qrcodeurl.com?address=receiving_address"
}
Error:
{
"status": false,
"message": "Error message"
}
Create Withdrawal
Use this API to create a new withdrawal request. The request will be processed, and the specified
amount will be withdrawn from the user's account.
POST /withdraw
For withdrawals, your Main wallet (native wallet, for BEP-20 token, its BNB) must have sufficient fund to
cover gas fee for outgoing transactions. Else withdrawals will be halted.
Headers:
Content-Type: application/json
Parameters
- api_key (required): Your API key with 'CREATE_DEPOSIT' permission.
- api_secret (required): Your API secret (This should never be exposed to the
client side.).
- amount (required): The amount to be withdrawn in crypto.
- ipn_url (required): The IPN URL to be notified when the withdrawal is
processed.
- token_id (required): The token ID of the cryptocurrency to be withdrawn.
- withdrawal_address (required): The withdrawal address to send the funds.
- udf (optional): Any user-defined field for additional information.
{
"api_key": "your_api_key_with_CREATE_WITHDRAWAL_permission",
"api_secret": "your_api_secret",
"amount": 100,
"ipn_url": "https://yourdomain.com/ipn",
"token_id": "your_token_id",
"withdrawal_address": "your_withdrawal_address",
"udf": "your_optional_additional_information"
}
Get the Token
IDs
here
→
Response
If the withdrawal request is successfully created, the API will return a JSON object with a "status"
field set to "true" and a "message" field containing the withdrawal ID. If there is an error, the
"status" field will be "false" and the "message" field will contain an error description.
{
"status": true,
"message": "withdrawal_id"
}
Check Balance
Check Balance in your Activated wallet. Balance will be fetched from Blockchain Directly.
POST /check-balance
Request
Headers:
Content-Type: application/json
Parameters
- api_key (required): Your API key with 'READ_WALLET_BALANCE' permission.
- token_id (required): The token ID of the cryptocurrency to be withdrawn.
Body:
{
"api_key": "your_api_key",
"token_id": "USDT.BEP20",
}
Get the Token
IDs
here
→
Response
Success:
{
"status": true,
"message":1,
"token": "BNB",
}
IPN Notification
This documentation describes how IPN notifications are sent to your specified IPN URL.
IPN Payload
When a deposit or withdrawal event occurs, an IPN notification will be sent as an HTTP POST request to
the provided IPN URL. The payload will be in JSON format, with the following fields:
Field |
Type |
Description |
txn_hash |
string |
The transaction hash for the deposit or withdrawal. |
ipn_type |
string |
The type of event, either "deposit" or "withdrawal". |
udf |
string |
Any user-defined field for additional information. |
amount |
number |
The amount of cryptocurrency involved in the transaction. |
network |
string |
The network on which the transaction occurred (e.g., BSC, ETH, TRX). |
datetime |
string |
The date and time the event occurred. |
ipnUrl |
string |
The IPN URL where the notification is being sent. |
deposit_address |
string |
The deposit address (only included if ipn_type is "deposit"). |
withdrawal_address |
string |
The withdrawal address (only included if ipn_type is "withdrawal"). |
Example IPN Payload
Here is an example of an IPN payload for a deposit:
{
"txn_hash": "0x12345...",
"ipn_type": "deposit",
"udf": "extra-info",
"amount": 1.234,
"network": "ETH",
"datetime": "2023-05-10T12:34:56.789Z",
"ipnUrl": "https://example.com/ipn-handler",
"deposit_address": "0x6789..."
}
And an example of an IPN payload for a withdrawal:
{
"txn_hash": "0x12345...",
"ipn_type": "withdrawal",
"udf": "extra-info",
"amount": 1.234,
"network": "ETH",
"datetime": "2023-05-10T12:34:56.789Z",
"ipnUrl": "https://example.com/ipn-handler",
"withdrawal_address": "0x6789..."
}
IPN Notification Handling
Upon receiving the IPN notification at the specified IPN URL, your server should handle the incoming
request and process the payload accordingly. The payload will be in POST data format, so
you can parse the post data and extract the relevant information. Also before accepting the IPN
notification, you should check if IPN data is genuine or not using below API:
Validating IPN notifications
To validate the received IPN notifications, perform the following steps:
- Extract the signature from the
X-Sagapay-IPN
header.
- Recompute the signature using the shared secret key and the received payload.
- Compare the recomputed signature with the signature extracted from the header. If they match, the
IPN notification is considered genuine.
IPN Validation Demo
Node.js
const crypto = require('crypto');
const express = require('express');
const app = express();
const secretKey = 'api secret key';
app.use(express.json());
app.post('/ipn', (req, res) => {
const receivedSignature = req.header('X-Sagapay-IPN');
const payload = JSON.stringify(req.body);
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(payload);
const computedSignature = hmac.digest('hex');
if (receivedSignature === computedSignature) {
console.log('Valid IPN:', req.body);
res.status(200).send('OK');
} else {
console.log('Invalid IPN signature');
res.status(401).send('Unauthorized');
}
});
app.listen(3000, () => {
console.log('Listening on port 3000');
});
PHP
<?php
$secretKey = 'api secret key';
$headers = getallheaders();
$receivedSignature = $headers['X-Sagapay-IPN'];
$payload = file_get_contents('php://input');
$computedSignature = hash_hmac('sha256', $payload, $secretKey);
if ($receivedSignature === $computedSignature) {
echo 'Valid IPN';
http_response_code(200);
} else {
echo 'Invalid IPN signature';
http_response_code(401);
}
?>
Go
// go get -u golang.org/x/crypto
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
http.HandleFunc("/ipn", ipnHandler)
http.ListenAndServe(":8080", nil)
}
func ipnHandler(w http.ResponseWriter, r *http.Request) {
// Read request body
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Error reading request body", http.StatusInternalServerError)
return
}
// Replace with the secret key provided by the payment gateway
secretKey := "api secret key"
// Get the signature from the header
sentSignature := r.Header.Get("X-Sagapay-IPN")
// Calculate the expected signature
expectedSignature := calculateHMAC(secretKey, string(body))
// Compare the sent signature with the expected signature
if sentSignature == expectedSignature {
fmt.Println("IPN signature is valid")
} else {
fmt.Println("IPN signature is invalid")
}
}
func calculateHMAC(secretKey, data string) string {
h := hmac.New(sha256.New, []byte(secretKey))
h.Write([]byte(data))
return hex.EncodeToString(h.Sum(nil))
}
NPM Plugin
This plugin is for Node JS based application only
PHP Plugin
This plugin works with all PHP frameworks
Golang Module
Works with Go lang versions