diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index b772b844dd..cf24091631 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@kontist/mock-solaris", - "version": "1.0.183", + "version": "1.0.184", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@kontist/mock-solaris", - "version": "1.0.183", + "version": "1.0.184", "license": "Apache-2.0", "dependencies": { "bluebird": "^3.4.7", diff --git a/package.json b/package.json index c77c766ee6..63c2f80189 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kontist/mock-solaris", - "version": "1.0.183", + "version": "1.0.184", "description": "Mock Service for Solaris API", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/src/app.ts b/src/app.ts index fb644d6831..c9ab149d84 100644 --- a/src/app.ts +++ b/src/app.ts @@ -777,7 +777,7 @@ app.post( // BACKOFFICE - SCHEDULED TRANSFERS app.post( - "/__BACKOFFICE__/triggerScheduledTransfer/:personId/:scheduledTransferId", + "/__BACKOFFICE__/triggerScheduledTransfer/:accountId/:scheduledTransferId", safeRequestHandler( scheduledTransfersAPI.triggerScheduledTransferRequestHandler ) diff --git a/src/helpers/types.ts b/src/helpers/types.ts index 79fe33b4cd..081d011850 100644 --- a/src/helpers/types.ts +++ b/src/helpers/types.ts @@ -636,6 +636,7 @@ export enum TransactionWebhookEvent { "SEPA_TIMED_ORDER" = "SEPA_TIMED_ORDER", "SEPA_DIRECT_DEBIT_RETURN" = "SEPA_DIRECT_DEBIT_RETURN", "SCHEDULED_TRANSFER_STATUS_CHANGED" = "SCHEDULED_TRANSFER_STATUS_CHANGED", + "SEPA_CREDIT_TRANSACTION_DECLINED" = "SEPA_CREDIT_TRANSACTION_DECLINED", } export enum PersonWebhookEvent { diff --git a/src/helpers/webhooks.ts b/src/helpers/webhooks.ts index 3d858eb205..b9d3130d44 100644 --- a/src/helpers/webhooks.ts +++ b/src/helpers/webhooks.ts @@ -77,6 +77,10 @@ const WEBHOOK_SECRETS = { process.env.SOLARIS_SEPA_TIMED_ORDER_WEBHOOK_SECRET, [TransactionWebhookEvent.SEPA_DIRECT_DEBIT_RETURN]: process.env.SOLARIS_SEPA_DIRECT_DEBIT_RETURN_WEBHOOK_SECRET, + [TransactionWebhookEvent.SCHEDULED_TRANSFER_STATUS_CHANGED]: + process.env.SOLARIS_SCHEDULED_TRANSFER_STATUS_CHANGED_WEBHOOK_SECRET, + [TransactionWebhookEvent.SEPA_CREDIT_TRANSACTION_DECLINED]: + process.env.SOLARIS_SEPA_CREDIT_TRANSACTION_DECLINED_WEBHOOK_SECRET, [AccountWebhookEvent.ACCOUNT_BLOCK]: process.env.SOLARIS_ACCOUNT_BLOCK_WEBHOOK_SECRET, @@ -158,7 +162,7 @@ export const triggerWebhook = async ({ try { await triggerRequest(webhook.url); } catch (err) { - log.error(`Webhook request to ${webhook.url} failed`, err); + log.error(`Webhook request to ${webhook.url} failed`, err.message); throw err; } }; diff --git a/src/routes/backoffice.ts b/src/routes/backoffice.ts index bbd598995d..2e6a94f1e6 100644 --- a/src/routes/backoffice.ts +++ b/src/routes/backoffice.ts @@ -611,8 +611,8 @@ export const processQueuedBooking = async ( if (id) { const findQueuedBooking = (queuedBooking) => queuedBooking.id === id; booking = bookings.find(findQueuedBooking); - // Standing orders are not removed until cancelled or expired. - if (!isStandingOrder) { + // Standing orders and scheduled transfers are not removed until cancelled or expired. + if (!isStandingOrder && !isScheduledTransfer) { _.remove(bookings, findQueuedBooking); } } else { @@ -716,8 +716,8 @@ export const processBusinessQueuedBooking = async ( if (id) { const findQueuedBooking = (queuedBooking) => queuedBooking.id === id; booking = bookings.find(findQueuedBooking); - // Standing orders are not removed until cancelled or expired. - if (!isStandingOrder) { + // Standing orders and scheduled transfers are not removed until cancelled or expired. + if (!isStandingOrder && !isScheduledTransfer) { _.remove(bookings, findQueuedBooking); } } else { diff --git a/src/routes/scheduledTransfers.ts b/src/routes/scheduledTransfers.ts index e042aeb549..8cd901da5a 100644 --- a/src/routes/scheduledTransfers.ts +++ b/src/routes/scheduledTransfers.ts @@ -17,6 +17,7 @@ import { processQueuedBooking, } from "./backoffice"; import { + Booking, EXECUTION_SCHEDULE, SCHEDULED_TRANSFER_STATUS, ScheduledTransfer, @@ -312,17 +313,47 @@ export const triggerScheduledTransferRequestHandler = async (req, res) => { scheduledTransferId ); - let booking; + let booking: Booking; if (!declinedReason) { - booking = (await person) - ? processQueuedBooking(accountId, scheduledTransferId, false, true) + booking = await (!!person + ? processQueuedBooking(person.id, scheduledTransferId, false, true) : processBusinessQueuedBooking( - accountId, + business.id, scheduledTransferId, false, true - ); + )); + } else { + const { scheduledTransfer } = await getScheduledTransfer( + accountId, + scheduledTransferId + ); + + const payload = { + id: scheduledTransferId, + status: "declined", + reference: "", + amount: { + value: scheduledTransfer.amount.value, + unit: "cents", + currency: "EUR", + }, + description: scheduledTransfer.description, + recipient_iban: scheduledTransfer.creditor_iban, + recipient_name: scheduledTransfer.creditor_name, + recipient_bic: scheduledTransfer.creditor_bic || "SOLARIS", + end_to_end_id: "END2ENDREJ", + schedule_id: scheduledTransferId, + batch_id: null, + created_at: moment().toISOString(), + rejection_reason: declinedReason, + }; + + await triggerWebhook({ + type: TransactionWebhookEvent.SEPA_CREDIT_TRANSACTION_DECLINED, + payload, + }); } // We need to update next execution date and call webhook in all cases, even when a scheduled transfer is declined @@ -368,7 +399,7 @@ const updateScheduledTransferNextExecutionDateAndStatus = async ( scheduledTransferId ) => { const { scheduledTransfer } = await getScheduledTransfer( - account, + account.id, scheduledTransferId ); @@ -523,6 +554,13 @@ const hasFundsToExecuteScheduledTransfer = async ( (so) => so.id === scheduledTransferId ); + if (!scheduledTransfer) { + log.error( + `hasFundsToExecuteScheduledTransfer: Scheduled transfer not found: ${scheduledTransferId}` + ); + return false; + } + return account.balance.value >= scheduledTransfer.amount.value; }; @@ -531,7 +569,7 @@ const triggerSepaScheduledTransactionWebhook = async ({ scheduledTransferId, }) => { const { scheduledTransfer } = await getScheduledTransfer( - person.account, + person.account.id, scheduledTransferId ); @@ -548,8 +586,8 @@ const triggerSepaScheduledTransactionWebhook = async ({ }; const getScheduledTransfer = async ( - accountId, - scheduledTransferId + accountId: string, + scheduledTransferId: string ): Promise<{ scheduledTransfer: ScheduledTransfer; }> => {