Configure callback URLs to receive automatic notifications when transaction status changes. This eliminates the need for polling and provides real-time updates.
Contact our support team to configure callback URLs programmatically through API settings.
When a transaction status changes, Swiftrans will send an HTTP POST request to your configured callback URL with the following JSON payload:
{
"transaction_id": "100028355123792503",
"amount": "10000",
"status": "Success",
"reference_id": "REFID153966210",
"admin_fee": "3500"
}
| Header | Value | Description |
|---|---|---|
Content-Type |
application/json | Request content type |
| Parameter | Type | Description |
|---|---|---|
transaction_id |
string | System generated transaction ID |
amount |
string | Transaction amount (in IDR) |
status |
string | Transaction status |
reference_id |
string | Your unique reference ID |
admin_fee |
string | Administrative fee charged |
| Status | Description |
|---|---|
Success |
Transaction completed successfully |
Failed |
Transaction failed |
<?php
// callback.php
header('Content-Type: application/json');
// Get the callback data
$input = file_get_contents('php://input');
$callbackData = json_decode($input, true);
// Validate the callback data
if (!$callbackData || !isset($callbackData['transaction_id']) || !isset($callbackData['reference_id'])) {
http_response_code(400);
echo json_encode(['error' => 'Invalid callback data']);
exit;
}
// Extract callback parameters
$transactionId = $callbackData['transaction_id'];
$amount = $callbackData['amount'];
$status = $callbackData['status'];
$referenceId = $callbackData['reference_id'];
$adminFee = $callbackData['admin_fee'];
// Log the callback for debugging
error_log("Callback received: " . $input);
try {
// Update your database with the transaction status
updateTransactionStatus($referenceId, $status, $transactionId);
// Handle different status types
switch ($status) {
case 'Success':
handleSuccessfulTransaction($referenceId, $transactionId, $amount);
break;
case 'Failed':
handleFailedTransaction($referenceId, $transactionId);
break;
case 'Process':
handleProcessingTransaction($referenceId, $transactionId);
break;
}
// Send success response
http_response_code(200);
echo json_encode(['status' => 'received']);
} catch (Exception $e) {
// Log error
error_log("Callback processing error: " . $e->getMessage());
// Send error response (will trigger retry)
http_response_code(500);
echo json_encode(['error' => 'Processing failed']);
}
function updateTransactionStatus($referenceId, $status, $transactionId) {
// Your database update logic here
// Example with PDO:
$pdo = new PDO($dsn, $username, $password);
$stmt = $pdo->prepare("
UPDATE transactions
SET status = ?, transaction_id = ?, updated_at = NOW()
WHERE reference_id = ?
");
$stmt->execute([$status, $transactionId, $referenceId]);
}
function handleSuccessfulTransaction($referenceId, $transactionId, $amount) {
// Handle successful transaction
// e.g., send notification to user, update user balance, etc.
// Send notification email
sendNotificationEmail($referenceId, 'Transaction successful', $amount);
// Update user balance if applicable
// creditUserAccount($referenceId, $amount);
}
function handleFailedTransaction($referenceId, $transactionId) {
// Handle failed transaction
// e.g., notify user, refund if applicable, etc.
sendNotificationEmail($referenceId, 'Transaction failed', null);
}
function handleProcessingTransaction($referenceId, $transactionId) {
// Handle processing status
// Usually no action needed as transaction is still in progress
error_log("Transaction $referenceId is still processing");
}
function sendNotificationEmail($referenceId, $subject, $amount) {
// Your email notification logic here
error_log("Would send email for $referenceId: $subject");
}
?>
const express = require('express');
const app = express();
// Middleware to parse JSON
app.use(express.json());
// Callback endpoint
app.post('/callback/@php echo strtolower(App\Helpers\BrandingHelper::getBrandName()); @endphp', async (req, res) => {
try {
// Get callback data
const {
transaction_id,
amount,
status,
reference_id,
admin_fee
} = req.body;
// Validate required fields
if (!transaction_id || !reference_id || !status) {
return res.status(400).json({ error: 'Missing required fields' });
}
// Log callback for debugging
console.log('Callback received:', req.body);
// Update transaction in database
await updateTransactionStatus(reference_id, status, transaction_id);
// Handle different status types
switch (status) {
case 'Success':
await handleSuccessfulTransaction(reference_id, transaction_id, amount);
break;
case 'Failed':
await handleFailedTransaction(reference_id, transaction_id);
break;
case 'Process':
await handleProcessingTransaction(reference_id, transaction_id);
break;
}
// Send success response
res.status(200).json({ status: 'received' });
} catch (error) {
console.error('Callback processing error:', error);
// Send error response (will trigger retry)
res.status(500).json({ error: 'Processing failed' });
}
});
async function updateTransactionStatus(referenceId, status, transactionId) {
// Your database update logic here
// Example with a hypothetical database client:
await db.query(`
UPDATE transactions
SET status = ?, transaction_id = ?, updated_at = NOW()
WHERE reference_id = ?
`, [status, transactionId, referenceId]);
}
async function handleSuccessfulTransaction(referenceId, transactionId, amount) {
// Handle successful transaction
console.log(`Transaction ${referenceId} completed successfully`);
// Send notification
await sendNotification(referenceId, 'Transaction successful', amount);
// Update user balance or perform other business logic
// await creditUserAccount(referenceId, amount);
}
async function handleFailedTransaction(referenceId, transactionId) {
// Handle failed transaction
console.log(`Transaction ${referenceId} failed`);
await sendNotification(referenceId, 'Transaction failed', null);
}
async function handleProcessingTransaction(referenceId, transactionId) {
// Handle processing status
console.log(`Transaction ${referenceId} is still processing`);
}
async function sendNotification(referenceId, message, amount) {
// Your notification logic here (email, SMS, push notification, etc.)
console.log(`Notification for ${referenceId}: ${message}`);
}
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Callback server running on port ${PORT}`);
});
from flask import Flask, request, jsonify
import json
import logging
app = Flask(__name__)
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.route('/callback/@php echo strtolower(App\Helpers\BrandingHelper::getBrandName()); @endphp', methods=['POST'])
def handle_callback():
try:
# Get callback data
callback_data = request.get_json()
if not callback_data:
return jsonify({'error': 'Invalid JSON data'}), 400
# Extract parameters
transaction_id = callback_data.get('transaction_id')
amount = callback_data.get('amount')
status = callback_data.get('status')
reference_id = callback_data.get('reference_id')
admin_fee = callback_data.get('admin_fee')
# Validate required fields
if not all([transaction_id, reference_id, status]):
return jsonify({'error': 'Missing required fields'}), 400
# Log callback
logger.info(f"Callback received: {callback_data}")
# Update transaction status
update_transaction_status(reference_id, status, transaction_id)
# Handle different status types
if status == 'Success':
handle_successful_transaction(reference_id, transaction_id, amount)
elif status == 'Failed':
handle_failed_transaction(reference_id, transaction_id)
elif status == 'Process':
handle_processing_transaction(reference_id, transaction_id)
# Return success response
return jsonify({'status': 'received'}), 200
except Exception as e:
logger.error(f"Callback processing error: {str(e)}")
return jsonify({'error': 'Processing failed'}), 500
def update_transaction_status(reference_id, status, transaction_id):
"""Update transaction status in database"""
# Your database update logic here
logger.info(f"Updating transaction {reference_id} to status {status}")
def handle_successful_transaction(reference_id, transaction_id, amount):
"""Handle successful transaction"""
logger.info(f"Transaction {reference_id} completed successfully")
# Send notification, update user balance, etc.
def handle_failed_transaction(reference_id, transaction_id):
"""Handle failed transaction"""
logger.info(f"Transaction {reference_id} failed")
# Send notification, handle refund, etc.
def handle_processing_transaction(reference_id, transaction_id):
"""Handle processing transaction"""
logger.info(f"Transaction {reference_id} is still processing")
if __name__ == '__main__':
app.run(debug=True, port=5000)
Possible Causes:
Solutions:
Possible Causes:
Solutions:
Possible Causes:
Solutions: