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}#
|
||||
FITLIENHOST=#{FITLIENHOST}#
|
||||
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 { convert } = require('html-to-text');
|
||||
const twilio = require('twilio');
|
||||
|
||||
const { v4: uuidv4 } = require('uuid');
|
||||
|
||||
if (!admin.apps.length) {
|
||||
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({
|
||||
region: '#{SERVICES_RGN}#'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user