"use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports.metadata=void 0;const db_1=require("@b/db"),sequelize_1=require("sequelize"),utils_1=require("./utils"),console_1=require("@b/utils/console");exports.metadata={summary:"2Checkout IPN webhook handler",description:"Handles Instant Payment Notifications (IPN) from 2Checkout to automatically process payment status updates",operationId:"handle2CheckoutWebhook",tags:["Finance","Webhook"],logModule:"WEBHOOK",logTitle:"2Checkout webhook",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",description:"2Checkout IPN payload"}},"application/x-www-form-urlencoded":{schema:{type:"object",description:"2Checkout IPN form data"}}}},responses:{200:{description:"IPN processed successfully",content:{"text/plain":{schema:{type:"string",example:"OK"}}}},400:{description:"Invalid IPN data"},500:{description:"Server error processing IPN"}},requiresAuth:!1};exports.default=async e=>{const{body:t,ctx:a}=e;try{const e=(0,utils_1.use2Checkout)(),a=t,{REFNO:o,ORDERNO:r,EXTERNAL_REFERENCE:s,ORDER_STATUS:n,PAYMENT_STATUS:i,SIGNATURE:c,TIMESTAMP:l,CURRENCY:u,TOTAL:d}=a;if(!o&&!r){console_1.logger.error("2CHECKOUT","Missing required reference number");return{statusCode:400,body:"Missing reference number"}}if(c){const t={REFNO:o||"",ORDERNO:r||"",EXTERNAL_REFERENCE:s||"",ORDER_STATUS:n||"",PAYMENT_STATUS:i||"",TIMESTAMP:l||"",CURRENCY:u||"",TOTAL:d||""};if(!(0,utils_1.verify2CheckoutSignature)(t,c,e.secretKey)){console_1.logger.error("2CHECKOUT","Invalid signature");return{statusCode:400,body:"Invalid signature"}}}const p=s?{description:{[sequelize_1.Op.like]:`%${s}%`}}:{metadata:{[sequelize_1.Op.like]:`%${o||r}%`}},E=await db_1.models.transaction.findOne({where:{...p,type:"DEPOSIT",status:"PENDING"},include:[{model:db_1.models.wallet,as:"wallet"}]});if(!E){console_1.logger.warn("2CHECKOUT",`Transaction not found for reference ${s||o||r}`);return{statusCode:200,body:"OK"}}const T="COMPLETE"===n||"AUTHRECEIVED"===n||"COMPLETE"===i||"AUTHRECEIVED"===i;await db_1.sequelize.transaction(async e=>{if(T){await E.update({status:"COMPLETED",metadata:JSON.stringify({...JSON.parse(E.metadata||"{}"),refNo:o,orderNo:r,externalReference:s,orderStatus:n,paymentStatus:i,gateway:"2checkout",ipnTimestamp:l,processedAt:(new Date).toISOString(),ipnData:a})},{transaction:e});const t=E.wallet;if(t){const a=parseFloat(E.amount)-parseFloat(E.fee||"0"),o=parseFloat(t.balance)+a;await t.update({balance:o},{transaction:e});console_1.logger.info("2CHECKOUT",`Wallet ${t.id} balance updated by ${a} ${t.currency}`)}console_1.logger.success("2CHECKOUT",`Transaction ${E.id} completed successfully`)}else{await E.update({status:"FAILED",metadata:JSON.stringify({...JSON.parse(E.metadata||"{}"),refNo:o,orderNo:r,externalReference:s,orderStatus:n,paymentStatus:i,gateway:"2checkout",ipnTimestamp:l,failureReason:`Order status: ${n}, Payment status: ${i}`,processedAt:(new Date).toISOString(),ipnData:a})},{transaction:e});console_1.logger.warn("2CHECKOUT",`Transaction ${E.id} marked as failed`)}});return{statusCode:200,body:"OK"}}catch(e){console_1.logger.error("2CHECKOUT","IPN Error",e);return{statusCode:500,body:"Internal Server Error"}}};