Skip to content

Commit

Permalink
refact: tweak payBatch controller to return after marking expenses as…
Browse files Browse the repository at this point in the history
… processing
  • Loading branch information
kewitz committed Feb 29, 2024
1 parent d054805 commit 6aa9c2a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 33 deletions.
51 changes: 38 additions & 13 deletions server/controllers/transferwise.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import config from 'config';
import { Request, Response } from 'express';

import expenseStatus from '../constants/expense-status';
Expand All @@ -6,22 +7,28 @@ import { idDecode, IDENTIFIER_TYPES } from '../graphql/v2/identifiers';
import errors from '../lib/errors';
import logger from '../lib/logger';
import { reportErrorToSentry, reportMessageToSentry } from '../lib/sentry';
import { simulateTransferSuccess } from '../lib/transferwise';
import models, { Op } from '../models';
import transferwise from '../paymentProviders/transferwise';
import { handleTransferStateChange } from '../paymentProviders/transferwise/webhook';
import { BatchGroup } from '../types/transferwise';

const processPaidExpense = (host, remoteUser, batchGroup: BatchGroup) => async expense => {
await expense.reload();
if (expense.data?.transfer) {
const payoutMethod = await expense.getPayoutMethod();
const { feesInHostCurrency } = await getExpenseFees(expense, host, { payoutMethod });
return setTransferWiseExpenseAsProcessing({
expense,
host,
data: { batchGroup },
feesInHostCurrency,
remoteUser,
});
try {
await expense.reload();
if (expense.data?.transfer) {
const payoutMethod = await expense.getPayoutMethod();
const { feesInHostCurrency } = await getExpenseFees(expense, host, { payoutMethod });
return setTransferWiseExpenseAsProcessing({
expense,
host,
data: { batchGroup },
feesInHostCurrency,
remoteUser,
});
}
} catch (e) {
logger.error(`Wise Batch Payment: Error processing paid expense ${expense.id}`, e);
}
};

Expand Down Expand Up @@ -83,10 +90,28 @@ export async function payBatch(
res.setHeader('x-2fa-approval', fundResponse.headers['x-2fa-approval']);
res.sendStatus(fundResponse.status);
} else if (fundResponse.status === 'COMPLETED') {
// Send 200 to the frontend
res.sendStatus(200);
// Mark expenses as paid and create transactions
await Promise.all(expenses.map(processPaidExpense(host, remoteUser, fundResponse)));
// Send 200 to the frontend
res.sendStatus(200);
// Simulate transfer success in other environments so transactions don't get stuck.
if (['development', 'staging'].includes(config.env)) {
const connectedAccount = await host.getAccountForPaymentProvider('transferwise');
logger.debug(`Wise: Simulating transfer success for batch group ${fundResponse.id}`);
for (const transferId of fundResponse.transferIds) {
const response = await simulateTransferSuccess(connectedAccount, transferId);
logger.debug(`Wise: Simulated transfer success for transfer ${transferId}`);
const expense = expenses.find(e => e.data.transfer.id === transferId);
await expense.update({ data: { ...expense.data, transfer: response } });
// In development mode we don't have webhooks set up, so we need to manually trigger the event handler.
if (config.env === 'development') {
await handleTransferStateChange({
// eslint-disable-next-line camelcase
data: { resource: response, current_state: 'outgoing_payment_sent' },
} as any);
}
}
}
} else {
throw new Error(`Could not pay for batch group #${fundResponse.id}, please contact support.`);
}
Expand Down
20 changes: 0 additions & 20 deletions server/paymentProviders/transferwise/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,26 +482,6 @@ async function payExpensesBatchGroup(host, expenses, x2faApproval?: string, remo
batchGroupId,
x2faApproval,
)) as BatchGroup;
// Simulate transfer success in other environments so transactions don't get stuck.
if (['development', 'staging'].includes(config.env)) {
logger.debug(`Wise: Simulating transfer success for batch group ${batchGroup.id}`);
const expenses = await Expense.findAll({
where: { data: { batchGroup: { id: batchGroup.id } } },
});
for (const transferId of batchGroup.transferIds) {
const response = await transferwise.simulateTransferSuccess(connectedAccount, transferId);
logger.debug(`Wise: Simulated transfer success for transfer ${transferId}`);
const expense = expenses.find(e => e.data.transfer.id === transferId);
await expense.update({ data: { ...expense.data, transfer: response } });
// In development mode we don't have webhooks set up, so we need to manually trigger the event handler.
if (config.env === 'development') {
await handleTransferStateChange({
// eslint-disable-next-line camelcase
data: { resource: response, current_state: 'outgoing_payment_sent' },
} as any);
}
}
}
return batchGroup;
} else {
throw new Error('payExpensesBatchGroup: you need to pass either expenses or x2faApproval');
Expand Down

0 comments on commit 6aa9c2a

Please sign in to comment.