🔹 Introduction
When integrating Paytm (payments) with Firebase Realtime Database or Firestore, many developers face a common problem: values stored as null (or missing) after a Paytm callback / request. This usually happens because of incorrect payload handling, wrong database paths, async timing issues, or JSON/encoding problems.
In this guide you’ll learn practical steps to find and fix null value issues (both client & server side), plus working code examples and troubleshooting tips.
🔹 Common Causes of null Values
-
Wrong database path or reference (writing to a different node).
-
Using
push()then overwriting withset()incorrectly. -
Writing before the Paytm response is fully parsed (async/await missing).
-
Wrong JSON structure / missing keys in payload.
-
Not converting data types (e.g., sending
undefinedor empty string). -
Firebase Security Rules blocking writes (appears as no data).
-
Using
.val()or snapshot incorrectly when reading data. -
Incorrect
Content-Type/ encoding in server callbacks (Paytm -> your webhook).
🔹 Step-by-Step Fixes (Server & Client)
1. Log the incoming Paytm payload
Before writing to DB, log the raw payload to confirm what Paytm sent.
// Node.js / Express example
app.post('/paytm-callback', (req, res) => {
console.log('Paytm payload:', req.body);
// then parse and validate
});
If req.body is empty or undefined, ensure you use the correct body parser and Content-Type (e.g., application/x-www-form-urlencoded or JSON).
2. Ensure correct body parsing
Paytm sometimes posts urlencoded data. Use proper middleware:
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
3. Validate keys & set defaults
Always read required keys and set fallback defaults to avoid undefined:
const orderId = req.body.ORDERID || 'unknown';
const status = req.body.STATUS || 'UNKNOWN';
4. Use async/await / Promises properly
Write to Firebase only after payload validation and checksum verification:
// Firebase Admin SDK (Realtime DB)
const admin = require('firebase-admin');
async function handlePaytm(req, res) {
const data = { orderId, status, amount };
try {
const ref = admin.database().ref('payments').child(orderId);
await ref.set(data); // ensures data saved
res.send('OK');
} catch (err) {
console.error(err);
res.status(500).send('Error');
}
}
If you call res.send() before the await, writes may not complete reliably.
5. Check and use correct DB path
A tiny typo in the path means writing to a different location. Example:
// Bad: 'payment' vs correct 'payments'
admin.database().ref('payments').child(orderId).set(data);
6. Avoid writing undefined or NaN
If an object contains undefined values, Firebase may store null. Clean the object:
function clean(obj) {
return Object.fromEntries(Object.entries(obj).filter(([k,v]) => v !== undefined));
}
await ref.set(clean(data));
7. Use update() when partial updates needed
If you want to update only some fields (no overwriting), use update():
await ref.update({ status: 'TXN_SUCCESS', updatedAt: Date.now() });
8. Check Firebase Security Rules
If rules deny write, the client may get silent failure. For Realtime DB:
{
"rules": {
"payments": {
".write": true,
".read": true
}
}
}
(Use strict rules for production — above is only for quick debugging.)
9. Verify Paytm checksum & respond correctly
Paytm requires you to verify checksum — only write to DB after verification:
const isValid = verifyChecksum(req.body, PAYTM_MERCHANT_KEY);
if (!isValid) {
return res.status(400).send('Checksum mismatch');
}
10. Read with snapshot.val() correctly
When reading back, use snapshot properly:
const snap = await admin.database().ref('payments').child(orderId).once('value');
const saved = snap.val();
console.log('Saved record', saved);
🔹 Example: Full Node.js Flow (Paytm callback → Firebase Realtime DB)
const express = require('express');
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: 'https://your-db.firebaseio.com'
});
const app = express();
app.use(express.urlencoded({ extended:true }));
app.use(express.json());
app.post('/paytm-callback', async (req, res) => {
try {
console.log('raw body:', req.body);
// 1. Verify checksum here (Paytm lib)
// const isValid = verifyChecksum(req.body, PAYTM_KEY);
// if (!isValid) return res.status(400).send('Checksum fail');
// 2. Extract & sanitize
const orderId = req.body.ORDERID || 'unknown';
const amount = req.body.TXNAMOUNT || '0';
const status = req.body.STATUS || 'UNKNOWN';
const payload = { orderId, amount, status, receivedAt: Date.now() };
// clean undefined
const cleanPayload = Object.fromEntries(Object.entries(payload).filter(([k,v]) => v !== undefined));
// 3. Write to Firebase
const ref = admin.database().ref(`payments/${orderId}`);
await ref.set(cleanPayload);
// 4. Confirm
res.status(200).send('OK');
} catch (err) {
console.error('callback error', err);
res.status(500).send('Server Error');
}
});
🔹 Android (Client) Tips — If you write from app after Paytm SDK
-
Wait for
onTransactionResponse()or callback before writing to Firebase. -
Use
Map<String, Object>and ensure values not null. -
Use
push()to create unique child, thenupdateChildren()to avoid overwriting.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("payments");
Map<String, Object> data = new HashMap<>();
data.put("orderId", orderId);
data.put("status", status == null ? "UNKNOWN" : status);
ref.child(orderId).setValue(data).addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Log.d("FB", "Saved");
} else {
Log.e("FB", "Save failed", task.getException());
}
});
🔹 Extra Troubleshooting Checklist
-
Test payload with Postman and verify your endpoint receives fields.
-
Enable Firebase Database logging (console) to see writes/denials.
-
Inspect network tab (DevTools) for failed requests.
-
Temporarily relax rules to test writing, then tighten later.
-
Add server-side retries with exponential backoff for transient errors.
-
Confirm timestamps and numeric types are strings if Paytm sends them as strings (or convert appropriately).
🔹 Key Features (What this fix provides)
-
Reliable writes to Firebase after Paytm callback.
-
No
nullvalues — use cleaning + validation. -
Secure: verify checksum before saving.
-
Works for Realtime DB and similar approach for Firestore.
🔹 Perfect For
-
Developers integrating Paytm payments with Firebase.
-
Backend engineers handling payment callbacks & database writes.
-
Android/iOS devs who want reliable payment records in DB.
🔹 FAQ (Simple English)
Q1: Why do some fields show null after save?
Usually because the value was undefined or you wrote to wrong path. Log payload first and clean object before saving.
Q2: Paytm sends urlencoded data — how to parse?
Make sure server uses express.urlencoded({ extended: true }) or correct body parser for your framework.
Q3: Firebase rules blocking my write — how to check?
Check Firebase Console → Realtime Database → Rules and enable temporary write for debugging.
Q4: Does this work for Firestore too?
Yes — the same principles apply: validate payload, clean undefined fields, use set() or update() with proper document path.
