Skip to content

Commit

Permalink
fix(apps): Prefering keys from app data (when available) over env vars
Browse files Browse the repository at this point in the history
Update env vars always config keys are read from app data (seller config)
  • Loading branch information
leomp12 committed Aug 1, 2024
1 parent 88dac3e commit 613c095
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 158 deletions.
32 changes: 15 additions & 17 deletions packages/apps/mercadopago/src/mp-create-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import type {
CreateTransactionResponse,
} from '@cloudcommerce/types';
import { getFirestore } from 'firebase-admin/firestore';
import logger from 'firebase-functions/logger';
import config from '@cloudcommerce/firebase/lib/config';
import config, { logger } from '@cloudcommerce/firebase/lib/config';
import axios from 'axios';

const parsePaymentStatus = (status: string) => {
Expand Down Expand Up @@ -60,7 +59,7 @@ export default async (appData: AppModuleBody) => {

const { buyer } = params;
const orderId = params.order_id;
logger.log('> MP Transaction #', storeId, orderId);
logger.info('> MP Transaction #', { storeId, orderId });

// https://www.mercadopago.com.br/developers/pt/reference/payments/_payments/post/
const payerPhone = {
Expand Down Expand Up @@ -145,20 +144,19 @@ export default async (appData: AppModuleBody) => {
ecom_order_id: orderId,
},
};
logger.log('>data: ', JSON.stringify(payment));
logger.info('>data: ', payment);

const mpAccessToken = configApp.mp_access_token;
if (typeof mpAccessToken === 'string' && mpAccessToken) {
process.env.MERCADOPAGO_TOKEN = mpAccessToken;
}
if (!process.env.MERCADOPAGO_TOKEN) {
const mpAccessToken = configApp.mp_access_token;
if (typeof mpAccessToken === 'string' && mpAccessToken) {
process.env.MERCADOPAGO_TOKEN = mpAccessToken;
} else {
logger.warn('Missing Mercadopago access token');
return {
status: 409,
error: 'CREATE_TRANSACTION_ERR',
message: 'The MERCADOPAGO_TOKEN is not defined in the environment variables',
};
}
logger.warn('Missing Mercadopago access token');
return {
status: 409,
error: 'CREATE_TRANSACTION_ERR',
message: 'The MERCADOPAGO_TOKEN is not defined in the environment variables',
};
}

try {
Expand All @@ -179,7 +177,7 @@ export default async (appData: AppModuleBody) => {
data: payment,
});
if (data) {
logger.log('> MP Checkout #', storeId, orderId);
logger.info('> MP Checkout #', { storeId, orderId });

const statusPayment = parsePaymentStatus(data.status);
let isSaveRetry = false;
Expand All @@ -198,7 +196,7 @@ export default async (appData: AppModuleBody) => {
merge: true,
})
.then(() => {
logger.log('> Payment #', String(data.id));
logger.info('> Payment #', { paymentId: String(data.id) });
resolve(true);
})
.catch((err) => {
Expand Down
162 changes: 79 additions & 83 deletions packages/apps/mercadopago/src/mp-webhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,107 +23,103 @@ export const mercadopago = {
const app = (await api.get(
`applications?app_id=${config.get().apps.mercadoPago.appId}&fields=hidden_data`,
)).data.result;
const mpAccessToken = app[0]?.hidden_data?.mp_access_token;
if (typeof mpAccessToken === 'string' && mpAccessToken) {
process.env.MERCADOPAGO_TOKEN = mpAccessToken;
}
if (!process.env.MERCADOPAGO_TOKEN) {
const mpAccessToken = app[0].hidden_data?.mp_access_token;
if (typeof mpAccessToken === 'string' && mpAccessToken) {
process.env.MERCADOPAGO_TOKEN = mpAccessToken;
} else {
logger.warn('Missing Mercadopago access token');
}
logger.warn('Missing Mercadopago access token');
res.sendStatus(406);
return;
}

if (process.env.MERCADOPAGO_TOKEN) {
const notification = req.body;
if (notification.type !== 'payment' || !notification.data || !notification.data.id) {
res.status(404).send('SKIP');
}

logger.log('> MP Notification for Payment #', notification.data.id);
const notification = req.body;
if (notification.type !== 'payment' || !notification.data || !notification.data.id) {
res.status(404).send('SKIP');
}
logger.log('> MP Notification for Payment #', notification.data.id);

const docRef = getFirestore().collection('mercadopagoPayments')
.doc(String(notification.data.id));
const docRef = getFirestore().collection('mercadopagoPayments')
.doc(String(notification.data.id));

docRef.get()
.then(async (doc) => {
if (doc.exists) {
const data = doc.data();
const orderId = data?.order_id;
const order = (await api.get(
`orders/${orderId}`,
)).data;
logger.log('>order ', JSON.stringify(order), '<');
if (order && order.transactions) {
const payment = (await axios.get(
`https://api.mercadopago.com/v1/payments/${notification.data.id}`,
{
headers: {
Authorization: `Bearer ${process.env.MERCADOPAGO_TOKEN}`,
'Content-Type': 'application/json',
},
docRef.get()
.then(async (doc) => {
if (doc.exists) {
const data = doc.data();
const orderId = data?.order_id;
const order = (await api.get(
`orders/${orderId}`,
)).data;
logger.log('>order ', JSON.stringify(order), '<');
if (order && order.transactions) {
const payment = (await axios.get(
`https://api.mercadopago.com/v1/payments/${notification.data.id}`,
{
headers: {
Authorization: `Bearer ${process.env.MERCADOPAGO_TOKEN}`,
'Content-Type': 'application/json',
},
)).data;
logger.log('>payment ', JSON.stringify(payment), ' <');
const methodPayment = payment.payment_method_id;
},
)).data;
logger.log('>payment ', JSON.stringify(payment), ' <');
const methodPayment = payment.payment_method_id;

const transaction = order.transactions.find(({ intermediator }) => {
return intermediator
&& intermediator.transaction_code === notification.data.id;
});
const status = parsePaymentStatus(payment.status);
if (transaction) {
const bodyPaymentHistory = {
transaction_id: transaction._id,
date_time: new Date().toISOString(),
status,
notification_code: String(notification.id),
flags: [
'mercadopago',
],
} as any; // TODO: incompatible type=> amount and status
const transaction = order.transactions.find(({ intermediator }) => {
return intermediator
&& intermediator.transaction_code === notification.data.id;
});
const status = parsePaymentStatus(payment.status);
if (transaction) {
const bodyPaymentHistory = {
transaction_id: transaction._id,
date_time: new Date().toISOString(),
status,
notification_code: String(notification.id),
flags: [
'mercadopago',
],
} as any; // TODO: incompatible type=> amount and status

if (status !== order.financial_status?.current) {
// avoid unnecessary API request
await api.post(`orders/${orderId}/payments_history`, bodyPaymentHistory);
const updatedAt = new Date().toISOString();
docRef.set({ status, updatedAt }, { merge: true }).catch(logger.error);
}
if (status !== order.financial_status?.current) {
// avoid unnecessary API request
await api.post(`orders/${orderId}/payments_history`, bodyPaymentHistory);
const updatedAt = new Date().toISOString();
docRef.set({ status, updatedAt }, { merge: true }).catch(logger.error);
}

if ((status === 'paid' && methodPayment === 'pix' && transaction)) {
let { notes } = transaction;
notes = notes?.replace('display:block', 'display:none'); // disable QR Code
notes = `${notes} # PIX Aprovado`;
if ((status === 'paid' && methodPayment === 'pix' && transaction)) {
let { notes } = transaction;
notes = notes?.replace('display:block', 'display:none'); // disable QR Code
notes = `${notes} # PIX Aprovado`;

// Update to disable QR Code
try {
await api.patch(
`orders/${order._id}/transactions/${transaction._id}`,
{ notes },
);
} catch (e) {
logger.error(e);
}
// Update to disable QR Code
try {
await api.patch(
`orders/${order._id}/transactions/${transaction._id}`,
{ notes },
);
} catch (e) {
logger.error(e);
}
res.status(200).send('SUCCESS');
} else {
logger.log('> Transaction not found #', notification.data.id);
res.sendStatus(404);
}
res.status(200).send('SUCCESS');
} else {
logger.log('> Order Not Found #', orderId);
logger.log('> Transaction not found #', notification.data.id);
res.sendStatus(404);
}
} else {
logger.log('> Payment not found in Firestore #', notification.data.id);
logger.log('> Order Not Found #', orderId);
res.sendStatus(404);
}
})
.catch((err) => {
logger.error(err);
res.sendStatus(503);
});
} else {
res.sendStatus(406);
}
} else {
logger.log('> Payment not found in Firestore #', notification.data.id);
res.sendStatus(404);
}
})
.catch((err) => {
logger.error(err);
res.sendStatus(503);
});
} catch (e) {
logger.error(e);
res.sendStatus(500);
Expand Down
19 changes: 9 additions & 10 deletions packages/apps/pagarme/src/pagarme-create-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,16 @@ export default async (modBody: AppModuleBody<'create_transaction'>) => {
} = params;
logger.info(`Transaction #${orderId}`);

const pagarmeToken = appData.pagarme_api_key;
if (typeof pagarmeToken === 'string' && pagarmeToken) {
process.env.PAGARME_TOKEN = pagarmeToken;
}
if (!process.env.PAGARME_TOKEN) {
const pagarmeToken = appData.pagarme_api_key;
if (typeof pagarmeToken === 'string' && pagarmeToken) {
process.env.PAGARME_TOKEN = pagarmeToken;
} else {
logger.warn('Missing Pagar.me API token');
return {
error: 'NO_PAGARME_KEYS',
message: 'Chave de API não configurada (lojista deve configurar o aplicativo)',
};
}
logger.warn('Missing Pagar.me API token');
return {
error: 'NO_PAGARME_KEYS',
message: 'Chave de API não configurada (lojista deve configurar o aplicativo)',
};
}

// https://apx-mods.e-com.plus/api/v1/create_transaction/response_schema.json?store_id=100
Expand Down
15 changes: 7 additions & 8 deletions packages/apps/pagarme/src/pagarme-webhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ export const pagarme = {
`applications?app_id=${config.get().apps.pagarMe.appId}&fields=hidden_data`,
)).data.result;

const pagarmeToken = app[0]?.hidden_data?.pagarme_api_key;
if (typeof pagarmeToken === 'string' && pagarmeToken) {
process.env.PAGARME_TOKEN = pagarmeToken;
}
if (!process.env.PAGARME_TOKEN) {
const pagarmeToken = app[0].hidden_data?.pagarme_api_key;
if (typeof pagarmeToken === 'string' && pagarmeToken) {
process.env.PAGARME_TOKEN = pagarmeToken;
} else {
logger.warn('Missing PagarMe API token');
res.sendStatus(409);
return;
}
logger.warn('Missing PagarMe API token');
res.sendStatus(409);
return;
}

// https://docs.pagar.me/docs/gerenciando-postbacks
Expand Down
17 changes: 10 additions & 7 deletions packages/apps/paghiper/src/paghiper-create-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,18 @@ export default async (appData: AppModuleBody) => {
paghiperTransaction.notification_url += '/pix';
}

const pagHiperToken = configApp.paghiper_api_key;
if (typeof pagHiperToken === 'string' && pagHiperToken) {
process.env.PAGHIPER_TOKEN = pagHiperToken;
}
if (!process.env.PAGHIPER_TOKEN) {
const pagHiperToken = configApp.paghiper_api_key;
if (typeof pagHiperToken === 'string' && pagHiperToken) {
process.env.PAGHIPER_TOKEN = pagHiperToken;
} else {
logger.warn('Missing PagHiper API token');
}
logger.warn('Missing PagHiper API token');
return {
error: 'NO_PAGHIPER_KEYS',
message: 'Chave de API não configurada (lojista deve configurar o aplicativo)',
};
}
// use configured PagHiper API key

paghiperTransaction.apiKey = process.env.PAGHIPER_TOKEN;
// merge configured banking billet options
const options = configApp.banking_billet_options;
Expand Down
33 changes: 17 additions & 16 deletions packages/apps/pix/src/pix-create-transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,27 +103,28 @@ export default async (appData: AppModuleBody) => {
// const clientId = pixApi.client_id;
// const clientSecret = pixApi.client_secret;

let clientId: string;
let clientSecret: string;
let tokenData: string;

if (process.env.PIX_CREDENTIALS) {
let clientId: string | undefined;
let clientSecret: string | undefined;
let tokenData: string | undefined;
if (pixApi.client_id && pixApi.client_secret && pixApi.authentication) {
clientId = pixApi.client_id;
clientSecret = pixApi.client_secret;
tokenData = pixApi.authentication;
} else if (process.env.PIX_CREDENTIALS) {
try {
const pixCredentials = JSON.parse(process.env.PIX_CREDENTIALS);
clientId = pixCredentials.client_id;
clientSecret = pixCredentials.client_secret;
tokenData = pixCredentials.authentication;
} catch (e) {
logger.error(e);

clientId = pixApi.client_id;
clientSecret = pixApi.client_secret;
tokenData = pixApi.authentication;
}
} else {
clientId = pixApi.client_id;
clientSecret = pixApi.client_secret;
tokenData = pixApi.authentication;
}
if ((!clientId || !clientSecret) && !tokenData) {
return {
error: 'NO_PIX_CREDENTIALS',
message: 'Client ID e/ou Secret não configurados (lojista deve configurar o aplicativo)',
};
}

const pix = new Pix({
Expand Down Expand Up @@ -236,9 +237,9 @@ export default async (appData: AppModuleBody) => {
};
transaction.payment_link = qrCodeUrl;
transaction.notes = `<img src="${qrCodeSrc}" style="display:block;margin:0 auto">`;

await saveToDb(clientId, clientSecret, pixApi, pix.axios, configApp, baseUri);

if (clientId && clientSecret) {
await saveToDb(clientId, clientSecret, pixApi, pix.axios, configApp, baseUri);
}
return {
status: 200,
redirect_to_payment: false,
Expand Down
Loading

0 comments on commit 613c095

Please sign in to comment.