Transaction Refund / Cancel
The refund process of a payment is carried out in the form of cancellation for certain situations and as a refund for others.
Cancel: If the payment has not been completed by the end of the day and there has been no previous partial refund for this payment, this process is referred to as Cancellation.
Refund: If a partial refund has been made for the payment to be refunded, or if a refund request is received on a day different from the day the payment was made, this process is referred to as Refund.
HTTP method, Endpoint, Headers, and Request information are provided below.
Method |
API Endpoint |
Content-Type |
POST |
/api/refund |
application/json |
Parameter |
Requirement |
Content-Type |
Authorization |
Mandatory |
Bearer |
Accept |
Mandatory |
application/json |
Parameter |
Data Type |
Requirement |
Description |
invoice_id |
string |
Mandatory |
Unique invoice number indicating the completed payment. |
amount |
double / empty string |
Mandatory |
Amount to be refunded. If the amount is conveyed as an empty string (""), the total transaction amount is refunded. Here, the remaining amount = total transaction amount - total amount of partial refunds |
app_id |
string |
Mandatory |
Unique Application Key obtained through PayBull |
app_secret |
string |
Mandatory |
Unique Application Password obtained through PayBull |
merchant_key |
string |
Mandatory |
Unique Merchant Key obtained through PayBull |
hash_key |
string |
Mandatory |
See Creating Hash Key |
refund_webhook_key |
string |
Optional |
Used to receive notifications about the success or failure status of the refund. Must assign the Refund webhook URL in the Paybull Merchant Panel. |
CREATE HASH KEY
function generateRefundHashKey($amount, $invoice_id, $merchant_key, $app_secret) {
$data = $amount.'|'.$invoice_id.'|'.$merchant_key;
$iv = substr(sha1(mt_rand()), 0, 16);
$password = sha1($app_secret);
$salt = substr(sha1(mt_rand()), 0, 4);
$saltWithPassword = hash('sha256', $password . $salt);
$encrypted = openssl_encrypt(
"$data", 'aes-256-cbc', "$saltWithPassword", null, $iv
);
$msg_encrypted_bundle = "$iv:$salt:$encrypted";
$hash_key = str_replace('/', '__', $msg_encrypted_bundle);
return $hash_key;
}
public static string GenerateHashKey(string invoice_id, string merchant_key, string app_secret){
var data = invoice_id+'|'+merchant_key;
var sha1 = new SHA1Managed();
Random rnd = new Random();
var iv = sha1.ComputeHash(Encoding.UTF8.GetBytes(rnd.ToString()));
var password = sha1.ComputeHash(Encoding.UTF8.GetBytes(app_secret)).ToString();
rnd = new Random();
var shaSalt = sha1.ComputeHash(Encoding.UTF8.GetBytes(rnd.ToString())).ToString();
var salt = shaSalt.Substring(0, 4);
var sha256 = new SHA256Managed();
var saltWithPassword = sha256.ComputeHash(Encoding.UTF8.GetBytes(password+salt));
var encrypted = EncryptString(data,saltWithPassword,iv);
var msg_encrypted_bundle = iv + ":" + salt + ":" + encrypted;
msg_encrypted_bundle = msg_encrypted_bundle.Replace("/","__");
return msg_encrypted_bundle;
}
public static string EncryptString(string plainText, byte[] key, byte[] iv){
Aes encryptor = Aes.Create();
encryptor.Mode = CipherMode.CBC;
encryptor.Key = key;
encryptor.IV = iv;
MemoryStream memoryStream = new MemoryStream();
ICryptoTransform aesEncryptor = encryptor.CreateEncryptor();
CryptoStream cryptoStream = new CryptoStream(memoryStream, aesEncryptor, CryptoStreamMode.Write);
byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
string cipherText = Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);
return cipherText;
}
function generateRefundHashKey(invoice_id , merchant_key , app_secret) {
data = invoice_id + "|" + merchant_key;
var randNumIv = Math.floor(Math.random() * (99999999999999999 - 10000000000000000) + 10000000000000000);
var hashNumIv = sha1(randNumIv);
hashNumIv = hashNumIv.create();
var iv = hashNumIv.slice(0,16);
var hashPass = sha1(app_secret);
hashPass = hashPass.create();
var password = hashPass.hex();
var randNumSalt = Math.floor(Math.random() * (99999999999999999 - 10000000000000000) + 10000000000000000);
var hashNumSalt = sha1(randNumIv);
hashNumSalt = hashNumSalt.create();
var salt = hashNumSalt.hex();
var strPassSalt = password + salt;
var hashStr = sha1(strPassSalt);
hashStr.create();
var saltWithPassword = strPassSalt.hex();
var encrypted = "";
var msg_encrypted_bundle = iv + ":" + salt + ":" + encrypted;
var hashKey = msg_encrypted_bundle.replaceAll("/" , "_");
return hashKey;
}
import random
from Crypto.Hash import SHA1
from Crypto.Hash import SHA256
def generateRefundHashKey(invoice_id , merchant_key , app_secret) :
data = invoice_id + "|" + merchant_key
randNumIv = str(random.randint(10000000000000000,99999999999999999))
hashNumIv = SHA1.new()
hashNumIv.update(randNumIv.encode("UTF-8"))
hashNumber = hashNumIv.hexdigest()
iv = hashNumber[:16]
hashAppSec = SHA1.new()
hashAppSec.update(app_secret.encode("UTF-8"))
password = hashAppSec.hexdigest()
randNumSalt = str(random.randint(10000000000000000,99999999999999999))
hashNumSalt = SHA1.new()
hashNumSalt.update(randNumSalt.encode("UTF-8"))
hashSalt = hashNumSalt.hexdigest()
salt = hashSalt[:4]
strPassSalt = password + salt
hashStr = SHA256.new()
hashStr.update(strPassSalt.encode("UTF-8"))
saltWithPassword = hashStr.hexdigest()
encrypted = ""
msg_encrypted_bundle = iv + ":" + salt + ":" + encrypted
hash_key = msg_encrypted_bundle.replace("/" , "_")
return hash_key
When Status Code 100 and 101 are returned, it indicates that the Refund transaction was done successfully. You can update the Transaction Status as Refunded
. In cases where the refund is not accepted by the bank, refunds are made by the PayBull Operations team.
status_code |
transaction_status |
100 |
Refunded |
101 |
Awaiting Refunded |
EXAMPLE CODES
{
"amount" : "10",
"invoice_id" : "c9fa2586-89f5-4898-a6b6-34554fbe1c89",
"hash_key": "1al1:47tri3g5nM4Snmc_ri3g_R1NylhHZcj0Zu3EuluVWRq9YMaHo2npFjXr7Nfe04po",
"app_id": "c3d81ae3cc3011ef10dcefa31a458d65",
"app_secret": "217071ea9f3f2e9b695d8f0039024e64",
"merchant_key" :"$2y$10$w/ODdbTmfubcbUCUq/ia3OoJFMUmkM1UVNBiIQIuLfUlPmaLUT1he"
}
{
"status_code": 100,
"status_description": "Refund completed successfully",
"order_no": "15925741639038",
"invoice_id": "66955",
"ref_no": "5454545dgdgd545545"
}
{
"status_code": 49,
"status_description": "Refund Failed",
"order_no": "15925741639038",
"invoice_id": "66955",
"ref_no": ""
}