Merge branch 'dev' into qa
This commit is contained in:
commit
e8ca80df48
@ -10,3 +10,4 @@ CASHFREE_CLIENT_SECRET=#{CASHFREE_CLIENT_SECRET}#
|
|||||||
GOOGLE_MAPS_API_KEY=#{GOOGLE_MAPS_API_KEY}#
|
GOOGLE_MAPS_API_KEY=#{GOOGLE_MAPS_API_KEY}#
|
||||||
FITLIENHOST=#{FITLIENHOST}#
|
FITLIENHOST=#{FITLIENHOST}#
|
||||||
CASHFREE_URL=#{CASHFREE_URL}#
|
CASHFREE_URL=#{CASHFREE_URL}#
|
||||||
|
CASHFREE_LINK_URL=#{CASHFREE_LINK_URL}#
|
||||||
|
|||||||
@ -15,7 +15,7 @@ const formData = require('form-data');
|
|||||||
const Mailgun = require('mailgun.js');
|
const Mailgun = require('mailgun.js');
|
||||||
const { convert } = require('html-to-text');
|
const { convert } = require('html-to-text');
|
||||||
const twilio = require('twilio');
|
const twilio = require('twilio');
|
||||||
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
if (!admin.apps.length) {
|
if (!admin.apps.length) {
|
||||||
admin.initializeApp();
|
admin.initializeApp();
|
||||||
@ -486,6 +486,144 @@ export const createCashfreeOrder = onRequest({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const createCashfreeLink = onRequest({
|
||||||
|
region: '#{SERVICES_RGN}#'
|
||||||
|
}, async (request: Request, response: express.Response) => {
|
||||||
|
|
||||||
|
return corsHandler(request, response, async () => {
|
||||||
|
try {
|
||||||
|
const authHeader = request.headers.authorization;
|
||||||
|
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||||
|
response.status(401).json({ error: 'Unauthorized' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const idToken = authHeader.split('Bearer ')[1];
|
||||||
|
try {
|
||||||
|
const decodedToken = await admin.auth().verifyIdToken(idToken);
|
||||||
|
const uid = decodedToken.uid;
|
||||||
|
|
||||||
|
const {
|
||||||
|
amount,
|
||||||
|
customerName,
|
||||||
|
customerEmail,
|
||||||
|
customerPhone,
|
||||||
|
productInfo,
|
||||||
|
userId,
|
||||||
|
gymId,
|
||||||
|
orderId
|
||||||
|
} = request.body;
|
||||||
|
|
||||||
|
if (!amount || !customerEmail || !customerPhone) {
|
||||||
|
response.status(400).json({ error: 'Missing required fields' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const expirationDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
||||||
|
const expirationString = expirationDate.toISOString();
|
||||||
|
const clientId = process.env.CASHFREE_CLIENT_ID;
|
||||||
|
const clientSecret = process.env.CASHFREE_CLIENT_SECRET;
|
||||||
|
let apiUrl = process.env.CASHFREE_LINK_URL;
|
||||||
|
|
||||||
|
if (!clientId || !clientSecret) {
|
||||||
|
logger.error('Cashfree credentials not configured');
|
||||||
|
response.status(500).json({ error: 'Payment gateway configuration error' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const linkId = uuidv4();
|
||||||
|
try {
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'x-api-version': '2025-01-01',
|
||||||
|
'x-client-id': `${process.env.CASHFREE_CLIENT_ID}`,
|
||||||
|
'x-client-secret': `${process.env.CASHFREE_CLIENT_SECRET}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: `{
|
||||||
|
"customer_details": {
|
||||||
|
"customer_email": "${customerEmail}",
|
||||||
|
"customer_name": "${customerName}",
|
||||||
|
"customer_phone": "${customerPhone}"
|
||||||
|
},
|
||||||
|
"link_amount": ${amount},
|
||||||
|
"link_auto_reminders": true,
|
||||||
|
"link_currency": "INR",
|
||||||
|
"link_expiry_time": "${expirationString}",
|
||||||
|
"link_id": "${linkId}",
|
||||||
|
"link_meta": {
|
||||||
|
"notify_url": "https://ee08e626ecd88c61c85f5c69c0418cb5.m.pipedream.net",
|
||||||
|
"return_url": "https://www.cashfree.com/devstudio/thankyou",
|
||||||
|
"upi_intent": false
|
||||||
|
},
|
||||||
|
"link_notes": {
|
||||||
|
"userId": "${userId}",
|
||||||
|
"gymId": "${gymId}",
|
||||||
|
"orderId": "${orderId}",
|
||||||
|
"requestUserId": "${uid}"
|
||||||
|
},
|
||||||
|
"link_notify": {
|
||||||
|
"send_email": true,
|
||||||
|
"send_sms": true
|
||||||
|
},
|
||||||
|
"link_partial_payments": false,
|
||||||
|
"link_purpose": "${productInfo}",
|
||||||
|
"order_splits": []
|
||||||
|
}`
|
||||||
|
};
|
||||||
|
const cashfreeResponse = await axios.post(apiUrl!, options);
|
||||||
|
try {
|
||||||
|
await admin.firestore().collection('payment_links').doc(orderId).set({
|
||||||
|
requestUserId: uid,
|
||||||
|
amount: amount,
|
||||||
|
customerEmail: customerEmail,
|
||||||
|
customerPhone: customerPhone,
|
||||||
|
userId: userId,
|
||||||
|
gymId: gymId,
|
||||||
|
orderId: orderId,
|
||||||
|
...cashfreeResponse.data,
|
||||||
|
createdAt: new Date(),
|
||||||
|
});
|
||||||
|
} catch (firestoreError) {
|
||||||
|
logger.error('Error storing order in Firestore:', firestoreError);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.json({
|
||||||
|
success: true,
|
||||||
|
linkId: linkId,
|
||||||
|
linkUrl: cashfreeResponse.data.link_url,
|
||||||
|
linkExpiryTime: cashfreeResponse.data.link_expiry_time,
|
||||||
|
linkStatus: cashfreeResponse.data.link_status
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (axiosError: any) {
|
||||||
|
logger.error('Cashfree API error:', axiosError);
|
||||||
|
response.status(axiosError.response?.status || 500).json({
|
||||||
|
success: false,
|
||||||
|
error: 'Payment gateway error',
|
||||||
|
details: axiosError.response?.data || axiosError.message,
|
||||||
|
code: axiosError.code
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (authError) {
|
||||||
|
logger.error('Authentication error:', authError);
|
||||||
|
response.status(401).json({
|
||||||
|
success: false,
|
||||||
|
error: 'Invalid authentication token'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
logger.error('Cashfree order creation error:', error);
|
||||||
|
response.status(500).json({
|
||||||
|
success: false,
|
||||||
|
error: 'Failed to create payment order',
|
||||||
|
details: error.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
export const verifyCashfreePayment = onRequest({
|
export const verifyCashfreePayment = onRequest({
|
||||||
region: '#{SERVICES_RGN}#'
|
region: '#{SERVICES_RGN}#'
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user