Process Full or Partial Refunds via API
Use Case
An online marketplace, digital service, or e-commerce store wants to refund customers (fully or partially) for cancelled or disputed orders using TransactPay.
Prerequisites
- Completed payment made through TransactPay
- Access to the original
order_id
ortransaction_reference
- Your TransactPay secret key
- Refund reason (optional but recommended)
Step-by-Step Implementation
Step 1: Prepare Refund Payload
A typical refund requires:
order_id
ortransaction_reference
amount
(for partial refund, less than original)reason
(optional but useful for logging)
Node.js Example – Refund Request
const axios = require("axios");
const NodeRSA = require("node-rsa");
const fs = require("fs");
require("dotenv").config();
const pubKey = fs.readFileSync("./transactpay_pub.pem", "utf8");
const rsa = new NodeRSA(pubKey);
rsa.setOptions({ encryptionScheme: "pkcs1" });
const refundPayload = {
order_id: "TP-ORDER-001",
amount: 5000, // NGN 5,000 refunded (partial refund)
reason: "Customer cancelled the service"
};
const encrypted = rsa.encrypt(JSON.stringify(refundPayload), "base64");
axios
.post("https://api.transactpay.io/payment/refund", {
data: encrypted,
}, {
headers: {
Authorization: `Bearer ${process.env.TRANSACTPAY_SECRET_KEY}`,
},
})
.then((res) => {
console.log("Refund processed:", res.data);
})
.catch((err) => {
console.error("Refund error:", err.response?.data || err.message);
});
import json, requests, os
from dotenv import load_dotenv
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding
load_dotenv()
key = os.getenv("TRANSACTPAY_SECRET_KEY")
with open("transactpay_pub.pem", "rb") as key_file:
pub_key = serialization.load_pem_public_key(key_file.read())
payload = {
"order_id": "TP-ORDER-001",
"amount": 5000,
"reason": "Customer cancelled the service"
}
encrypted = pub_key.encrypt(json.dumps(payload).encode(), padding.PKCS1v15())
res = requests.post(
"https://api.transactpay.io/payment/refund",
headers={"Authorization": f"Bearer {key}"},
json={"data": encrypted.hex()}
)
print("Refund response:", res.json())
Sample Response
{
"status": true,
"message": "Refund initiated successfully",
"data": {
"refund_id": "RF-000123",
"status": "pending"
}
}
Refunds may take a few hours to reflect in the customer’s account depending on the payment method.
Optional: Handle Refund Webhook
Listen for webhook events like refund.success
to confirm when the refund is completed.
Example event structure:
{
"event": "refund.success",
"data": {
"order_id": "TP-ORDER-001",
"refund_id": "RF-000123",
"amount": 5000
}
}
Tips
- Always log the refund reason and internal user ID
- For full refunds, set the amount equal to original charge
- Handle 400-level errors (e.g., "already refunded", "invalid order") gracefully
Updated 1 day ago