diff --git a/functions/src/payments/phonepe/webhook.ts b/functions/src/payments/phonepe/webhook.ts index 05e4ee9..1694817 100644 --- a/functions/src/payments/phonepe/webhook.ts +++ b/functions/src/payments/phonepe/webhook.ts @@ -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}`