Safe to log: transaction reference, amount, status, customer email, gateway_response, channel, ip_address. Never log: your Paystack secret key, authorization_code (store encrypted instead), full card numbers (you should never see these), CVV, or the raw Authorization header from your outbound API requests. Mask sensitive values in logs using a sanitize function before writing to any log store.
| Data | Log? | Reason |
|---|---|---|
| Transaction reference | Yes | Core debug identifier |
| Amount (in kobo) | Yes | Needed for reconciliation |
| Status (success/failed) | Yes | Track payment outcomes |
| Customer email | Yes (masked) | Use "u***@gmail.com" format |
| gateway_response | Yes | Debug declined cards |
| channel | Yes | Debug payment method issues |
| ip_address | Yes | Fraud detection |
| Paystack secret key | Never | Full account compromise |
| Authorization header (outbound) | Never | Contains secret key |
| authorization_code | Never in plaintext | Token for charging card again |
| Card number (PAN) | Never | You should never see this anyway |
| CVV | Never | You should never see this |
// logger.js — safe payment event logging
function maskEmail(email) {
if (!email || !email.includes('@')) return email;
var [local, domain] = email.split('@');
return local[0] + '***@' + domain;
}
function sanitizePaystackResponse(data) {
// Only extract the fields you need — never spread the whole object
return {
reference: data.reference,
amount: data.amount,
status: data.status,
gateway_response: data.gateway_response,
channel: data.channel,
ip_address: data.ip_address,
customer_email: maskEmail(data.customer?.email),
// Deliberately excluded: authorization.authorization_code, authorization.bin (full)
};
}
// In your webhook handler
if (event.event === 'charge.success') {
var safeData = sanitizePaystackResponse(event.data);
console.log(JSON.stringify({ event: 'charge.success', ...safeData }));
// Safe — none of the sensitive fields are in here
}
// When making outbound Paystack API calls — never log the full headers object
async function callPaystack(endpoint, body) {
var response = await fetch('https://api.paystack.co' + endpoint, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
// Log the response, not the request headers
var data = await response.json();
console.log(JSON.stringify({ endpoint, status: response.status, ref: data.data?.reference }));
return data;
}
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
This guide is part of the Paystack security guide.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course