chore: gitignore dev_docs and remove from tracking (#7)

* chore: gitignore dev_docs and remove from tracking

Internal reference docs — not needed in the public repo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: skip env validation during builds when vars are absent

The build-time guard only checked for Docker placeholder sentinels
but not for completely absent vars (CI/Vercel builds). This caused
page collection to fail in environments without env vars.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: handle absent env vars in Supabase browser client during builds

The build-time guard only checked for Docker placeholder sentinels
but crashed on undefined when env vars are completely absent (CI).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: remove core import from @/extensions/ in describe route

Inline the DescriptionAnalysisInput/Result types instead of importing
from the ai-categorization extension. Core code must not import from
extensions directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-03-09 15:50:56 +01:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 42534a6328
commit d696e0282b
13 changed files with 33 additions and 4790 deletions
+3
View File
@@ -47,6 +47,9 @@ supabase/.temp/
# claude local settings
.claude/settings.local.json
# dev docs (internal reference, not published)
/dev_docs
# Extension registry (auto-generated but defaults are committed)
# Run `npm run setup:extensions` to regenerate after changing extensions.config.json
# The empty defaults in lib/extensions/_generated/ are committed so core compiles
+22 -2
View File
@@ -5,9 +5,29 @@ import { validateBody } from '@/lib/api/validate'
import { DescribeTransactionSchema } from '@/lib/api/schemas'
import { extensionRegistry } from '@/lib/extensions/registry'
import { findMatchingTemplates, type TemplateMatch } from '@/lib/bookkeeping/booking-templates'
import type { Transaction, EntityType } from '@/types'
import type { Transaction, EntityType, VatTreatment } from '@/types'
import type { Extension } from '@/lib/extensions/types'
import type { DescriptionAnalysisInput, DescriptionAnalysisResult } from '@/extensions/general/ai-categorization/lib/description-analyzer'
interface DescriptionAnalysisInput {
description: string
transactionAmount: number
transactionDate: string
transactionDescription: string
merchantName: string | null
currency: string
entityType: EntityType
}
interface DescriptionAnalysisResult {
debitAccount: string
creditAccount: string
vatTreatment: VatTreatment | null
category: string
confidence: number
reasoning: string
warnings: string[]
templateId: string | null
}
ensureInitialized()
-146
View File
@@ -1,146 +0,0 @@
# Arkivplan
**Mall for användare av erp-base**
Upprättad i enlighet med BFNAR 2013:2 punkt 8.3
---
## Instruktioner
Denna mall ska fyllas i av dig som kund och sparas som del av din systemdokumentation. Bokföringsnämndens allmänna råd (BFNAR 2013:2) kräver att varje bokföringsskyldig upprättar en arkivplan som beskriver vilken räkenskapsinformation som finns, var den förvaras, och vem som ansvarar för arkiveringen.
Fyll i de markerade fälten. Radera denna instruktionssektion innan du arkiverar dokumentet.
---
## 1. Företagsuppgifter
| Fält | Uppgift |
|---|---|
| Företagsnamn | [FÖRETAGSNAMN] |
| Organisationsnummer | [ORG-NR] |
| Företagsform | [ ] Enskild firma [ ] Aktiebolag |
| Räkenskapsår | [STARTMÅNAD] - [SLUTMÅNAD] |
| Bokföringsmetod | [ ] Faktureringsmetoden [ ] Kontantmetoden |
| Momsredovisningsperiod | [ ] Månadsvis [ ] Kvartalsvis [ ] Årsvis |
| Ansvarig för bokföringen | [NAMN, ROLL] |
## 2. Bokföringssystem
| Fält | Uppgift |
|---|---|
| Programvara | erp-base ([DOMÄN]) |
| Leverantör | [BOLAGSNAMN], org.nr [ORG-NR] |
| Lagringsplats | Molnbaserad tjänst, data lagrat inom EU (Supabase/AWS) |
| Åtkomst | Via webbläsare, inloggning med magic link (e-post) |
| Kontoplan | BAS 2025/2026 (konfigurerad i erp-base) |
## 3. Förteckning över räkenskapsinformation
Tabellen nedan anger vilken räkenskapsinformation som finns, i vilken form den förvaras, var, och arkiveringstid.
### 3.1 Löpande bokföring
| Räkenskapsinformation | Form | Lagringsplats | Arkiveringstid |
|---|---|---|---|
| Grundbokföring (registreringsordning) | Elektronisk | erp-base databas | 7 år efter räkenskapsårets utgång |
| Huvudbokföring (systematisk ordning) | Elektronisk | erp-base databas | 7 år efter räkenskapsårets utgång |
| Verifikationer (journalposter) | Elektronisk | erp-base databas | 7 år efter räkenskapsårets utgång |
### 3.2 Verifikationsunderlag
| Räkenskapsinformation | Form | Lagringsplats | Arkiveringstid | Anmärkning |
|---|---|---|---|---|
| Kundfakturor (utgående) | Elektronisk (PDF) | erp-base dokumentarkiv | 7 år | Genereras i erp-base |
| Leverantörsfakturor (inkommande) | Elektronisk (PDF/bild) | erp-base dokumentarkiv | 7 år | Uppladdade/skannade |
| Kvitton | Elektronisk (foto/PDF) | erp-base dokumentarkiv | 7 år | Fotograferade via appen |
| Bankutdrag/kontoutdrag | Elektronisk | erp-base via PSD2-koppling | 7 år | Synkroniserade via Enable Banking |
| Avtal och övriga underlag | [Elektronisk/Papper] | [erp-base / Fysisk pärm] | 7 år | [Ange var dessa förvaras] |
### 3.3 Årsbokslut och årsredovisning
| Räkenskapsinformation | Form | Lagringsplats | Arkiveringstid |
|---|---|---|---|
| Resultaträkning | Elektronisk | erp-base rapportmodul | 7 år |
| Balansräkning | Elektronisk | erp-base rapportmodul | 7 år |
| Årsredovisning (AB) / Årsbokslut (EF) | [Elektronisk/Papper] | [erp-base / Bolagsverket / Fysisk pärm] | 7 år (10 år rekommenderat) |
| NE-bilaga (EF) | Elektronisk | erp-base rapportmodul | 7 år |
| SIE-filer (export) | Elektronisk | [Ange var exporterade filer sparas] | 7 år |
### 3.4 Skattedeklarationer och momsrapporter
| Räkenskapsinformation | Form | Lagringsplats | Arkiveringstid |
|---|---|---|---|
| Momsdeklarationer | Elektronisk | erp-base rapportmodul + Skatteverket | 7 år |
| SRU-filer | Elektronisk | erp-base rapportmodul | 7 år |
| Inkomstdeklaration | [Elektronisk/Papper] | [Skatteverket / Egen kopia] | 7 år |
### 3.5 Systemdokumentation
| Dokument | Form | Lagringsplats | Arkiveringstid |
|---|---|---|---|
| Systemdokumentation | Elektronisk | [erp-base / Egen lagring] | Samma som den räkenskapsinformation den avser |
| Behandlingshistorik | Elektronisk | erp-base (automatiskt genererad) | Samma som den räkenskapsinformation den avser |
| Denna arkivplan | [Elektronisk/Papper] | [Ange lagringsplats] | Samma som den räkenskapsinformation den avser |
## 4. Pappersoriginal
4.1. Räkenskapsinformation som tagits emot i pappersform (kvitton, fakturor) och som har överförts till elektronisk form genom skanning eller fotografering ska bevaras i sin ursprungliga pappersform i minst tre (3) år efter utgången av det kalenderår då räkenskapsåret avslutades, i enlighet med 7 kap. 6 § BFL.
*Notering: Lagändring trädde i kraft 1 juli 2024 som möjliggör omedelbar förstöring av pappersoriginal efter överföring till elektronisk form, under förutsättning att överföringen sker på ett betryggande sätt och att inga uppgifter går förlorade. Se BFNAR 2024:1 och uppdaterad vägledning (2024-09-16) for detaljer om vilka krav som gäller vid sådan överföring.*
4.2. Dokument som tas emot elektroniskt (e-fakturor, digitala kvitton) arkiveras i elektronisk form. Inget pappersoriginal finns.
4.3. Förvaring av pappersoriginal:
- Plats: [ANGE PLATS, t.ex. kontor, bankfack]
- Ansvarig: [NAMN]
## 5. Säkerhetskopiering och redundans
5.1. erp-base sköter automatisk daglig säkerhetskopiering av databasen via Supabase-infrastrukturen.
5.2. Kunden rekommenderas att regelbundet exportera SIE4-filer och spara dessa på en separat lagringsplats som kompletterande säkerhetskopia.
Kundens kompletterande säkerhetskopiering:
- Frekvens: [t.ex. månadsvis, kvartalsvis]
- Lagringsplats: [t.ex. extern hårddisk, molnlagring]
- Ansvarig: [NAMN]
## 6. Åtkomst efter avslutad prenumeration
6.1. Vid uppsägning av erp-base-kontot har Kunden nittio (90) dagar att exportera all räkenskapsinformation i enlighet med Användarvillkoren avsnitt 8.
6.2. Räkenskapsinformation som omfattas av sjuårig arkiveringsskyldighet bevaras i skrivskyddat läge av erp-base, alternativt tillhandahålls som fullständig dataexport.
6.3. Det är Kundens ansvar att planera för dataportabilitet och säkerställa tillgång till räkenskapsinformation under hela arkiveringsperioden, oavsett om Tjänsten fortfarande används.
## 7. Geografisk lagring
7.1. All data i erp-base lagras inom EU/EES via Supabase (AWS-infrastruktur, region eu-central eller eu-west).
7.2. Viss behandling sker hos underbiträden i USA (se Personuppgiftsbiträdesavtalet, avsnitt 6.2) med stöd av EU-U.S. Data Privacy Framework eller standardavtalsklausuler.
7.3. I enlighet med 7 kap. 3a § BFL får räkenskapsinformation i elektronisk form förvaras i annat EU-land under förutsättning att detta har anmälts till Skatteverket.
**Anmälan till Skatteverket:** [ ] Har gjorts [ ] Behöver göras [ ] Ej tillämpligt (data lagras i Sverige)
## 8. Ansvar och kontakt
| Roll | Namn | Kontakt |
|---|---|---|
| Bokföringsansvarig | [NAMN] | [E-POST / TELEFON] |
| Extern redovisningskonsult (om tillämpligt) | [NAMN / BYRÅ] | [E-POST / TELEFON] |
| Revisor (om tillämpligt) | [NAMN / BYRÅ] | [E-POST / TELEFON] |
## 9. Uppdatering av arkivplanen
Denna arkivplan ska granskas och vid behov uppdateras minst en gång per räkenskapsår, samt vid byte av bokföringsprogram, ändring av företagsform, eller ändring av lagringsrutiner.
| Datum | Ändring | Utförd av |
|---|---|---|
| [DATUM] | Första version upprättad | [NAMN] |
| | | |
---
*Denna arkivplan uppfyller kraven i BFNAR 2013:2 punkt 8.3 och Exempel 8.1 i vägledningen. Anpassa innehållet till ditt företags specifika förhållanden. Platshållare markerade med hakparenteser ska fyllas i.*
-259
View File
@@ -1,259 +0,0 @@
# Systemdokumentation
**Mall for användare av erp-base**
Upprättad i enlighet med 5 kap. 11 § BFL och BFNAR 2013:2 kapitel 9
---
## Instruktioner
Varje bokföringsskyldig ska upprätta en systemdokumentation som beskriver bokföringssystemets organisation och uppbyggnad. Dokumentationen ska göra det möjligt att utan svårighet överblicka systemet och förstå hur bokföringen är organiserad (BFNAR 2013:2 punkt 9.1).
Denna mall är förifylld med uppgifter som gäller för erp-base. Avsnitt markerade med hakparenteser ska anpassas till ditt företags förhållanden. Radera denna instruktionssektion innan du arkiverar dokumentet.
Systemdokumentationen ska förvaras tillsammans med övrig räkenskapsinformation under hela arkiveringsperioden (7 år).
---
## 1. Företagsuppgifter
| Fält | Uppgift |
|---|---|
| Företagsnamn | [FÖRETAGSNAMN] |
| Organisationsnummer | [ORG-NR] |
| Företagsform | [ ] Enskild firma [ ] Aktiebolag |
| Räkenskapsår | [STARTMÅNAD] - [SLUTMÅNAD] |
| Tillämpat K-regelverk | [ ] K1 (förenklat årsbokslut, EF under 3 MSEK) [ ] K2 (årsredovisning, mindre AB) [ ] K3 (årsredovisning, huvudregelverk) |
## 2. Bokföringsprogram
| Fält | Uppgift |
|---|---|
| Programnamn | erp-base |
| Version | [ANGE VERSION, t.ex. 1.0] |
| Leverantör | [BOLAGSNAMN], org.nr [ORG-NR] |
| Webbplats | [DOMÄN] |
| Typ | Molnbaserad SaaS-tjänst (webbläsarbaserad) |
| Databasplattform | PostgreSQL via Supabase (AWS, EU-region) |
| Autentisering | Magic link via e-post (lösenordsfri) |
## 3. Kontoplan (BFNAR 2013:2 punkt 9.2)
3.1. Kontoplanen bygger på BAS-kontoplanen (BAS 2025/2026) utgiven av BAS-intressenternas Förening.
3.2. Kontona är indelade i klasser enligt BAS-standard:
| Klass | Beskrivning | Exempel på konton |
|---|---|---|
| 1 | Tillgångar | 1510 Kundfordringar, 1930 Företagskonto |
| 2 | Eget kapital och skulder | 2013 Egna uttag (EF), 2440 Leverantörsskulder, 2611-2631 Utgående moms, 2641 Ingående moms |
| 3 | Intäkter | 3001 Försäljning 25%, 3002 Försäljning 12%, 3003 Försäljning 6%, 3305 Exportförsäljning |
| 4-7 | Kostnader | Konfigureras efter verksamhet |
| 8 | Finansiella poster och skatt | Konfigureras efter verksamhet |
3.3. Kontoplanen kan ses och exporteras i erp-base under Inställningar > Kontoplan.
3.4. Företagsspecifika anpassningar av kontoplanen:
[BESKRIV EVENTUELLA TILLAGDA ELLER BORTTAGNA KONTON, t.ex. "Konto 4010 Inköp varor, 5010 Lokalhyra har lagts till. Inga standardkonton har tagits bort."]
## 4. Samlingsplan (BFNAR 2013:2 punkt 9.3-9.5)
Samlingsplanen beskriver hur bokföringen är organiserad i form av delsystem, grundbokföring och huvudbokföring.
### 4.1 Översikt
```
Affärshändelse
|
v
Verifikation skapas (manuellt eller automatiskt)
|
v
Journalpost registreras (grundbokföring, registreringsordning)
|
v
Konteras på BAS-konton (huvudbokföring, systematisk ordning)
|
v
Status: Utkast (draft)
|
v
Bekräftas av användaren
|
v
Status: Bokförd (posted), verifikationsnummer tilldelas
```
### 4.2 Grundbokföring (registreringsordning)
Samtliga affärshändelser registreras kronologiskt i erp-base journalen. Varje post innehåller:
- Verifikationsnummer (sekventiellt, tilldelat automatiskt vid bokföring)
- Registreringsdatum (datum då posten skapades i systemet)
- Bokföringsdatum (datum för affärshändelsen)
- Beskrivning
- Konteringsrader med konto, debet, kredit
Grundbokföringen kan visas under Bokföring > Journal i erp-base.
### 4.3 Huvudbokföring (systematisk ordning)
Huvudbokföringen presenterar affärshändelserna sorterade per konto. Varje konto visar ingående saldo, periodens transaktioner och utgående saldo.
Huvudbokföringen kan visas och exporteras under Rapporter > Huvudbok i erp-base.
### 4.4 Delsystem
Följande delsystem matar journalen:
| Delsystem | Beskrivning | Automatisk kontering |
|---|---|---|
| Kundfakturering | Utgående fakturor med per-rad momssats | Debet 1510, kredit 30xx + 26xx |
| Kundbetalningar | Inbetalningar mot fakturor | Debet 1930, kredit 1510 |
| Leverantörsfakturor | Inkommande fakturor, registrering och betalning | Debet kostnadskonto + 2641, kredit 2440 |
| Leverantörsbetalningar | Utbetalningar mot leverantörsfakturor | Debet 2440, kredit 1930 |
| Banktransaktioner | Synkroniserade via PSD2 (Enable Banking) | Kontering via kategoriseringsregler |
| Kvittohantering | OCR-bearbetade kvitton | Kontering efter granskning |
| Kreditnotor | Kreditering av utgående fakturor | Omvänd kontering av originalfaktura |
### 4.5 Avstämningsordning
Bankkonto 1930 avstäms via erp-base bankavstämningsmodul (4-stegs matchning: exakt belopp+datum, referensmatchning, datumintervall, fuzzy-matchning).
## 5. Verifikationer (BFNAR 2013:2 punkt 9.6-9.8)
### 5.1 Verifikationsnumrering
Verifikationsnummer tilldelas sekventiellt av systemet vid bokföring. Numreringen är unik per räkenskapsår och användare. Numren tilldelas via databas-RPC (concurrent-safe) och kan inte sättas manuellt.
En enda verifikationsnummerserie används: [A1, A2, A3, ...].
[OM FÖRETAGET ANVÄNDER FLERA SERIER, BESKRIV HÄR.]
### 5.2 Verifikationens innehåll
Varje verifikation i erp-base innehåller:
- Verifikationsnummer
- Bokföringsdatum (affärshändelsens datum)
- Registreringsdatum (datum då posten skapades)
- Beskrivning av affärshändelsen
- Konteringsrader (konto, debet, kredit)
- Referens till underlag (bifogat dokument, fakturanummer, etc.)
- Status (utkast / bokförd / reverserad)
- Vid rättelse: referens till reverserad/reverserande verifikation
### 5.3 Underlag
Underlag kopplas till verifikationer som bifogade dokument (PDF, bild). Dokumenten lagras i erp-base dokumentarkiv med SHA-256 checksumma for integritetskontroll.
Typer av underlag:
- Kundfakturor (genererade i systemet)
- Leverantörsfakturor (uppladdade)
- Kvitton (fotograferade/skannade)
- Bankbekräftelser (synkroniserade)
- Övriga avtal och dokument (uppladdade)
## 6. Rättelser (BFNAR 2013:2 punkt 9.9)
6.1. Bokförda verifikationer (status: posted) kan inte ändras eller raderas. Detta upprätthålls av databastriggrar i enlighet med bokföringslagens krav på oföränderlighet.
6.2. Rättelse sker genom stornobokning: en ny verifikation skapas som reverserar den felaktiga posten (byter debet/kredit). Den nya verifikationen länkas till originalet via referens (reverses_id / reversed_by_id).
6.3. Därefter skapas en ny korrekt verifikation vid behov.
6.4. Rättelseverifikationen innehåller uppgift om vilken verifikation som rättats, när rättelsen gjordes, och vem som utförde rättelsen (BFNAR 2013:2 punkt 2.17).
## 7. Periodavstängning
7.1. Räkenskapsperioder kan stängas (låsas) i erp-base. En låst period tillåter inte nya bokföringsposter. Periodlåsning upprätthålls av databastriggrar (enforce_period_lock).
7.2. Årsbokslut registreras som bokföringsposter i systemet.
## 8. Momshantering
8.1. Följande momssatser hanteras:
| Momssats | Beskrivning | Utgående moms-konto | Ingående moms-konto |
|---|---|---|---|
| 25 % | Standardsats | 2611 | 2641 |
| 12 % | Reducerad (livsmedel, hotell m.m.) | 2621 | 2641 |
| 6 % | Reducerad (böcker, tidningar, kultur m.m.) | 2631 | 2641 |
| 0 % (export) | Varuexport utanför EU | - | 2641 |
| 0 % (omvänd skattskyldighet) | Försäljning med omvänd skattskyldighet | - | 2641/2645 |
| Momsfri | Undantagna transaktioner | - | - |
*Notering: Livsmedel sänks till 6 % från 1 april 2026 t.o.m. 31 december 2027.*
8.2. Fakturor stödjer blandade momssatser (per fakturarad).
8.3. Momsrapport genereras under Rapporter > Momsdeklaration och mappas till Skatteverkets rutor.
## 9. Behandlingshistorik (BFNAR 2013:2 punkt 9.16)
9.1. erp-base registrerar automatiskt en behandlingshistorik som inkluderar:
- Registreringsdatum och tidpunkt for varje journalpost
- Tidpunkt för statusändring (utkast till bokförd)
- Vem som utförde bokningen (användar-ID kopplat till e-postadress)
- Stornobokningar med referens till originalverifikation
- Tidpunkt och utförare av periodlåsning
9.2. Behandlingshistoriken genereras automatiskt av systemet och kan inte ändras av användaren.
9.3. Behandlingshistoriken kan exporteras under Rapporter > Audit trail.
## 10. Import och export
| Funktion | Format | Beskrivning |
|---|---|---|
| SIE-import | SIE4 | Import av bokföringsdata från annat system |
| Bankfil-import | CSV (10 svenska bankformat) | Import av banktransaktioner |
| SIE-export | SIE4 | Export av komplett bokföring per räkenskapsår |
| Huvudbok | PDF/skärm | Export av huvudbok |
| Resultaträkning | PDF/skärm | Export av resultaträkning |
| Balansräkning | PDF/skärm | Export av balansräkning |
| Momsdeklaration | PDF/skärm | Underlag för momsdeklaration |
| SRU-export | SRU | Export for inkomstdeklaration |
| NE-bilaga | PDF/skärm | Bilaga till inkomstdeklaration (EF) |
| Verifikationsunderlag | PDF/bild | Nedladdning av bifogade dokument |
## 11. Integrationer
| Integration | Beskrivning | Dataflöde |
|---|---|---|
| Enable Banking (PSD2) | Bankkontosynkronisering | Bank -> erp-base (läsning av transaktioner och saldon) |
| Anthropic API | AI-kategorisering av transaktioner, OCR | erp-base -> Anthropic -> erp-base (transaktionsdata skickas, kategoriseringsförslag returneras) |
| OpenAI API | Embeddingar for likhetsmatchning | erp-base -> OpenAI -> erp-base (transaktionsbeskrivningar skickas, vektorer returneras) |
| Resend | E-postutskick | erp-base -> Resend -> mottagare (fakturor, påminnelser) |
[ANGE YTTERLIGARE INTEGRATIONER OM TILLÄMPLIGT]
## 12. Behörigheter och åtkomstkontroll
12.1. Varje konto i erp-base är isolerat via Row Level Security (RLS) i databasen. En användare kan enbart se och redigera sin egen data.
12.2. Nuvarande behörighetsstruktur:
| Roll | Beskrivning |
|---|---|
| Kontoägare | Full åtkomst till all data och funktionalitet |
[OM YTTERLIGARE ROLLER FINNS, BESKRIV HÄR]
12.3. Ansvarig for att tilldela och granska behörigheter: [NAMN]
## 13. Uppdatering av systemdokumentationen
Systemdokumentationen ska uppdateras vid:
- Byte eller uppgradering av bokföringsprogram
- Ändringar i kontoplan
- Ändringar i momshantering
- Nya integrationer eller delsystem
- Minst en gång per räkenskapsår
| Datum | Ändring | Utförd av |
|---|---|---|
| [DATUM] | Första version upprättad | [NAMN] |
| | | |
---
*Denna systemdokumentation uppfyller kraven i 5 kap. 11 § BFL och BFNAR 2013:2 kapitel 9 (punkterna 9.1-9.16) samt Exempel 9.1-9.4 i vägledningen. Anpassa innehållet till ditt företags specifika förhållanden.*
File diff suppressed because it is too large Load Diff
-467
View File
@@ -1,467 +0,0 @@
1/9
BAS Förenklat årsbokslut (K1) – Kontoplan 2018
Inga ändring eller tillägg har gjorts
jämfört med 2017.
BAS-konton Rad Underkonton Rad
1000 Immateriella
anläggningstillgångar
B1 1009 Årets avskrivningar på
immateriella
anläggningstillgångar
B1
BAS-konton Rad Underkonton Rad
1110 Byggnader B2 1119 Ackumulerade avskrivningar på
byggnader
B2
1130 Mark B3
1150 Markanläggningar B2 1159 Ackumulerade avskrivningar på
markanläggningar
B2
1180 Pågående nyanläggningar och
förskott för byggnader och
mark
B3
Rad Rad
1220 Maskiner och inventarier B4 1221 Årets nyanskaffning av
maskiner och inventarier
B4
1222 Årets ersättning för maskiner
och inventarier
B4
1229 Årets avskrivningar på maskiner
och inventarier
B4
1230 Byggnads- och markinventarier B4 1231 Årets nyanskaffning av
byggnads- och markinventarier
B4
1232 Årets ersättning för byggnadsoch markinventarier
B4
1239 Årets avskrivningar på
byggnads- och markinventarier
B4
1240 Bilar och andra transportmedel B4 1241 Årets nyanskaffning av bilar och
andra transportmedel
B4
1242 Årets ersättning för bilar och
andra transportmedel
B4
1249 Årets avskrivningar på bilar och
andra transportmedel
B4
Rad Rad
1300 Andelar B5
BAS-konton Rad Rad
1 Tillgångar
10 Immateriella anläggningstillgångar
11 Byggnader och mark
12 Maskiner och inventarier
14 Lager
BAS-konton Underkonton
Underkonton
13 Övriga anläggningstillgångar
BAS-konton Underkonton
Kontoplan_K1_2018_ver1
2/9
1400 Lager B6
Rad Rad
1500 Kundfordringar B7
Rad Rad
1600 Övriga fordringar B8
1650 Momsfordran B8
Rad
1700 Förskott till leverantörer B8
Rad
1910 Kassa B9
1920 PlusGiro B9
1930 Företagskonto/checkkonto/affär
skonto
B9
1940 Övriga bankkonton B9
1970 Särskilda bankkonton B9
Rad Rad
2010 Eget kapital, delägare 1 B10 2011 Egna varuuttag B10
2012 Avräkning för skatter och
avgifter (skattekonto)
B10
2013 Övriga egna uttag B10
2014 Uttag förmåner B10
2017 Egna insättningar B10
2019 Årets resultat, delägare 1 B10
2020 Eget kapital, delägare 2 B10 Se delägre 1
2030 Eget kapital, delägare 3 B10 Se delägre 1
2040 Eget kapital, delägare 4 B10 Se delägre 1
2050 Avsättning till expansionsfond U2
2060 Ersättningsfond U3
2070 Insatsemissioner,
avbetalningsplan på skog,
skogskonto,
upphovsmannakonto
U4
2080 Periodiseringsfonder U1 2083 Periodiseringsfond vid 2012 års
taxering
U1
BAS-konton
16 Övriga fordringar
BAS-konton Underkonton
BAS-konton Underkonton
Underkonton
2 EGET KAPITAL OCH SKULDER
19 Kassa och bank
17 Förskott till leverantörer
15 Kundfordringar
BAS-konton
BAS-konton Underkonton
20 Eget kapital
Underkonton
Kontoplan_K1_2018_ver1
3/9
2084 Periodiseringsfond vid 2013 års
taxering
U1
2085 Periodiseringsfond 2013 U1
2086 Periodiseringsfond 2014 U1
2087 Periodiseringsfond 2015 U1
2088 Periodiseringsfond 2016 U1
2089 Periodiseringsfond 2017 U1
2090 Utjämningskonto upplysningar
1-4
Rad Rad
2330 Checkräkningskredit B13
2350 Skulder till kreditinstitut B13
2390 Övriga låneskulder B13
Rad Rad
2440 Leverantörsskulder B15
Rad Rad
2610 Utgående moms, 25 % B14 2611 Utgående moms på försäljning
inom Sverige, 25 %
B14
2612 Utgående moms på egna uttag,
25 %
B14
2613 Utgående moms för uthyrning,
25 %
B14
2614 Utgående moms omvänd
skattskyldighet, 25 %
B14
2615 Utgående moms import av
varor, 25 %
B14
2618 Vilande utgående moms, 25 % B14
2620 Utgående moms, 12 % B14 2621 Utgående moms på försäljning
inom Sverige, 12 %
B14
2622 Utgående moms på egna uttag,
12 %
B14
2623 Utgående moms för uthyrning,
12 %
B14
2624 Utgående moms omvänd
skattskyldighet, 12 %
B14
2625 Utgående moms import av
varor, 12 %
B14
2628 Vilande utgående moms, 12 % B14
2630 Utgående moms, 6 % B14 2631 Utgående moms på försäljning
inom Sverige, 6 %
B14
2632 Utgående moms på egna uttag,
6 %
B14
BAS-konton Underkonton
23 Låneskulder
Underkonton
BAS-konton Underkonton
24 Skulder till leverantörer
26 Moms och särskilda punktskatter
BAS-konton
Kontoplan_K1_2018_ver1
4/9
2633 Utgående moms för uthyrning,
6 %
B14
2634 Utgående moms omvänd
skattskyldighet, 6 %
B14
2635 Utgående moms import av
varor, 6 %
B14
2638 Vilande utgående moms, 6 % B14
2640 Ingående moms B14 2641 Debiterad ingående moms B14
2642 Debiterad ingående moms i
anslutning till frivillig
skattskyldighet
B14
2645 Beräknad ingående moms på
förvärv från utlandet
B14
2646 Ingående moms på uthyrning B14
2648 Vilande ingående moms B14
2649 Ingående moms, blandad
verksamhet
B14
2650 Redovisningskonto för moms B14 B14
2660 Särskilda punktskatter B14 B14
Rad Rad
2710 Personalskatt B14
2730 Lagstadgade/avtalade sociala
avgifter och särskild löneskatt
B14
Rad Rad
2900 Övriga skulder B16
Rad Rad
3000 Försäljning och utfört arbete
samt övriga momspliktiga
intäkter
R1
3100 Momsfria intäkter R2
3200 Bil- och bostadsförmån m.m. R3
Rad Rad
3500 Fakturerade kostnader R1
Rad Rad
3700 Lämnade rabatter, bonus etc. R1/R2
Underkonton
35 Fakturerade kostnader
37 Intäktskorrigeringar
Underkonton
BAS-konton
Underkonton
3 RÖRELSENS INKOMSTER/INTÄKTER
30-34 Huvudintäkter
BAS-konton Underkonton
BAS-konton
29 Övriga skulder
27 Personalens skatter, avgifter och löneavdrag
BAS-konton Underkonton
BAS-konton
Kontoplan_K1_2018_ver1
5/9
Rad Rad
3900 Övriga rörelseintäkter R1/R2
3970 Vinst vid avyttring av
immateriella och materiella
anläggningstillgångar
R2
3980 Erhållna bidrag R2
Rad Rad
4000 Varor R5
Rad Rad
4600 Legoarbeten och
underentreprenader
R5
Rad Rad
4700 Erhållna rabatter, bonus etc. R6
Rad Rad
4900 Förändring av lager R5
Rad Rad
5000 Lokalkostnader R6
Rad Rad
5100 Fastighetskostnader R6
Rad Rad
5200 Hyra av anläggningstillgångar R6
Underkonton
Underkonton
BAS-konton Underkonton
39 Övriga rörelseintäkter
Underkonton
BAS-konton
4 UTGIFTER/KOSTNADER FÖR VAROR, MATERIAL OCH VISSA
KÖPTA TJÄNSTER
Underkonton
47 Reduktion av inköpspriser
49 Förändring av lager
BAS-konton Underkonton
Underkonton
BAS-konton Underkonton
46 Legoarbeten, underentreprenader
BAS-konton
BAS-konton
BAS-konton
40-45 Inköp av varor och material
BAS-konton
5-6 ÖVRIGA EXTERNA RÖRELSEUTGIFTER/KOSTNADER
50 Lokalkostnader
51 Fastighetskostnader
52 Hyra av anläggningstillgångar
54 Förbrukningsinventarier och förbrukningsmaterial
Kontoplan_K1_2018_ver1
6/9
Rad Rad
5400 Förbrukningsinventarier och
förbrukningsmaterial
R6
Rad Rad
5500 Reparation och underhåll R6
Rad Rad
5600 Kostnader för transportmedel R6
5610 Personbilskostnader R6 5611 Drivmedel för personbilar R6
5612 Försäkring och skatt för
personbilar
R6
5613 Reparation och underhåll av
personbilar
R6
5615 Leasing av personbilar R6
5618 Schablonmässig milkostnad
privat personbil
R6
5619 Övriga personbilskostnader R6
5620 Lastbilskostnader R6
Rad Rad
5700 Frakter och transporter R6
Rad Rad
5800 Resekostnader R6
Rad Rad
5900 Reklam och PR R6
Rad Rad
6000 Övriga försäljningskostnader
R6
R6 R6
6070 Representation R6 R6 6071 Representation, avdragsgill
6072 Representation, ej avdragsgill R6
+
NE
sid.
2
BAS-konton
BAS-konton
Underkonton
55 Reparation och underhåll
56 Kostnader för transportmedel
BAS-konton Underkonton
Underkonton
Underkonton
BAS-konton Underkonton
57 Frakter och transporter
58 Resekostnader
59 Reklam och PR
60 Övriga försäljningskostnader
BAS-konton
Underkonton
BAS-konton
Underkonton
BAS-konton
Kontoplan_K1_2018_ver1
7/9
Rad Rad
6100 Kontorsmateriel och trycksaker R6
Rad Rad
6200 Tele och post R6
Rad Rad
6300 Företagsförsäkringar och
övriga riskkostnader
R6
6310 Företagsförsäkringar R6
Rad Rad
6500 Övriga externa tjänster R6
Rad Rad
6800 Inhyrd personal R6
Rad Rad
6900 Övriga kostnader R6
6980 Föreningsavgifter R6
Rad Rad
7000 Löner till anställda R7
Rad Rad
7300 Kostnadsersättningar och
förmåner
R7
Rad Rad
7400 Pensionskostnader R7
74 Pensionskostnader
61 Kontorsmateriel och trycksaker
62 Tele och post
BAS-konton Underkonton
BAS-konton Underkonton
63 Företagsförsäkringar och övriga riskkostnader
Underkonton
70 Löner till anställda
7 UTGIFTER/KOSTNADER FÖR PERSONAL, AVSKRIVNINGAR
BAS-konton
68 Inhyrd personal
69 Övriga kostnader
BAS-konton Underkonton
BAS-konton Underkonton
BAS-konton Underkonton
65 Övriga externa tjänster
BAS-konton Underkonton
BAS-konton Underkonton
73 Kostnadsersättningar och förmåner
BAS-konton Underkonton
Kontoplan_K1_2018_ver1
8/9
Rad Rad
7500 Sociala och andra avgifter
enligt lag och avtal
R7
Rad Rad
7600 Övriga personalkostnader R7 7631 Personalrepresentation,
avdragsgill
R7
7632 Personalrepresentation, ej
avdragsgill
R7
+
NE
sid.
2
Rad Rad
7700 Nedskrivningar R9
alt.
R10
Rad Rad
7810 Avskrivningar på immateriella
anläggningstillgångar
R10
7820 Avskrivningar på byggnader
och markanläggningar
R9
7830 Avskrivningar på maskiner och
inventarier
R10
Rad Rad
7970 Förlust vid avyttring av
immateriella och materiella
anläggningstillgångar
R6
7980 Ersättningsfonder R9/
10
Rad Rad
8 FINANSIELLA OCH ANDRA INKOMSTER/INTÄKTER OCH
UTGIFTER/ KOSTNADER
Underkonton
BAS-konton Underkonton
79 Övriga rörelsekostnader
77 Nedskrivningar och återföring av nedskrivningar
76 Övriga personalkostnader
78 Avskrivningar
83 Övriga ränteintäkter och liknande resultatposter
BAS-konton Underkonton
BAS-konton Underkonton
75 Sociala och andra avgifter enligt lag och avtal
BAS-konton
BAS-konton Underkonton
BAS-konton Underkonton
Kontoplan_K1_2018_ver1
9/9
8310 Ränteintäkter och utdelningar R4 8314 Skattefria ränteintäkter R4
+
NE
sid.
2
8330 Valutakursdifferenser på
fordringar och placeringar
R4
Rad Rad
8410 Räntekostnader för skulder R8
8430 Valutakursdifferenser på
skulder R8
Rad Rad
8990 Resultat R11 R11 8999 Årets resultat R11
84 Räntekostnader och liknande
BAS-konton Underkonton
BAS-konton Underkonton
88 Bokslutsdispositioner
89 Årets resultat
Kontoplan_K1_2018_ver1
-940
View File
@@ -1,940 +0,0 @@
API reference
Scroll down for example requests and responses.
Base URLs:
https://api.enablebanking.com
https://api.tilisy.com (deprecated)
Flow diagrams
Account information flow
AIS flow diagram
Application (i.e. API client) makes GET /aspsps request to obtain a list of available ASPSPs along with necessary meta data. Alternatively, the list of ASPSP can be displayed using the ASPSP selection UI widget.
List of available ASPSPs is returned and displayed to a PSU.
The PSU selects desired ASPSP and an application makes POST /auth request, specifying desired ASPSP and providing information about needed access rights.
Enable Banking starts authorisation in a desired ASPSP.
Enable Banking responds to the client with a redirect url to a Enable Banking page, where PSU needs to be redirected.
The PSU is redirected to the Enable Banking page.
After the PSU is redirected, Enable Banking does interactions with an ASPSP necessary to get authorised access to the PSU's account.
These actions are ASPSP-specific and may be different depending of the authentication method (which may be specified at step 3).
The PSU is redirected to the callback URL provided by the application with additional parameters added in its query string.
If the authorisation went successfully then query string from step 8 will contain code parameter, which needs to be sent in POST /sessions request.
The Enable Banking API will respond with created session_id along with a list of accessible accounts and their details.
Note that some of the information returned in that call is shown only once.
After successfull response to POST /sessions request the application can start making requests to Enable Banking API to fetch information about session, account balances and transactions.
Possible query parameters returned in the step 8 (parameters follow The OAuth 2.0 Authorization Framework (opens new window)):
code — authorisation code.
state — same as state, provided in the step 1.
error — error code
error_description — human-readable error description
Possible error descriptions:
Denied data sharing consent — user cancelled authentication before accepting data sharing consent (error code is access_denied)
Cancelled by user — user cancelled authorisation of access to account information (error code is access_denied). There are also arbitrary error descriptions possible, which are coming from ASPSPs.
Payment initiation flow
PIS flow diagram
Application (i.e. API client) makes GET /aspsps request to obtain a list of available ASPSPs along with necessary meta data. Alternatively, the list of ASPSP can be displayed using the ASPSP selection UI widget.
List of available ASPSPs is returned and displayed to a PSU.
The PSU selects desired ASPSP and the application makes POST /payments request, specifying a desired ASPSP, providing details for the payment to be initiated and other details such as callback URL, preferred authentication method, etc.
Enable Banking responds to the application with an ID assigned to the payment and a URL of the page, where PSU needs to be redirected.
The PSU is redirected to the Enable Banking page, where they shall review payment details and terms of the service.
After the PSU accepted term of service, Enable Banking does interactions with the ASPSP necessary to initiate the payment and complete its authorisation.
These actions are ASPSP-specific and may be different depending of the authentication method (which may be specified at step 3).
The PSU is redirected to the callback URL provided by the application with additional parameters added in its query string.
Possible query parameters returned in the step 7:
state — same as state, provided in the step 1.
error — error code
error_description — human-readable error description
Possible error descriptions:
Cancelled by user — user cancelled authorisation of the payment (error code is access_denied). There are also arbitrary error descriptions possible, which are coming from ASPSPs.
Authentication
In order to get access to this API you need to:
Generate a private RSA key and a self-signed certificate;
Upload the certificate to enablebanking.com and get application ID;
Construct JWT with the data described below and signed with your private key;
Send the JWT in the Authorization header.
Private key and certificate generation
Generating private RSA key
openssl genrsa -out private.key 4096
OpenSSL CLI can be used for generation of a private key and self-signed certificate.
Make sure you keep the private key in secret (e.g. don't expose it to client, share with anyone nor embed into mobile or other apps intalled to user devices).
Generating self-signed certificate
openssl req -new -x509 -days 365 -key private.key -out public.crt -subj "/C=FI/ST=Uusima/L=Helsinki/O=ExampleOrganisation/CN=www.bigorg.com"
You should replace values under -subj with appropriate values.
Alternatively you can use the private key generated in your browser when registering a new application. Just choose Generate in the browser (using SubtleCrypto) and export private key option when registering an application, and the private key will be exported after the application has been registered (the corresponding certificate will be used for the app registration).
Certificate upload and application registration
To register a new application you need to have an account on the Enable Banking Control Panel (opens new window). You can create one by visiting https://enablebanking.com/sign-in/ (opens new window)and entering your email address (a one-time authentication link will be sent to your email address).
In the app registration form (opens new window)you will be asked to upload the public certificate that you created for the application being registered.
An application can be registered to either PRODUCTION (aka "live") or SANDBOX (aka "simulation") environment. Applications can not be transferred from the sandbox to the production environment and vice versa.
Applications registered into the sandbox environment are activated automatically. Applications registered to the production environment at first appear as pending and will be activated either after contractual formalities for the use of the API are cleared or after you whitelist your own accounts. For more information please contact us at info@enablebanking.com.
Application registration API
You can also register an application sending POST request containing JSON with the application details and public certificate to https://enablebanking.com/api/applications endpoint.
The JSON body for the endpoint is to include the following fields:
"certificate": Content of the certificate or public key of the application (always required)
"environment": Environment (SANDBOX or PRODUCTION) in which the application will operate (always required)
"name": Name of the application being registered (always required)
"redirect_urls": List of allowed redirect URLs for the application (always required)
"description": Description of the application being registered (required when the environment field is set to PRODUCTION)
"gdpr_email": Email address for data protection matters (required when the environment field is set to PRODUCTION)
"privacy_url": URL of the application's privacy policy (required when the environment field is set to PRODUCTION)
"terms_url": URL of the application's terms of service (required when the environment field is set to PRODUCTION)
App registration example using curl
curl -X POST -H "Authorization: Bearer YOUR-JWT-ON-ENABLEBANKING-COM" \
-H "Content-Type: application/json" \
-d "{\"name\":\"My app\",\"certificate\":\"$(cat public.crt | tr '\n' '|' | sed 's/|/\\n/g')\",\"environment\":\"SANDBOX\",\"redirect_urls\":[\"https://example.org/\"]}" \
https://enablebanking.com/api/applications
In response to the app registration request, you will receive an ID assigned to your application, which is to be used when forming JTW token.
Example response
{
"app_id": "cf589be3-3755-465b-a8df-a90a16a31403"
}
JWT format and signature
JWT example
eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJSUzI1NiIsICJraWQiOiAiY2Y1ODliZTMtMzc1NS00NjViLWE4ZGYtYTkwYTE2YTMxNDAzIn0.eyJpc3MiOiAiZW5hYmxlYmFua2luZy5jb20iLCAiYXVkIjogImFwaS50aWxpc3kuY29tIiwgImlhdCI6IDE2MDE0NTY3NjgsICJleHAiOiAxNjAxNTQzMTY4fQ.daO3ENSYIA3ud7Ay7uGQ0xxqq9r4_WLcM5SbrN_6_fqsFZXFdoGQA5nKiyP8Ot4nWdYcZvaNWxEAOIodUFndOP8pjihF9-rMXuNGEjde1cq2WjYzKwiIeodUej8okDWdB--szcgurzGMd8RRMjqr951PWqnXS-PbrRsavDHp8l2q4YBjh2m80nRruKnQCAn0dtm4A5G9rZaEowo9z-c8HJU101jKddyOpHhl9UvxVrERzHtyO4LdidiP4rP1hmaVMWybSbcIMI_h30qjqWP21kYRH9ENITTttbf0uZIa8s74jKYxNIdiiDyRaq9WjoPolrHI_ZxcMjp8mmCKX-N-1w
You can read more about JWT here: https://jwt.io/introduction/
JWT header must contain following fields:
"typ": "JWT" (always the same)
"alg": "RS256" (always the same, only RS256 is supported)
"kid": "<application_id>" (application id obtained after certificate upload)
JWT body must contain following fields:
"iss": "enablebanking.com" (always the same)
"aud": "api.enablebanking.com" (always the same, formerly had to be "api.tilisy.com", which is now deprecated)
"iat": 1601456603 (timestamp when the token is being created)
"exp": 1601460262 (timestamp when the token expires)
Maximum allowed time-to-live for token is 86400 seconds (24 hours). Tokens created with longer TTL are not accepted by the API.
Check code samples in C#, Node.js, PHP, Python and Ruby in our GitHub repository(opens new window)
https://github.com/enablebanking/enablebanking-api-samples
Send request with JWT provided
Example request
GET https://api.enablebanking.com/application HTTP/1.1
Host: api.enablebanking.com
Authorization: Bearer eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJSUzI1NiIsICJraWQiOiAiY2Y1ODliZTMtMzc1NS00NjViLWE4ZGYtYTkwYTE2YTMxNDAzIn0.eyJpc3MiOiAiZW5hYmxlYmFua2luZy5jb20iLCAiYXVkIjogImFwaS5lbmFibGViYW5raW5nLmNvbSIsICJpYXQiOiAxNjAxNDU2NzY4LCAiZXhwIjogMTYwMTU0MzE2OH0.daO3ENSYIA3ud7Ay7uGQ0xxqq9r4_WLcM5SbrN_6_fqsFZXFdoGQA5nKiyP8Ot4nWdYcZvaNWxEAOIodUFndOP8pjihF9-rMXuNGEjde1cq2WjYzKwiIeodUej8okDWdB--szcgurzGMd8RRMjqr951PWqnXS-PbrRsavDHp8l2q4YBjh2m80nRruKnQCAn0dtm4A5G9rZaEowo9z-c8HJU101jKddyOpHhl9UvxVrERzHtyO4LdidiP4rP1hmaVMWybSbcIMI_h30qjqWP21kYRH9ENITTttbf0uZIa8s74jKYxNIdiiDyRaq9WjoPolrHI_ZxcMjp8mmCKX-N-1w
In order to authenticate your application, you need to provide JWT in the "Authorization" header of your request.
User sessions
The following operations can be used to initiate and complete end-user authorization for access to account information. The other operations provide possibility to retrieve session status and other details and to close (delete) a session.
Start user authorization
POST /auth
Start authorization by getting a redirect link and redirecting a PSU to that link
Parameters
Name In Type Required Description
body body StartAuthorizationRequest true none
Authentication
To perform this operation, API requests must include Authorization header containing JWT calculated using private RSA key of the client application making the request. See jwtAuthentication.
Example request
POST https://api.enablebanking.com/auth HTTP/1.1
Host: api.enablebanking.com
Content-Type: application/json
Accept: application/json
Authorization: Bearer <JWT>
Request body
{
"access": {
"valid_until": "2019-08-24T14:15:22Z"
},
"aspsp": {
"name": "Nordea",
"country": "FI"
},
"state": "3a57e2d3-2e0c-4336-af9b-7fa94f0606a3",
"redirect_url": "http://example.com",
"psu_type": "business",
"auth_method": "methodName",
"credentials": {
"userId": "MyUsername"
},
"credentials_autosubmit": true,
"language": "fi",
"psu_id": "string"
}
Responses
Status Description Schema
200 Successful Response StartAuthorizationResponse
400 Bad Request ErrorResponse
401 Unauthorized ErrorResponse
403 Forbidden ErrorResponse
404 Not Found ErrorResponse
408 Request Timeout ErrorResponse
422 Unprocessable Entity ErrorResponse
429 Too Many Requests ErrorResponse
500 Internal Server Error ErrorResponse
Example responses
200 Response
{
"url": "https://tilisy.enablebanking.com/welcome?sessionid=73100c65-c54d-46a1-87d1-aa3effde435a",
"authorization_id": "73100c65-c54d-46a1-87d1-aa3effde435a",
"psu_id_hash": "string"
}
Authorize user session
POST /sessions
Authorize user session by provided authorization code
Parameters
Name In Type Required Description
body body AuthorizeSessionRequest true none
Authentication
To perform this operation, API requests must include Authorization header containing JWT calculated using private RSA key of the client application making the request. See jwtAuthentication.
Example request
POST https://api.enablebanking.com/sessions HTTP/1.1
Host: api.enablebanking.com
Content-Type: application/json
Accept: application/json
Authorization: Bearer <JWT>
Request body
{
"code": "string"
}
Responses
Status Description Schema
200 Successful Response AuthorizeSessionResponse
400 Bad Request ErrorResponse
401 Unauthorized ErrorResponse
403 Forbidden ErrorResponse
404 Not Found ErrorResponse
408 Request Timeout ErrorResponse
422 Unprocessable Entity ErrorResponse
429 Too Many Requests ErrorResponse
500 Internal Server Error ErrorResponse
Example responses
200 Response
{
"session_id": "string",
"accounts": [
{
"account_id": {
"iban": "FI0455231152453547"
},
"all_account_ids": [
{
"identification": "123456",
"scheme_name": "BBAN"
}
],
"account_servicer": {
"bic_fi": "string",
"clearing_system_member_id": {
"clearing_system_id": "NZNCC",
"member_id": 20368
},
"name": "string"
},
"name": "string",
"details": "string",
"usage": "PRIV",
"cash_account_type": "CACC",
"product": "string",
"currency": "string",
"psu_status": "string",
"credit_limit": {
"currency": "EUR",
"amount": "1.23"
},
"legal_age": true,
"postal_address": {
"address_type": "Business",
"department": "Department of resources",
"sub_department": "Sub Department of resources",
"street_name": "Vasavagen",
"building_number": "4",
"post_code": "00123",
"town_name": "Helsinki",
"country_sub_division": "Uusimaa",
"country": "FI",
"address_line": [
"Mr Asko Teirila PO Box 511",
"39140 AKDENMAA FINLAND"
]
},
"uid": "07cc67f4-45d6-494b-adac-09b5cbc7e2b5",
"identification_hash": "WwpbCiJhY2NvdW50IiwKImFjY291bnRfaWQiLAoiaWJhbiIKXQpd.E8GzhnnsFC7K+4e3YMYYKpyM83Zx6toXrjgcvPP/Lqc=",
"identification_hashes": [
"WwpbCiJhY2NvdW50IiwKImFjY291bnRfaWQiLAoiaWJhbiIKXQpd.E8GzhnnsFC7K+4e3YMYYKpyM83Zx6toXrjgcvPP/Lqc=",
"WwpbCiJhc3BzcF9uYW1lIgpdLApbCiJhc3BzcF9jb3VudHJ5IgpdLApbCiJhY2NvdW50IiwKImFjY291bnRfaWQiLAoib3RoZXIiLAoic2NoZW1lX25hbWUiCl0sClsKImFjY291bnQiLAoiYWNjb3VudF9pZCIsCiJvdGhlciIsCiJpZGVudGlmaWNhdGlvbiIKXQpd.AOm/TULGPD4a4GdcWhR9xh0GPlPUZuB2O1S9SYFWEz0="
]
}
],
"aspsp": {
"name": "Nordea",
"country": "FI"
},
"psu_type": "business",
"access": {
"valid_until": "2019-08-24T14:15:22Z"
}
}
Get session data
GET /sessions/{session_id}
Get session data by session ID
Parameters
Name In Type Required Description
session_id path string(uuid) true Previously authorized session ID
Authentication
To perform this operation, API requests must include Authorization header containing JWT calculated using private RSA key of the client application making the request. See jwtAuthentication.
Example request
GET https://api.enablebanking.com/sessions/{session_id} HTTP/1.1
Host: api.enablebanking.com
Accept: application/json
Authorization: Bearer <JWT>
Responses
Status Description Schema
200 Successful Response GetSessionResponse
400 Bad Request ErrorResponse
401 Unauthorized ErrorResponse
403 Forbidden ErrorResponse
404 Not Found ErrorResponse
408 Request Timeout ErrorResponse
422 Unprocessable Entity ErrorResponse
429 Too Many Requests ErrorResponse
500 Internal Server Error ErrorResponse
Example responses
200 Response
{
"access": {
"valid_until": "2020-12-01T12:00:00.000000+00:00"
},
"accounts": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
],
"accounts_data": [
{
"identification_hash": "WwpbCiJhY2NvdW50IiwKImFjY291bnRfaWQiLAoiaWJhbiIKXQpd.E8GzhnnsFC7K+4e3YMYYKpyM83Zx6toXrjgcvPP/Lqc=",
"uid": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}
],
"aspsp": {
"country": "FI",
"name": "Nordea"
},
"authorized": "2020-12-01T12:00:00.000000+00:00",
"created": "2020-12-01T12:00:00.000000+00:00",
"psu_type": "business",
"status": "AUTHORIZED"
}
Delete session
DELETE /sessions/{session_id}
Delete session by session ID. PSU's bank consent will be closed automatically if possible
Parameters
Name In Type Required Description
session_id path string(uuid) true Previously authorized session ID
Psu-Ip-Address header string false PSU IP address
Psu-User-Agent header string false PSU browser User Agent
Psu-Referer header string false PSU Referer
Psu-Accept header string false PSU accept header
Psu-Accept-Charset header string false PSU charset
Psu-Accept-Encoding header string false PSU accept encoding
Psu-Accept-language header string false PSU accept language
Psu-Geo-Location header string false Comma separated latitude and longitude coordinates without spaces
Authentication
To perform this operation, API requests must include Authorization header containing JWT calculated using private RSA key of the client application making the request. See jwtAuthentication.
Example request
DELETE https://api.enablebanking.com/sessions/{session_id} HTTP/1.1
Host: api.enablebanking.com
Accept: application/json
Psu-Ip-Address: string
Psu-User-Agent: string
Psu-Referer: string
Psu-Accept: string
Psu-Accept-Charset: string
Psu-Accept-Encoding: string
Psu-Accept-language: string
Psu-Geo-Location: -1.2345,6.789
Authorization: Bearer <JWT>
Responses
Status Description Schema
200 Successful Response SuccessResponse
400 Bad Request ErrorResponse
401 Unauthorized ErrorResponse
403 Forbidden ErrorResponse
404 Not Found ErrorResponse
408 Request Timeout ErrorResponse
422 Unprocessable Entity ErrorResponse
429 Too Many Requests ErrorResponse
500 Internal Server Error ErrorResponse
Example responses
200 Response
{
"message": "OK"
}
Accounts data
Get account details
GET /accounts/{account_id}/details
Fetching account details from ASPSP for an account by its ID
Parameters
Name In Type Required Description
account_id path string(uuid) true Account ID
Psu-Ip-Address header string false PSU IP address
Psu-User-Agent header string false PSU browser User Agent
Psu-Referer header string false PSU Referer
Psu-Accept header string false PSU accept header
Psu-Accept-Charset header string false PSU charset
Psu-Accept-Encoding header string false PSU accept encoding
Psu-Accept-language header string false PSU accept language
Psu-Geo-Location header string false Comma separated latitude and longitude coordinates without spaces
Authentication
To perform this operation, API requests must include Authorization header containing JWT calculated using private RSA key of the client application making the request. See jwtAuthentication.
Example request
GET https://api.enablebanking.com/accounts/{account_id}/details HTTP/1.1
Host: api.enablebanking.com
Accept: application/json
Psu-Ip-Address: string
Psu-User-Agent: string
Psu-Referer: string
Psu-Accept: string
Psu-Accept-Charset: string
Psu-Accept-Encoding: string
Psu-Accept-language: string
Psu-Geo-Location: -1.2345,6.789
Authorization: Bearer <JWT>
Responses
Status Description Schema
200 Successful Response AccountResource
400 Bad Request ErrorResponse
401 Unauthorized ErrorResponse
403 Forbidden ErrorResponse
404 Not Found ErrorResponse
408 Request Timeout ErrorResponse
422 Unprocessable Entity ErrorResponse
429 Too Many Requests ErrorResponse
500 Internal Server Error ErrorResponse
Example responses
200 Response
{
"account_id": {
"iban": "FI0455231152453547"
},
"all_account_ids": [
{
"identification": "123456",
"scheme_name": "BBAN"
}
],
"account_servicer": {
"bic_fi": "string",
"clearing_system_member_id": {
"clearing_system_id": "NZNCC",
"member_id": 20368
},
"name": "string"
},
"name": "string",
"details": "string",
"usage": "PRIV",
"cash_account_type": "CACC",
"product": "string",
"currency": "string",
"psu_status": "string",
"credit_limit": {
"currency": "EUR",
"amount": "1.23"
},
"legal_age": true,
"postal_address": {
"address_type": "Business",
"department": "Department of resources",
"sub_department": "Sub Department of resources",
"street_name": "Vasavagen",
"building_number": "4",
"post_code": "00123",
"town_name": "Helsinki",
"country_sub_division": "Uusimaa",
"country": "FI",
"address_line": [
"Mr Asko Teirila PO Box 511",
"39140 AKDENMAA FINLAND"
]
},
"uid": "07cc67f4-45d6-494b-adac-09b5cbc7e2b5",
"identification_hash": "WwpbCiJhY2NvdW50IiwKImFjY291bnRfaWQiLAoiaWJhbiIKXQpd.E8GzhnnsFC7K+4e3YMYYKpyM83Zx6toXrjgcvPP/Lqc=",
"identification_hashes": [
"WwpbCiJhY2NvdW50IiwKImFjY291bnRfaWQiLAoiaWJhbiIKXQpd.E8GzhnnsFC7K+4e3YMYYKpyM83Zx6toXrjgcvPP/Lqc=",
"WwpbCiJhc3BzcF9uYW1lIgpdLApbCiJhc3BzcF9jb3VudHJ5IgpdLApbCiJhY2NvdW50IiwKImFjY291bnRfaWQiLAoib3RoZXIiLAoic2NoZW1lX25hbWUiCl0sClsKImFjY291bnQiLAoiYWNjb3VudF9pZCIsCiJvdGhlciIsCiJpZGVudGlmaWNhdGlvbiIKXQpd.AOm/TULGPD4a4GdcWhR9xh0GPlPUZuB2O1S9SYFWEz0="
]
}
Get account balances
GET /accounts/{account_id}/balances
Fetching account balances from ASPSP for an account by its ID
Parameters
Name In Type Required Description
account_id path string(uuid) true PSU account ID accessible in the provided session
Psu-Ip-Address header string false PSU IP address
Psu-User-Agent header string false PSU browser User Agent
Psu-Referer header string false PSU Referer
Psu-Accept header string false PSU accept header
Psu-Accept-Charset header string false PSU charset
Psu-Accept-Encoding header string false PSU accept encoding
Psu-Accept-language header string false PSU accept language
Psu-Geo-Location header string false Comma separated latitude and longitude coordinates without spaces
Authentication
To perform this operation, API requests must include Authorization header containing JWT calculated using private RSA key of the client application making the request. See jwtAuthentication.
Example request
GET https://api.enablebanking.com/accounts/{account_id}/balances HTTP/1.1
Host: api.enablebanking.com
Accept: application/json
Psu-Ip-Address: string
Psu-User-Agent: string
Psu-Referer: string
Psu-Accept: string
Psu-Accept-Charset: string
Psu-Accept-Encoding: string
Psu-Accept-language: string
Psu-Geo-Location: -1.2345,6.789
Authorization: Bearer <JWT>
Responses
Status Description Schema
200 Successful Response HalBalances
400 Bad Request ErrorResponse
401 Unauthorized ErrorResponse
403 Forbidden ErrorResponse
404 Not Found ErrorResponse
408 Request Timeout ErrorResponse
422 Unprocessable Entity ErrorResponse
429 Too Many Requests ErrorResponse
500 Internal Server Error ErrorResponse
Example responses
200 Response
{
"balances": [
{
"name": "Booked balance",
"balance_amount": {
"currency": "EUR",
"amount": "1.23"
},
"balance_type": "CLAV",
"last_change_date_time": "2019-08-24T14:15:22Z",
"reference_date": "2019-08-24",
"last_committed_transaction": "4604aa90f8a8418092d80c3270846f0a"
}
]
}
Get account transactions
GET /accounts/{account_id}/transactions
Fetching account transactions from ASPSP for an account by its ID
Parameters
Name In Type Required Description
account_id path string(uuid) true PSU account ID accessible in the provided session
date_from query string(date) false Date to fetch transactions from (including the date, UTC timezone is assumed)
date_to query string(date) false Date to fetch transactions to (including the date, UTC timezone is assumed)
continuation_key query string false Key, allowing iterate over multiple API pages of transactions
transaction_status query TransactionStatus false Filter transactions by provided status
strategy query TransactionsFetchStrategy false Strategy how transaction are fetched
Psu-Ip-Address header string false PSU IP address
Psu-User-Agent header string false PSU browser User Agent
Psu-Referer header string false PSU Referer
Psu-Accept header string false PSU accept header
Psu-Accept-Charset header string false PSU charset
Psu-Accept-Encoding header string false PSU accept encoding
Psu-Accept-language header string false PSU accept language
Psu-Geo-Location header string false Comma separated latitude and longitude coordinates without spaces
Authentication
To perform this operation, API requests must include Authorization header containing JWT calculated using private RSA key of the client application making the request. See jwtAuthentication.
Example request
GET https://api.enablebanking.com/accounts/{account_id}/transactions HTTP/1.1
Host: api.enablebanking.com
Accept: application/json
Psu-Ip-Address: string
Psu-User-Agent: string
Psu-Referer: string
Psu-Accept: string
Psu-Accept-Charset: string
Psu-Accept-Encoding: string
Psu-Accept-language: string
Psu-Geo-Location: -1.2345,6.789
Authorization: Bearer <JWT>
Responses
Status Description Schema
200 Successful Response HalTransactions
400 Bad Request ErrorResponse
401 Unauthorized ErrorResponse
403 Forbidden ErrorResponse
404 Not Found ErrorResponse
408 Request Timeout ErrorResponse
422 Unprocessable Entity ErrorResponse
429 Too Many Requests ErrorResponse
500 Internal Server Error ErrorResponse
Example responses
200 Response
{
"transactions": [
{
"entry_reference": "5561990681",
"merchant_category_code": "5511",
"transaction_amount": {
"currency": "EUR",
"amount": "1.23"
},
"creditor": {
"name": "MyPreferredAisp",
"postal_address": {
"address_line": [
"Mr Asko Teirila PO Box 511",
"39140 AKDENMAA FINLAND"
],
"address_type": "Business",
"building_number": "4",
"country": "FI",
"country_sub_division": "Uusimaa",
"department": "Department of resources",
"post_code": "00123",
"street_name": "Vasavagen",
"sub_department": "Sub Department of resources",
"town_name": "Helsinki"
}
},
"creditor_account": {
"iban": "FI0455231152453547"
},
"creditor_agent": {
"bic_fi": "string",
"clearing_system_member_id": {
"clearing_system_id": "NZNCC",
"member_id": 20368
},
"name": "string"
},
"debtor": {
"name": "MyPreferredAisp",
"postal_address": {
"address_line": [
"Mr Asko Teirila PO Box 511",
"39140 AKDENMAA FINLAND"
],
"address_type": "Business",
"building_number": "4",
"country": "FI",
"country_sub_division": "Uusimaa",
"department": "Department of resources",
"post_code": "00123",
"street_name": "Vasavagen",
"sub_department": "Sub Department of resources",
"town_name": "Helsinki"
}
},
"debtor_account": {
"iban": "FI0455231152453547"
},
"debtor_agent": {
"bic_fi": "string",
"clearing_system_member_id": {
"clearing_system_id": "NZNCC",
"member_id": 20368
},
"name": "string"
},
"bank_transaction_code": {
"description": "Utlandsbetalning",
"code": "12",
"sub_code": "32"
},
"credit_debit_indicator": "CRDT",
"status": "BOOK",
"booking_date": "2020-01-03",
"value_date": "2020-01-02",
"transaction_date": "2020-01-01",
"balance_after_transaction": {
"currency": "EUR",
"amount": "1.23"
},
"reference_number": "RF07850352502356628678117",
"reference_number_schema": "SEBG",
"remittance_information": [
"RF07850352502356628678117",
"Gift for Alex"
],
"debtor_account_additional_identification": {
"identification": "12345678",
"scheme_name": "CPAN"
},
"creditor_account_additional_identification": {
"identification": "12345678",
"scheme_name": "BBAN"
},
"exchange_rate": {
"unit_currency": "EUR",
"exchange_rate": "string",
"rate_type": "SPOT",
"contract_identification": "string",
"instructed_amount": {
"currency": "EUR",
"amount": "1.23"
}
},
"note": "string",
"transaction_id": "string"
}
],
"continuation_key": "string"
}
Get transaction details
GET /accounts/{account_id}/transactions/{transaction_id}
Fetching transaction details from ASPSP for an account transaction by its ID
Parameters
Name In Type Required Description
account_id path string(uuid) true Account ID
transaction_id path string true Transaction ID
Psu-Ip-Address header string false PSU IP address
Psu-User-Agent header string false PSU browser User Agent
Psu-Referer header string false PSU Referer
Psu-Accept header string false PSU accept header
Psu-Accept-Charset header string false PSU charset
Psu-Accept-Encoding header string false PSU accept encoding
Psu-Accept-language header string false PSU accept language
Psu-Geo-Location header string false Comma separated latitude and longitude coordinates without spaces
Authentication
To perform this operation, API requests must include Authorization header containing JWT calculated using private RSA key of the client application making the request. See jwtAuthentication.
Example request
GET https://api.enablebanking.com/accounts/{account_id}/transactions/{transaction_id} HTTP/1.1
Host: api.enablebanking.com
Accept: application/json
Psu-Ip-Address: string
Psu-User-Agent: string
Psu-Referer: string
Psu-Accept: string
Psu-Accept-Charset: string
Psu-Accept-Encoding: string
Psu-Accept-language: string
Psu-Geo-Location: -1.2345,6.789
Authorization: Bearer <JWT>
Responses
Status Description Schema
200 Successful Response Transaction
400 Bad Request ErrorResponse
401 Unauthorized ErrorResponse
403 Forbidden ErrorResponse
404 Not Found ErrorResponse
408 Request Timeout ErrorResponse
422 Unprocessable Entity ErrorResponse
429 Too Many Requests ErrorResponse
500 Internal Server Error ErrorResponse
Example responses
200 Response
{
"entry_reference": "5561990681",
"merchant_category_code": "5511",
"transaction_amount": {
"currency": "EUR",
"amount": "1.23"
},
"creditor": {
"name": "MyPreferredAisp",
"postal_address": {
"address_line": [
"Mr Asko Teirila PO Box 511",
"39140 AKDENMAA FINLAND"
],
"address_type": "Business",
"building_number": "4",
"country": "FI",
"country_sub_division": "Uusimaa",
"department": "Department of resources",
"post_code": "00123",
"street_name": "Vasavagen",
"sub_department": "Sub Department of resources",
"town_name": "Helsinki"
}
},
"creditor_account": {
"iban": "FI0455231152453547"
},
"creditor_agent": {
"bic_fi": "string",
"clearing_system_member_id": {
"clearing_system_id": "NZNCC",
"member_id": 20368
},
"name": "string"
},
"debtor": {
"name": "MyPreferredAisp",
"postal_address": {
"address_line": [
"Mr Asko Teirila PO Box 511",
"39140 AKDENMAA FINLAND"
],
"address_type": "Business",
"building_number": "4",
"country": "FI",
"country_sub_division": "Uusimaa",
"department": "Department of resources",
"post_code": "00123",
"street_name": "Vasavagen",
"sub_department": "Sub Department of resources",
"town_name": "Helsinki"
}
},
"debtor_account": {
"iban": "FI0455231152453547"
},
"debtor_agent": {
"bic_fi": "string",
"clearing_system_member_id": {
"clearing_system_id": "NZNCC",
"member_id": 20368
},
"name": "string"
},
"bank_transaction_code": {
"description": "Utlandsbetalning",
"code": "12",
"sub_code": "32"
},
"credit_debit_indicator": "CRDT",
"status": "BOOK",
"booking_date": "2020-01-03",
"value_date": "2020-01-02",
"transaction_date": "2020-01-01",
"balance_after_transaction": {
"currency": "EUR",
"amount": "1.23"
},
"reference_number": "RF07850352502356628678117",
"reference_number_schema": "SEBG",
"remittance_information": [
"RF07850352502356628678117",
"Gift for Alex"
],
"debtor_account_additional_identification": {
"identification": "12345678",
"scheme_name": "CPAN"
},
"creditor_account_additional_identification": {
"identification": "12345678",
"scheme_name": "BBAN"
},
"exchange_rate": {
"unit_currency": "EUR",
"exchange_rate": "string",
"rate_type": "SPOT",
"contract_identification": "string",
"instructed_amount": {
"currency": "EUR",
"amount": "1.23"
}
},
"note": "string",
"transaction_id": "string"
}
@@ -1,224 +0,0 @@
# Business Banking Sandbox Setup Guide
## Overview
This guide explains how to configure Enable Banking to use business banking test data instead of personal banking data.
## Changes Made
### 1. Transaction Fetching Added
- ✅ Callback route now fetches transactions for each account
- ✅ Transactions are stored in `landing.transactions` table
- ✅ Error handling per account (continues if one account fails)
### 2. PSU Type Configuration
- ✅ Added `ENABLE_BANKING_PSU_TYPE` environment variable
- ✅ Code now uses this variable throughout the flow
- ✅ Defaults to `business` if not set
### 3. Sample Business Data Created
- ✅ Swedish business banking sample data in `SAMPLE_BUSINESS_BANKING_DATA.json`
- ✅ Realistic business transactions (invoices, rent, VAT, payroll, etc.)
- ✅ Swedish IBANs and business-specific patterns
## Environment Configuration
Your `.env.local` now includes:
```bash
ENABLE_BANKING_PSU_TYPE=business # or 'personal'
```
### Switching Between Personal and Business
**For Business Banking:**
```bash
ENABLE_BANKING_PSU_TYPE=business
```
**For Personal Banking:**
```bash
ENABLE_BANKING_PSU_TYPE=personal
```
## Sample Business Banking Data
The file `dev_docs/SAMPLE_BUSINESS_BANKING_DATA.json` contains:
### Account Details
- **Account Name**: Arcim AB Företagskonto
- **IBAN**: SE4550000000058398257466
- **Currency**: SEK
- **Balance**: 847,250.50 SEK
- **Type**: Business checking account (CACC)
### Sample Transactions (10 total)
1. **Customer Payment** - 125,000 SEK (credit)
- Faktura 2025-1045 Konsulttjänster Oktober
2. **Rent Payment** - 45,000 SEK (debit)
- Hyra Lokaler Q4 2025
3. **Supplier Payment** - 28,500 SEK (debit)
- Faktura KP-2025-0892 Konsulttjänster
4. **Customer Payment** - 89,000 SEK (credit)
- Betalning Faktura 2025-3421 Projektleverans
5. **VAT Payment** - 156,700 SEK (debit)
- Moms Q3 2025 - Organisationsnummer 556789-1234
6. **AWS Cloud** - 12,500 SEK (debit)
- AWS Cloud Services October 2025
7. **Payroll** - 245,000 SEK (debit)
- Löner Oktober 2025 - 5 anställda
8. **Customer Payment** - 175,000 SEK (credit)
- Faktura 2025-2189 Utveckling SaaS Plattform
9. **Telecom** - 8,500 SEK (debit)
- Företagsabonnemang Telefoni & Internet Oktober
10. **Insurance** - 32,000 SEK (debit)
- Företagsförsäkring Q4 2025
## Testing the Integration
### Current Status
✅ **Working:**
- Authentication with Enable Banking
- Bank connection storage
- Account storage
- Transaction fetching and storage
### Test Flow
1. **Clear existing data** (if needed):
```sql
DELETE FROM landing.transactions WHERE tenant_id = 'your_tenant_id';
DELETE FROM landing.bank_accounts WHERE tenant_id = 'your_tenant_id';
DELETE FROM landing.bank_connections WHERE tenant_id = 'your_tenant_id';
```
2. **Start dev server**:
```bash
npm run dev
```
3. **Connect to bank**:
- Go to `/banking/connect`
- Select a bank
- Click "Create Account" on mock ASPSP page
- Set up sample data (use the business sample structure)
- Grant consent
4. **Verify data in Snowflake**:
```sql
-- Check connections
SELECT * FROM landing.bank_connections
WHERE tenant_id = 'your_tenant_id'
ORDER BY created_at DESC;
-- Check accounts
SELECT * FROM landing.bank_accounts
WHERE tenant_id = 'your_tenant_id'
ORDER BY created_at DESC;
-- Check transactions
SELECT * FROM landing.transactions
WHERE tenant_id = 'your_tenant_id'
ORDER BY booking_date DESC;
```
5. **Check logs**:
Look for these in your terminal:
```
Fetching transactions for account acc-business-001
Found 10 transactions for account acc-business-001
```
## Troubleshooting
### No Transactions Stored
**Symptoms:** Accounts are created but no transactions
**Possible Causes:**
1. The mock ASPSP didn't create transaction data
2. The account UID is wrong
3. Transaction API returned error
**Debug:**
- Check terminal logs for "Fetching transactions" messages
- Check for error messages like "Failed to fetch transactions"
- Verify the account `uid` field is correct
### Wrong Data Type (Personal vs Business)
**Symptoms:** Getting personal accounts when expecting business
**Solution:**
1. Check `.env.local` has `ENABLE_BANKING_PSU_TYPE=business`
2. Restart dev server (environment variables only load on startup)
3. Create a new test account on mock ASPSP page
4. Try selecting a different bank from the list
### Transaction Format Issues
**Symptoms:** Transactions stored but with missing/wrong data
**Check:**
- Transaction amounts are parsed correctly (converts string to number)
- Remittance info is joined properly (array to string)
- Credit/debit indicator is mapped correctly
## Using the Sample Data Structure
The `SAMPLE_BUSINESS_BANKING_DATA.json` file shows the expected structure for business banking data. While you can't directly upload this to Enable Banking's mock ASPSP, you can:
1. **Use it as reference** when creating test data on the mock ASPSP page
2. **Manually insert** test data into your Snowflake tables for testing:
```sql
-- Example: Insert test transactions directly
INSERT INTO landing.transactions (
transaction_id, account_id, tenant_id, external_transaction_id,
booking_date, value_date, amount, currency, description,
counterparty_name, counterparty_account, transaction_type
) VALUES
('txn_test_001', 'your_account_id', 'your_tenant_id', '2025102101',
'2025-10-18', '2025-10-18', 125000.00, 'SEK',
'Faktura 2025-1045 Konsulttjänster Oktober',
'KUND AB', 'SE9950000000054740013810', 'credit');
```
3. **Request Enable Banking** to pre-populate business test data for your sandbox application
## Next Steps
### For Production
When moving to production:
1. Keep `ENABLE_BANKING_PSU_TYPE=business`
2. Register production application at Enable Banking
3. Update environment variables with production credentials
4. Real bank data will automatically populate
### For Enhanced Testing
Consider:
- Creating multiple test companies with different transaction patterns
- Testing edge cases (failed transactions, pending transactions)
- Testing different currencies (if expanding beyond Sweden)
- Testing large transaction volumes
## Support
If you encounter issues:
- Check Enable Banking documentation: https://enablebanking.com/docs
- Contact Enable Banking support: info@enablebanking.com
- Review logs in your terminal and Snowflake
@@ -1,148 +0,0 @@
UI Widgets
Terms consent
This widget provides the possibility to display to an end user terms of the service and acquire their consent before redirecting them to tilisy.enablebanking.com for authorisation of the requested access in an ASPSP.
NB
The widget shall be used only when your application relies on Enable Banking accessing ASPSPs as a regulated entity. If your company is a licensed TPP and Enable Banking acts solely as a technical service provider, the terms of service step is always skipped during the authorisation flow.
In order to use the widget, the following is needed.
Load the widgets library https://tilisy.enablebanking.com/lib/widgets.umd.min.js on the page where it is going to be used.
<script src="https://tilisy.enablebanking.com/lib/widgets.umd.min.js"></script>
Put the custom element enablebanking-consent registered by the widgets library into the place on the page where the widget needs to be shown.
<enablebanking-consent
id="enablebanking-consent"
authorization="a8bfe9f4-dfdf-4c86-9a94-9db7660bd4bd"
locale="SV"
can-cancel
sandbox></enablebanking-consent>
The element enablebanking-consent has the following attributes:
authorization (required), should contain authorisation ID received from POST /auth API call;
locale (optional), language in which the widget content should be presented. Supported languages: DA, EN, ET, FI, FR, LT, LV, NL, NO, PL, RU, SV;
can-cancel (optional), when present the “Cancel” button will be displayed, which will emit cancel event when pressed;
sandbox (optional), to be used when authorisation was initiated with an application registered to sandbox environment;
origin (optional), to be provided in case a custom/dedicated environment is used, the default value is https://tilisy.enablebanking.com;
no-redirect (optional), to be used if the end user should not be automatically redirected to tilisy.enablebanking.com for authorisation of the access in an ASPSP; in this case redirect is to be performed when confirmed event is triggered.
Using event listener function
<script>
document.getElementById("enablebanking-consent").addEventListener("confirmed", function(e) {
console.log(e)
});
</script>
The element produces the following events:
error, if an error occurs,
ready, when the widget is fully loaded,
confirmed, after a user has confirmed the consent,
cancelled, if the “Cancel” button was pressed.
The events can be listened similarly to standard Javascript events using addEventListener method called for the enablebanking-consent element.
The widget does not include any CSS, it will use the styles present on the page where included.
NB
The widget can be used only on the websites with origins whitelisted for the application used to initiate end user authorisation.
Whitelisting of the origins can be done through the control panel:
Go to https://enablebanking.com/cp/applications (opens new window);
Choose Edit from the context menu for your application ("⋮" next to the application name);
Enter necessary origins into the "Allowed widget origins" edit box;
Press the "Save" button.
ASPSP selection
This widget provides a method to present on a web page the list of available ASPSPs (i.e. banks and similar financial institutions) and let an end-user to select the one, which they want to proceed with.
The following code is needed in the html file.
Load the widgets library https://tilisy.enablebanking.com/lib/widgets.umd.min.js and the default CSS https://tilisy.enablebanking.com/lib/widgets.css on the page where it is going to be used.
<script src="https://tilisy.enablebanking.com/lib/widgets.umd.min.js"></script>
<link href="https://tilisy.enablebanking.com/lib/widgets.css" rel="stylesheet">
Put the custom element enablebanking-aspsp-list registered by the widgets library into the place on the page where the widget needs to be shown.
<enablebanking-aspsp-list
id="enablebanking-aspsp-list"
country="FI"
psu-type="personal"
service="AIS"
sandbox></enablebanking-aspsp-list>
Add an event listener, which would trigger authorisation of access to account information or payment initiation.
<script>
document.getElementById("enablebanking-aspsp-list").addEventListener("selected", function(e) {
console.log(e.detail)
});
</script>
When an end-user clicks one of the ASPSP cards, the event selected will be triggered and the detail field value is like this:
{
"beta": false,
"country": "SE",
"name": "Ekeby Sparbank",
"psuType": "personal",
"sandbox": true,
"service": "AIS"
}
The element enablebanking-aspsp-list has the following attributes:
country (required), two-letter country code determining which ASPSPs will be displayed;
psu-type (required), either personal or business determining the type of user, which will grant authorisation;
service (required), either AIS or PIS determining whether account information or payment initiation service will be used;
sandbox (optional), to be provided in case sandbox authorisation will take place in the sandbox environment;
no-beta (optional), can be used to filter out ASPSPs whose integrations are still in the beta-testing phase;
origin (optional), to be provided in case a custom/dedicated environment is used, the default value is https://tilisy.enablebanking.com;
search-term (optional), can be used to filter ASPSPs by name;
logo-transform (optional), can be used change dimentions of the logo image (for example, -/resize/320x/-/crop/440x340/center/, for full list of possible transformations, please refer to https://uploadcare.com/docs/transformations/image/resize-crop/).
The element produces the following events:
error, if an error occurs;
ready, when the widget is fully loaded or them the list of ASPSP is updated;
selected, after a user has selected an ASPSP.
Auth flow
This widget provides the possibility to perform interactions with an end user necessary for authorisation of access to account information and payment initiation from a web page hosted by the application accessing Enable Banking API and, if necessary, redirect directly ASPSPs bypassing redirect to tilisy.enablebanking.com (or a custom domain, in case the dedicated single-tenant environment is used).
In order to use the widget, the following is needed.
Load the widgets library https://tilisy.enablebanking.com/lib/widgets.umd.min.js on the page where it is going to be used.
<script src="https://tilisy.enablebanking.com/lib/widgets.umd.min.js"></script>
Put the custom element enablebanking-auth-flow registered by the widgets library into the place on the page where the widget needs to be shown.
<enablebanking-auth-flow
id="enablebanking-auth-flow"
authorization="a8bfe9f4-dfdf-4c86-9a94-9db7660bd4bd"
locale="SV"
can-cancel
sandbox></enablebanking-auth-flow>
The element enablebanking-auth-flow has the following attributes:
authorization (conditional), should contain authorisation ID received from POST /auth API call;
payment (conditional), should contain payment ID received from POST /payment API call;
locale (optional), language in which the widget content should be presented. Supported languages: DA, EN, ET, FI, FR, LT, LV, NL, NO, PL, RU, SV;
sandbox (optional), to be used when authorisation was initiated with an application registered to sandbox environment;
origin (optional), to be provided in case a custom/dedicated environment is used, the default value is https://tilisy.enablebanking.com.
Using event listener function
<script>
document.getElementById("enablebanking-auth-flow").addEventListener("ready", function(e) {
console.log("Auth flow widget is loaded")
});
</script>
The element produces the following events:
error, if an error occurs,
ready, when the widget is fully loaded,
ais-loaded, after authorisation session for AIS service is established,
pis-loaded, after authorisation session for PIS service is established.
The events can be listened similarly to standard Javascript events using addEventListener method called for the enablebanking-auth-flow element.
The widget includes default CSS, which can be overriden.
NB
The widget can be used only on the websites with origins whitelisted for the application used to initiate end user authorisation.
Whitelisting of the origins can be done through the control panel:
Go to https://enablebanking.com/cp/applications (opens new window);
Choose Edit from the context menu for your application ("⋮" next to the application name);
Enter necessary origins into the "Allowed widget origins" edit box;
Press the "Save" button.
@@ -1,198 +0,0 @@
Quick Start with Enable Banking API
Welcome to the Quick Start guide for the Enable Banking API! This guide will help you quickly get up and running with the API so you can start building innovative financial applications.
Signing up for an account
Before you can begin using the Enable Banking API, you'll need to sign up for an account to Enable Banking Control Panel. Follow these steps:
Visit the authentication page https://enablebanking.com/sign-in/ (opens new window).
Enter your email, new accounts are automatically created on the first sign in.
Follow the one-time authentication link sent to your email. After authentication you will be redirected your profile in the Control.
Registering an application
Once you have an account, you can register your application to obtain API access:
Go to the API applications (opens new window)page using the top menu of the Control Panel.
Fill out "Add a new application" form:
Keep the Sandbox environment and the default option for creation of the application's private key;
Fill in the name of your application (this name will be shown to end users when they will be requested to authorise sharing of their account information with your application or to confirm a payment initiated by your application);
Enter URLs whitelisted for redirecting of end users after they complete authorisation of access to account information or confirm a payment.
Submit the form by pressing "Register" button. Your web browser will generate a private key for the application and it will be saved into your downloads folder. The file name will be the ID that was assigned to the newly registered application (e.g., aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.pem).
Creating JWT for API authorisation
To authenticate with the API, your application will need to use JSON Web Tokens generated using the private key saved during the registration process described above. Here is a sample implementation:
Import a library allowing to generate JSON Web Tokens using RS256 algorithm:
PythonJavaScript
import jwt as pyjwt
Most modern languages will have a number of libraries for JWT generation in their ecosystems.
An extensive list of libraries for JWT generation can be found at https://jwt.io/libraries (opens new window).
Import other necessary libraries and write the necessary helper functions:
PythonJavaScript
import os
from datetime import datetime
This part significantly varies depending on the programming language you choose and the library you use for JWT generation.
Read application's private key from a file:
PythonJavaScript
private_key = open("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.pem", "rb").read()
Note that some libraries do not require you to load the private key from a file but rather allow you to pass the path to the file as a parameter.
Prepare the JWT payload (also known as the body):
PythonJavaScript
iat = int(datetime.now().timestamp())
jwt_body = {
"iss": "enablebanking.com", # always the same value
"aud": "api.enablebanking.com", # always the same value
"iat": iat, # time when the JSON Web Token is created
"exp": iat + 3600, # time when the token is set to expire
}
Create the JWT with its header and signature:
PythonJavaScript
jwt = pyjwt.encode(
jwt_body,
private_key,
algorithm="RS256",
headers={
"kid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", # your application's ID
}
)
Prepare the authorisation header for sending with every API request:
PythonJavaScript
base_headers = {
"Authorization": f"Bearer {jwt}",
}
Your application needs to send the above created authorisation header with every request it makes to Enable Banking API.
The full specification of the JWT format expected by Enable Banking API can be found in the API reference.
Accessing account information
With authentication in place, you can start accessing account information from ASPSPs (banks and similar financial institutions):
To obtain the list of available ASPSPs in a country, send a GET request to the ASPSPs endpoint specifying the desired country in the country query parameter in the format of Two-letter ISO 3166 code:
PythonJavaScript
import requests
from pprint import pprint
r = requests.get("https://api.enablebanking.com/aspsps?country=FI", headers=base_headers)
# If you want you can override BANK_NAME and BANK_COUNTRY with any bank from this list
print("Available ASPSPs:")
pprint(r.json()["aspsps"])
The first step in obtaining account information is to start the authorisation process. To do this, send a POST request to the authorisation endpoint, specifying a bank name and a country from the list returned from ASPSPs endpoint.
PythonJavaScript
body = {
"access": {
"valid_until": (datetime.now(timezone.utc) + timedelta(days=10)).isoformat() # 10 days ahead
},
"aspsp": {
"name": "Nordea", # BANK_NAME
"country": "FI" # BANK_COUNTRY
},
"state": "123e4567-e89b-12d3-a456-426614174000"
"redirect_url": "https://example.com/redirect", # application's redirect URL
"psu_type": "personal",
}
r = requests.post("https://api.enablebanking.com/auth", json=body, headers=base_headers)
auth_url = r.json()["url"]
The response will contain a redirect URL to which you should redirect the end user to complete the authorisation process. After the end user completes the authorisation process, they will be redirected to the URL you specified during the application registration. The URL will contain a query parameter named code which will be used to authorize the user session
PythonJavaScript
print(f"To authenticate open URL {auth_url}") # open this URL in a web browser
To authorize the user session send a POST request to the sessions endpoint, specifying the code received in the authorisation endpoint. In the response you will receive a session ID, with the list of authorized accounts.
PythonJavaScript
r = requests.post(f"https://api.enablebanking.com/sessions", json={"code": code}, headers=base_headers)
session = r.json()
print("New user session has been created:")
pprint(session)
To obtain the list of balances for the authorized accounts, send a GET request to the balances endpoint, specifying the account ID in the URL.
PythonJavaScript
# Using the first available account for the following API calls
account_uid = session["accounts"][0]["uid"]
# Retrieving account balances
r = requests.get(f"https://api.enablebanking.com/accounts/{account_uid}/balances", headers=base_headers)
print("Balances:")
pprint(r.json())
To obtain the list of transactions for the authorized accounts, send a GET request to the transactions endpoint, specifying the account ID in the URL.
PythonJavaScript
r = requests.get(f"https://api.enablebanking.com/accounts/{account_uid}/transactions",headers=base_headers)
resp_data = r.json()
print("Transactions:")
pprint(resp_data["transactions"])
you can refer to the API reference for more details on the API endpoints.
Full source code in our GitHub:
PythonJavaScript
https://github.com/enablebanking/enablebanking-api-samples/blob/master/python_example/account_information.py(opens new window)
Initiating payments
If your application requires payment initiation functionality, you can use the Enable Banking API for this purpose:
To initiate a payment, send a POST request to the Create Payment endpoint, specifying the payment details in the request body.
PythonJavaScript
body = {
"payment_type": "SEPA",
"payment_request": {
"credit_transfer_transaction": [
{
"beneficiary": {
"creditor_account": {
"scheme_name": "IBAN",
"identification": "FI7473834510057469",
},
"creditor": {
"name": "Test",
},
},
"instructed_amount": {"amount": "2.00", "currency": "EUR"},
"reference_number": "123",
}
],
},
"aspsp": {"name": "Nordea", "country": "FI"},
"state": "123e4567-e89b-12d3-a456-426614174000",
"redirect_url": "https://example.com/redirect", # application's redirect URL
"psu_type": "personal",
}
r = requests.post(f"https://api.enablebanking.com/payments", json=body, headers=base_headers)
payment = r.json()
The response will contain a redirect URL to which you should redirect the end user to complete the payment initiation process. Use following credentials to authenticate: customera / 12345678
PythonJavaScript
print("To authenticate open URL:")
print(payment["url"])
To get the status of the initiated payment, send a GET request to the Get Payment endpoint, specifying the payment ID in the URL.
PythonJavaScript
# This request can be called multiple times to check the status of the payment
payment_id = payment["payment_id"]
r = requests.get(f"https://api.enablebanking.com/payments/{payment_id}", headers=base_headers)
print("Payment status:")
pprint(r.json())
Full source code in our GitHub:
PythonJavaScript
https://github.com/enablebanking/enablebanking-api-samples/blob/master/python_example/payment_initiation.py(opens new window)
Next steps
Congratulations! You've completed the essential steps to get started with the Enable Banking API. Here are some suggested next steps:
Explore the API reference to learn more about the API endpoints and their parameters.
Check out code samples and a Postman collections in our GitHub repository (opens new window).
Discover the Control Panel where you can manage apps, configure settings, and monitor activity.
Learn how to test your API integrations in the Sandbox.
If you have any questions or run into issues, don't hesitate to reach out for assistance.
Happy coding!
@@ -1,210 +0,0 @@
Kickstart Open Banking and Enrichment in less than two hours
Get started quickly with connecting Open Banking, accessing raw account data, and creating financial insights.
Explore our docs
1
Enable Banking
Get started with accessing raw account data.
This documentation might not be fully up to date. You can view the latest information on Enable Bankings documentation page: https://enablebanking.com/docs/api/quick-start
1. Signing up for an account
Before you can begin using the Enable Banking API, you'll need to sign up for an account to Enable Banking Control Panel. Follow these steps.
1.1 Visit the authentication page here
1.2 Enter your email, new accounts are automatically created on the first sign in
1.3 Follow the one-time authentication link sent to your email. After authentication you will be redirected your profile in the Control
2. Registering an application
Once you have an account, you can register your application to obtain API access.
2.1 Go to the API applications page using the top menu of the Control Panel here
2.2 Fill out "Add a new application" form
2.2.1 Keep the Sandbox environment and the default option for creation of the application's private key
2.2.2 Fill in the name of your application (this name will be shown to end users when they will be requested to authorise sharing of their account information with your application or to confirm a payment initiated by your application)
2.2.3 Enter URLs whitelisted for redirecting of end users after they complete authorisation of access to account information or confirm a payment
2.3 Submit the form by pressing "Register" button. Your web browser will generate a private key for the application and it will be saved into your downloads folder. The file name will be the ID that was assigned to the newly registered application (e.g., aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.pem)
3. Creating JWT for API authorisation
To authenticate with the API, your application will need to use JSON Web Tokens generated using the private key saved during the registration process described above. The full specification of the JWT format expected by Enable Banking API can be found in the API reference. Here is a sample implementation
3.1 Import a library allowing to generate JSON Web Tokens using RS256 algorithm
const jwa = require("jwa")
Most modern languages will have a number of libraries for JWT generation in their ecosystems. An extensive list of libraries for JWT generation can be found at https://jwt.io/libraries (opens new window).
3.2 Import other necessary libraries and write the necessary helper functions
const fs = require("fs")
const jsonBase64 = (data) => {
return Buffer.from(JSON.stringify(data)).toString("base64").replace("=", "")
}
This part significantly varies depending on the programming language you choose and the library you use for JWT generation.
3.3 Read application's private key from a file
const privateKey = fs.readFileSync("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee.pem", "utf8")
Note that some libraries do not require you to load the private key from a file but rather allow you to pass the path to the file as a parameter.
3.4 Prepare the JWT payload (also known as the body)
const iat = Math.floor((new Date()).getTime() / 1000)
const jwtBody = {
iss: "enablebanking.com", // always the same value
aud: "api.enablebanking.com", // always the same value
iat: iat, // time when the token is created
exp: iat + 3600 // time when the token is set to expire
}
3.5 Create the JWT with its header and signature
const jwt = ((exp = 3600) => {
const header = jsonBase64({
typ: "JWT",
alg: "RS256",
kid: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" // your application's ID
})
const body = jsonBase64(jwtBody)
const signature = jwa("RS256").sign((header + '.' + body), privateKey)
return (header + '.' + body + '.' + signature)
})()
3.6 Prepare the authorisation header for sending with every API request
const baseHeaders = {
Authorization: "Bearer " + jwt
}
Your application needs to send the above created authorisation header with every request it makes to Enable Banking API.
4. Accessing account information
With authentication in place, you can start accessing account information from ASPSPs (banks and similar financial institutions).
4.1 To obtain the list of available ASPSPs in a country, send a GET request to the ASPSPs endpoint specifying the desired country in the country query parameter in the format of Two-letter ISO 3166 code
const fetch = require('node-fetch');
const aspspsResponse = await fetch('https://api.enablebanking.com/aspsps?country=FI', {
headers: baseHeaders
})
// If you want you can override BANK_NAME and BANK_COUNTRY with any bank from this list
console.log('Available ASPSPs: ' + await aspspsResponse.text())
4.2 The first step in obtaining account information is to start the authorisation process. To do this, send a POST request to the authorisation endpoint, specifying a bank name and a country from the list returned from ASPSPs endpoint
// 10 days ahead
const validUntil = new Date(new Date().getTime() + 10 * 24 * 60 * 60 * 1000);
const startAuthorizationBody = {
access: {
valid_until: validUntil.toISOString()
},
aspsp: {
name: "Nordea", // BANK_NAME
country: "FI" // BANK_COUNTRY
},
state: "123e4567-e89b-12d3-a456-426614174000",
redirect_url: "https://example.com/redirect", // application's redirect URL
psu_type: "personal"
}
const startAuthorizationResponse = await fetch('https://api.enablebanking.com/auth', {
method: "POST",
headers: baseHeaders,
body: JSON.stringify(startAuthorizationBody)
})
const startAuthorizationData = await startAuthorizationResponse.text();
console.log('Start authorization data: ' + startAuthorizationData)
4.3 The response will contain a redirect URL to which you should redirect the end user to complete the authorisation process. After the end user completes the authorisation process, they will be redirected to the URL you specified during the application registration. The URL will contain a query parameter named code which will be used to authorize the user session
console.log('To authenticate open URL ' + startAuthorizationData)
4.4 To authorize the user session send a POST request to the sessions endpoint, specifying the code received in the authorisation endpoint. In the response you will receive a session ID, with the list of authorized accounts
const createSessionBody = {
code: code
}
const createSessionResponse = await fetch('https://api.enablebanking.com/sessions', {
method: "POST",
headers: baseHeaders,
body: JSON.stringify(createSessionBody)
})
const session = await createSessionResponse.text()
console.log('New user session has been created: ' + session)
4.5 To obtain the list of balances for the authorized accounts, send a GET request to the balances endpoint, specifying the account ID in the URL
// Using the first available account for the following API calls
const accountId = JSON.parse(session).accounts[0]
const accountBalancesResponse = await fetch('https://api.enablebanking.com/accounts/' + accountId + '/balances', {
headers: baseHeaders
})
console.log('Account balances data: ' + accountBalancesResponse.text())
4.6 To obtain the list of balances for the authorized accounts, send a GET request to the balances endpoint, specifying the account ID in the URL
const accountTransactionsResponse = await fetch('https://api.enablebanking.com/accounts/' + accountId + '/transactions', {
headers: baseHeaders
})
console.log('Account transactions data: ' + accountTransactionsResponse.text()')
2
Gokind
Create insights from the raw account data
1. Fetch an API key pair
Get your first API key pair.
1.1 Visit the portal here
1.2 Request a key pair and await verification
1.3 Once your key pair has been verified download it and store it safely
2. Get an access token
JWT valid for two hours.
const axios = require('axios');
const { token } = await axios.post('https://api.gokind.co/auth', {
publicKey: "{YOUR_PUBLIC_KEY}",
privateKey: "{YOUR_PRIVATE_KEY}"
})M
console.log('JWT token valid for two hours: ' + token);
3. Format the Enable Banking data
Make it compatible with the Gokind API.
const formattedBundles = transactionFromEnableBanking.map(transaction => {
const {
remittance_information,
creditor,
debtor,
bank_transaction_code,
transaction_amount,
value_date,
booking_date,
transaction_date,
} = transaction;
const {description, sub_code, code} = bank_transaction_code;
const {amount, currency} = transaction_amount;
return {
label: remittance_information.join(' '),
creditor: creditor.name,
debtor: debtor.name,
type: description || code,
subType: sub_code,
amount: amount,
currency: currency,
date: value_date || booking_date || transaction_date
}
});
console.log('Formatted bundles: ' + JSON.stringify(formattedBundles));
4. Get the enriched response
Enrich the formatted bundles.
const axios = require('axios');
const headers = {
'Authorization': 'Bearer ' + token
};
const body = {
identifiers:{
account:{
type: "business",
},
bundles: formattedBundles
},
include:{
logo: true,
industries: true,
payment: true,
checks: true,
flags: true,
event: true,
},
config:{
region: "SE",
return: {
unidentified: true
}
}
};
const response = await axios.post('https://api.gokind.co/identify', body, { headers });
console.log(response);
+5 -6
View File
@@ -30,12 +30,11 @@ const OPTIONAL_VARS = [
] as const
function validateEnvironment(): void {
// During Docker builds, NEXT_PUBLIC_* vars are placeholder sentinels
// replaced at runtime by docker-entrypoint.sh. Server-only vars like
// SUPABASE_SERVICE_ROLE_KEY are not available at build time at all.
// Skip validation so Next.js page collection doesn't fail.
const isBuildPlaceholder = process.env.NEXT_PUBLIC_SUPABASE_URL?.startsWith('__')
if (isBuildPlaceholder) return
// During builds (CI, Docker, Vercel), env vars may be absent or set to
// placeholder sentinels. Skip validation so Next.js page collection
// doesn't fail — real validation happens at runtime.
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
if (!supabaseUrl || supabaseUrl.startsWith('__')) return
const missing: string[] = []
+3 -3
View File
@@ -4,9 +4,9 @@ import { createBrowserClient } from '@supabase/ssr'
// (e.g. __NEXT_PUBLIC_SUPABASE_URL__) that get replaced at runtime by
// docker-entrypoint.sh. Provide a dummy URL so the client constructor
// doesn't throw during Next.js static page generation.
const url = process.env.NEXT_PUBLIC_SUPABASE_URL!
const key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
const isBuildPlaceholder = url.startsWith('__')
const url = process.env.NEXT_PUBLIC_SUPABASE_URL ?? ''
const key = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ?? ''
const isBuildPlaceholder = !url || url.startsWith('__')
export function createClient() {
return createBrowserClient(