I am using the POST
method on a Phone Pe Web API endpoint to get a list of transactions. I include cookies for authorization, but I’m encountering a 412 Precondition Failed
error after a few hours. Specifically, the cookies _X52F70K3N
and _CKB2N1BHVZ
refresh every time, and I’m able to get the transaction list for about 2-4 hours. After that, the cookies expire, and I have to manually refresh them.
Here is the code I am using to make the request, along with the response I’m getting:
Code I am using:
const axios = require('axios');
const mysql = require('mysql2');
require('dotenv').config(); // Load environment variables from .env file
const dbConfig = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
};
// PhonePe API URL and headers
const PHONEPE_API_URL = 'https://web-api.phonepe.com/apis/mi-web/v3/transactions/list';
const headers = {
'Host': 'web-api.phonepe.com',
'Content-Type': 'application/json',
'Accept': 'application/json, text/plain, */*',
'X-Csrf-Token': 'X7M1l************YQhI', // Use the actual CSRF token here
'X-App-Id': 'oculus',
'X-Source-Type': 'WEB',
'User-Agent': 'Mozilla/5.0',
'Namespace': 'insights',
'X-Source-Platform': 'WEB',
'Sec-Fetch-Site': 'same-site',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://business.phonepe.com/',
'Accept-Encoding': 'gzip, deflate, br',
'Priority': 'u=4, i',
'Cookie': '_ppabwduref=PA***********00; MERCHANT_USER_A_TOKEN=eyJ0*************9.ey*****************************************bSgo***M-y90******wg; MERCHANT_USER_R_TOKEN=f8*******-1****-4****-a***3-6*****3; _ppabwdcid=ZX***********FRR*********************WV************************zhFVU********==; _ppabwdsid=*****-***-****-***-****; _CKB2N1BHVZ=1s**************************xKStt/S*****kQ; _X52F70K3N=X7M*******QhI' // Replace with actual cookies // Replace with actual cookies
};
// Calculate timestamps for "from" and "to"
const now = Date.now();
const fromTimestamp = now - 24 * 60 * 60 * 1000; // 24 hours before now
const toTimestamp = now;
// API request payload
const requestData = {
offset: 0,
size: 10,
filters: {},
transactionType: "FORWARD",
from: fromTimestamp,
to: toTimestamp,
selectedDateType: "today"
};
// Function to fetch transaction data from PhonePe API
async function fetchTransactionData() {
try {
const response = await axios.post(PHONEPE_API_URL, requestData, { headers });
if (response.data.success) {
console.log("Transaction Data Retrieved Successfully");
return response.data.data.results || []; // Extract results from the response
} else {
console.error("Failed to fetch transaction data.");
return [];
}
} catch (error) {
console.error("Error during API request:", error);
return [];
}
}
// Function to check if a transaction ID exists in the database
async function transactionExists(transactionId, connection) {
const query = 'SELECT COUNT(*) AS count FROM transactions WHERE transaction_id = ?';
try {
const [rows] = await connection.promise().query(query, [transactionId]);
return rows[0].count > 0;
} catch (error) {
console.error('Error checking transaction existence:', error);
return false;
}
}
// Function to insert transaction data into the database
async function insertTransaction(transaction, connection) {
const transactionData = {
transaction_id: transaction.transactionId,
transaction_type: transaction.transactionType,
payment_state: transaction.paymentState,
amount: transaction.amount / 100, // Convert paise to rupees
merchant_transaction_id: transaction.merchantTransactionId,
instrument_type: transaction.instrumentDetails[0]?.instrumentType || null,
vpa: transaction.instrumentDetails[0]?.vpa || null,
transaction_note: transaction.transactionNote,
transaction_date: new Date(transaction.transactionDate).toISOString(),
customer_name: transaction.customerDetails?.userName || null,
payment_app: transaction.paymentApp?.paymentApp || null,
settlement_status: transaction.settlement?.status || null,
settlement_text: transaction.settlement?.settlementText || null,
utr: transaction.utr || null
};
const query = `
INSERT INTO transactions (transaction_id, transaction_type, payment_state, amount,
merchant_transaction_id, instrument_type, vpa, transaction_note, transaction_date,
customer_name, payment_app, settlement_status, settlement_text, utr)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
`;
try {
await connection.promise().query(query, [
transactionData.transaction_id,
transactionData.transaction_type,
transactionData.payment_state,
transactionData.amount,
transactionData.merchant_transaction_id,
transactionData.instrument_type,
transactionData.vpa,
transactionData.transaction_note,
transactionData.transaction_date,
transactionData.customer_name,
transactionData.payment_app,
transactionData.settlement_status,
transactionData.settlement_text,
transactionData.utr
]);
console.log(`Transaction ID ${transactionData.transaction_id} inserted successfully.`);
} catch (error) {
console.error(`Error inserting transaction ID ${transactionData.transaction_id}:`, error);
}
}
// Main function to fetch and update transaction data
async function main() {
const transactions = await fetchTransactionData();
if (!transactions.length) {
console.log("No transactions found.");
return;
}
const connection = mysql.createConnection(dbConfig);
try {
for (const transaction of transactions) {
const exists = await transactionExists(transaction.transactionId, connection);
if (exists) {
console.log(`Transaction ID ${transaction.transactionId} already exists. Skipping.`);
} else {
await insertTransaction(transaction, connection);
}
}
} catch (error) {
console.error("Error processing transactions:", error);
} finally {
connection.end();
}
}
main();
Response of 412 is
config: {
transitional: [Object],
adapter: [Array],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: [Object],
validateStatus: [Function: validateStatus],
headers: [Object [AxiosHeaders]],
method: 'post',
url: 'https://web-api.phonepe.com/apis/mi-web/v3/transactions/list',
data: '{"offset":0,"size":10,"filters":{},"transactionType":"FORWARD","from":1734776412434,"to":1734862812434,"selectedDateType":"today"}'
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: '130',
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: false,
socket: [TLSSocket],
_header: 'POST /apis/mi-web/v3/transactions/list HTTP/1.1rn' +
'Accept: application/json, text/plain, */*rn' +
'Content-Type: application/jsonrn' +
'Host: web-api.phonepe.comrn' +
'X-Csrf-Token: X7M1l************YQhIrn' +
'X-App-Id: oculusrn' +
'X-Source-Type: WEBrn' +
'User-Agent: Mozilla/5.0rn' +
'Namespace: insightsrn' +
'X-Source-Platform: WEBrn' +
'Sec-Fetch-Site: same-sitern' +
'Sec-Fetch-Mode: corsrn' +
'Sec-Fetch-Dest: emptyrn' +
'Referer: https://business.phonepe.com/rn' +
'Accept-Encoding: gzip, deflate, brrn' +
'Priority: u=4, irn' +
'Cookie: __ppabwduref=PA***********00; MERCHANT_USER_A_TOKEN=eyJ0*************9.ey*****************************************bSgo***M-y90******wg; MERCHANT_USER_R_TOKEN=f8*******-1****-4****-a***3-6*****3; _ppabwdcid=ZX***********FRR*********************WV************************zhFVU********==; _ppabwdsid=*****-***-****-***-****; _CKB2N1BHVZ=1s**************************xKStt/S*****kQ; _X52F70K3N=X7M*******QhI
'Content-Length: 130rn' +
'Connection: closern' +
'rn',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'POST',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
joinDuplicateHeaders: undefined,
path: '/apis/mi-web/v3/transactions/list',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'web-api.phonepe.com',
protocol: 'https:',
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kHighWaterMark)]: 16384,
[Symbol(kRejectNonStandardBodyWrites)]: false,
[Symbol(kUniqueHeaders)]: null
},
data: ''
},
status: 412
}