Skip to content

Commit

Permalink
Update nordigen URL
Browse files Browse the repository at this point in the history
  • Loading branch information
gkalabin committed Jan 26, 2025
1 parent 05361bf commit 30a1dc2
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default async function Page({
}
const token = await getOrCreateToken(db, bankId);
const institutionsResponse = await fetch(
`https://ob.nordigen.com/api/v2/institutions/?country=${country}`,
`https://bankaccountdata.gocardless.com/api/v2/institutions/?country=${country}`,
{
method: 'GET',
headers: {Authorization: `Bearer ${token.access}`},
Expand Down
27 changes: 15 additions & 12 deletions src/app/api/open-banking/nordigen/connect/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,21 @@ export async function GET(request: NextRequest): Promise<Response> {
}
const reference = uuidv4();
const token = await getOrCreateToken(db, bankId);
const response = await fetch(`https://ob.nordigen.com/api/v2/requisitions/`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token.access}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
redirect: redirectURI,
institution_id: institutionId,
reference,
}),
});
const response = await fetch(
`https://bankaccountdata.gocardless.com/api/v2/requisitions/`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${token.access}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
redirect: redirectURI,
institution_id: institutionId,
reference,
}),
}
);
if (Math.round(response.status / 100) * 100 !== 200) {
return new Response(
`Failed to create requisition (status ${
Expand Down
13 changes: 8 additions & 5 deletions src/lib/openbanking/nordigen/account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export async function fetchAccounts(
return [];
}
const response = await fetch(
`https://ob.nordigen.com/api/v2/requisitions/${requisition.requisitionId}/`,
`https://bankaccountdata.gocardless.com/api/v2/requisitions/${requisition.requisitionId}/`,
{
method: 'GET',
headers: {Authorization: `Bearer ${token.access}`},
Expand All @@ -23,10 +23,13 @@ export async function fetchAccounts(
// TODO: define the interface for the external API response.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const fetches = response.accounts.map((aid: any) =>
fetch(`https://ob.nordigen.com/api/v2/accounts/${aid}/details/`, {
method: 'GET',
headers: {Authorization: `Bearer ${token.access}`},
})
fetch(
`https://bankaccountdata.gocardless.com/api/v2/accounts/${aid}/details/`,
{
method: 'GET',
headers: {Authorization: `Bearer ${token.access}`},
}
)
.then(response => response.json())
.then(a => {
return {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/openbanking/nordigen/balance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export async function fetchBalance(
mapping: ExternalAccountMapping
): Promise<AccountBalance> {
const response = await fetch(
`https://ob.nordigen.com/api/v2/accounts/${mapping.externalAccountId}/balances/`,
`https://bankaccountdata.gocardless.com/api/v2/accounts/${mapping.externalAccountId}/balances/`,
{
method: 'GET',
headers: {Authorization: `Bearer ${token.access}`},
Expand Down
53 changes: 38 additions & 15 deletions src/lib/openbanking/nordigen/token.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {DB} from '@/lib/db';
import prisma from '@/lib/prisma';
import {NordigenRequisition, NordigenToken} from '@prisma/client';
import {addSeconds, isBefore} from 'date-fns';
import {z} from 'zod';

export async function getOrCreateToken(db: DB, bankId: number) {
const now = new Date();
Expand All @@ -20,16 +21,35 @@ export async function getOrCreateToken(db: DB, bankId: number) {
return refreshToken(db, token);
}

const tokenResponseSchema = z.object({
access: z.string(),
access_expires: z.number(),
refresh: z.string(),
refresh_expires: z.number(),
});

async function createToken(db: DB, bankId: number): Promise<NordigenToken> {
const r = await fetch(`https://ob.nordigen.com/api/v2/token/new/`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
secret_id: process.env.NORDIGEN_SECRET_ID,
secret_key: process.env.NORDIGEN_SECRET_KEY,
}),
});
const {access, access_expires, refresh, refresh_expires} = await r.json();
const r = await fetch(
`https://bankaccountdata.gocardless.com/api/v2/token/new/`,
{
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
secret_id: process.env.NORDIGEN_SECRET_ID,
secret_key: process.env.NORDIGEN_SECRET_KEY,
}),
}
);
if (r.status !== 200) {
const text = await r.text();
throw new Error(`Failed to create Nordigen token (${r.status}): ${text}`);
}
const rawJson = await r.json();
const parsed = tokenResponseSchema.safeParse(rawJson);
if (!parsed.success) {
throw new Error(`Invalid response from Nordigen: ${parsed.error.message}`);
}
const {access, access_expires, refresh, refresh_expires} = parsed.data;
const now = new Date();
const data = {
access,
Expand All @@ -53,11 +73,14 @@ export async function refreshToken(
db: DB,
token: NordigenToken
): Promise<NordigenToken> {
const fetched = await fetch(`https://ob.nordigen.com/api/v2/token/refresh/`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({refresh: token.refresh}),
});
const fetched = await fetch(
`https://bankaccountdata.gocardless.com/api/v2/token/refresh/`,
{
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({refresh: token.refresh}),
}
);
if (fetched.status !== 200) {
const [bank] = await db.bankFindMany({
where: {
Expand Down Expand Up @@ -97,7 +120,7 @@ export async function deleteToken(
`bankId mismatch: token bank id is ${token.bankId}, requisition bank id is ${requisition.bankId}`
);
const response = await fetch(
`https://ob.nordigen.com/api/v2/requisitions/${requisition.requisitionId}/`,
`https://bankaccountdata.gocardless.com/api/v2/requisitions/${requisition.requisitionId}/`,
{
method: 'DELETE',
headers: {Authorization: `Bearer ${token.access}`},
Expand Down
2 changes: 1 addition & 1 deletion src/lib/openbanking/nordigen/transactions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function fetchTransactions(
method: 'GET',
headers: {Authorization: `Bearer ${token.access}`},
};
const url = `https://ob.nordigen.com/api/v2/accounts/${mapping.externalAccountId}/transactions/`;
const url = `https://bankaccountdata.gocardless.com/api/v2/accounts/${mapping.externalAccountId}/transactions/`;
return fetch(url, init)
.then(r => r.json())
.then(x => decode({response: x, accountId: mapping.internalAccountId}));
Expand Down

0 comments on commit 30a1dc2

Please sign in to comment.