Compare commits

...

20 Commits

Author SHA1 Message Date
769311bb1b Merge pull request 'phonepe' (#35) from phonepe into dev
Some checks failed
Deploy FitLien services to Dev / Deploy to Dev (push) Failing after 3m37s
Reviewed-on: #35
2025-05-20 10:10:58 +00:00
AllenTJ7
a4c3cbbba2 added logging 2025-05-20 15:40:30 +05:30
AllenTJ7
c6f8b7fc35 Update webhook.ts 2025-05-20 15:19:01 +05:30
AllenTJ7
9c002a4d61 Update firebase.json 2025-05-20 14:41:50 +05:30
AllenTJ7
6b1d86afc2 Merge branch 'dev' into phonepe 2025-05-20 14:34:17 +05:30
AllenTJ7
06c5f018c3 changed pdf again 2025-05-20 14:32:59 +05:30
AllenTJ7
9d17bd39ce Merge branch 'dev' into phonepe 2025-05-20 14:16:21 +05:30
AllenTJ7
762e6b77e5 Update invoiceService.ts 2025-05-20 14:15:36 +05:30
AllenTJ7
80b3829347 Merge branch 'dev' into phonepe 2025-05-20 13:51:47 +05:30
AllenTJ7
d8dfd8a6f2 pdf changes 2025-05-20 13:50:04 +05:30
AllenTJ7
756b6fed83 Merge branch 'dev' into phonepe 2025-05-20 13:34:23 +05:30
AllenTJ7
3ef81f8273 Update index.ts 2025-05-20 13:32:54 +05:30
AllenTJ7
b11cefbab4 Update invoiceService.ts 2025-05-20 13:32:51 +05:30
AllenTJ7
2d6b14663b changed pdf to use encoding supported package 2025-05-19 14:28:51 +05:30
AllenTJ7
4fe2ff7abf Merge branch 'dev' into phonepe 2025-05-19 13:20:59 +05:30
AllenTJ7
2d55e1f461 Update webhook.ts 2025-05-19 13:18:52 +05:30
AllenTJ7
f62dfdfad2 dev merged 2025-05-19 12:55:57 +05:30
AllenTJ7
e8710074c4 Invoice 2025-05-19 12:52:06 +05:30
AllenTJ7
6d64f1e4d7 Logging and client profile change 2025-05-14 18:34:58 +05:30
AllenTJ7
38d5092ee3 Update webhook.ts 2025-05-12 13:13:27 +05:30

View File

@ -21,7 +21,7 @@ export const phonePeWebhook = onRequest({
body: request.body,
method: request.method
});
const authHeader = request.headers['authorization'] as string;
const username = process.env.PHONEPE_WEBHOOK_USERNAME;
const password = process.env.PHONEPE_WEBHOOK_PASSWORD;
@ -37,7 +37,7 @@ export const phonePeWebhook = onRequest({
.createHash('sha256')
.update(credentialString)
.digest('hex');
const receivedAuth = authHeader.replace(/^SHA256\s+/i, '');
if (receivedAuth.toLowerCase() !== expectedAuth.toLowerCase()) {
@ -107,34 +107,53 @@ export const phonePeWebhook = onRequest({
if (payload.state === 'COMPLETED') {
try {
logger.info(`Starting payment update process for merchantOrderId: ${payload.merchantOrderId}`);
const paymentUpdateSuccess = await updatePaymentDataAfterSuccess(
payload.merchantOrderId,
payload.orderId,
payload
);
logger.info(`Payment update result for merchantOrderId: ${payload.merchantOrderId}`, {
success: paymentUpdateSuccess,
orderId: payload.orderId
});
if (paymentUpdateSuccess) {
const orderData = orderDoc.data();
const membershipId = orderData.metaInfo?.membershipId;
logger.info(`Processing invoice for completed payment`, {
merchantOrderId: payload.merchantOrderId,
orderId: payload.orderId,
membershipId: membershipId || 'not-provided'
});
if (membershipId) {
try {
logger.info(`Fetching membership data for membershipId: ${membershipId}`);
const membershipDoc = await admin.firestore()
.collection('memberships')
.doc(membershipId)
.get();
if (membershipDoc.exists) {
logger.info(`Membership data retrieved successfully for membershipId: ${membershipId}`);
const membershipData = membershipDoc.data();
const userId = membershipData?.userId;
logger.info(`Fetching user data for userId: ${userId}`);
const userDoc = await admin.firestore()
.collection('users')
.doc(userId)
.get();
if (userDoc.exists) {
logger.info(`User data retrieved successfully for userId: ${userId}`);
logger.info(`Starting invoice generation process for payment: ${payload.merchantOrderId}`);
const userData = userDoc.data();
const gymId = orderData.metaInfo?.gymId || membershipData?.gymId;
@ -202,6 +221,14 @@ export const phonePeWebhook = onRequest({
}
const invoiceNumber = `INV-${payload.merchantOrderId.substring(0, 8)}`;
logger.info(`Generated invoice number: ${invoiceNumber}`);
logger.info(`Preparing invoice data for generation`, {
invoiceNumber,
merchantOrderId: payload.merchantOrderId,
gymName: gymName
});
const invoiceData = {
invoiceNumber,
businessName: gymName,
@ -218,6 +245,12 @@ export const phonePeWebhook = onRequest({
};
const invoicePath = await invoiceService.generateInvoice(invoiceData);
logger.info(`Invoice generated successfully at path: ${invoicePath}`);
logger.info(`Updating membership payment with invoice path`, {
membershipId,
invoicePath
});
await admin.firestore()
.collection('membership_payments')
@ -225,29 +258,50 @@ export const phonePeWebhook = onRequest({
.get()
.then(async (doc) => {
if (doc.exists) {
logger.info(`Found membership payment document for membershipId: ${membershipId}`);
const paymentsData = doc.data()?.payments || [];
let paymentFound = false;
for (let i = 0; i < paymentsData.length; i++) {
if (paymentsData[i].referenceNumber === payload.merchantOrderId ||
paymentsData[i].transactionId === payload.orderId) {
paymentsData[i].invoicePath = invoicePath;
paymentFound = true;
break;
}
}
logger.info(`Payment record ${paymentFound ? 'found' : 'not found'} in membership payments`, {
membershipId,
merchantOrderId: payload.merchantOrderId,
orderId: payload.orderId
});
await doc.ref.update({
'payments': paymentsData,
'updatedAt': admin.firestore.FieldValue.serverTimestamp(),
});
logger.info(`Successfully updated membership payment with invoice path`, {
membershipId,
invoicePath
});
} else {
logger.warn(`No membership payment document found for membershipId: ${membershipId}`);
}
});
logger.info(`Generated invoice for payment: ${payload.merchantOrderId}, path: ${invoicePath}`);
logger.info(`Getting download URL for invoice: ${invoicePath}`);
const downloadUrl = await invoiceService.getInvoiceDownloadUrl(invoicePath);
logger.info(`Generated download URL for invoice: ${invoicePath}`);
const formattedDate = format(new Date(), 'dd/MM/yyyy');
if (membershipData?.fields?.['email']) {
logger.info(`Preparing to send invoice email to customer: ${membershipData?.fields?.['email']}`);
try {
const emailSubject = isFreeplan
? `Free Plan Assigned - ${gymName}`
@ -294,6 +348,7 @@ export const phonePeWebhook = onRequest({
}
if (gymOwnerEmail) {
logger.info(`Preparing to send invoice email to gym owner: ${gymOwnerEmail}`);
try {
const ownerEmailSubject = isFreeplan
? `Free Plan Assigned${paymentType === 'Gym Membership with Personal Training' ? ' with Personal Training' : ''} - ${gymName}`