Skip to content

Testscenarier i sandbox

Den här guiden hjälper kunder och partners att testa affärsscenarier mot Amilis REST-API i sandbox-miljön under uppbyggnaden av en integration. Varje scenario visar hur du utlöser det (API-anropen du gör) och hur du verifierar det (vad du kontrollerar i svaret).

Den är organiserad efter användningsfall — statusuppdateringar (påminnelse, inkasso, betalningar) och utbetalningsinformation — och kompletterar Use Case-matrisen, som beskriver vad du ska integrera snarare än hur du verifierar det.


Innan du börjar

Åtkomst och endpoints

Åtkomst till sandbox tillhandahålls av Amili, inte via självbetjäning. Under onboardingen registrerar Amili din publika nyckel, utfärdar din API-kod och skapar det/de konton och den/de borgenärer du testar mot.

  • API-bas: https://api-sandbox.amili.se (interaktiv referens på /docs)
  • Borgenärsapp: https://app-sandbox.amili.se · Kundapp: https://ada-customer-sandbox.vfs.visma.com
  • Autentisering: signera en kortlivad JWT med din privata nyckel → GET /authenticates/api-code → använd den returnerade token som X-API-Key i varje anrop. Se Autentisering.

Alla exempel nedan förutsätter en giltig X-API-Key.

Din uppsättning (konfigureras av Amili)

Ditt konto, din borgenär och ditt avtal sätts upp av Amili under onboardingen — du konfigurerar inte detta själv. Två av dessa inställningar påverkar vad du kan testa och är värda att känna till:

  • Ditt avtal avgör vilka åtgärder ett ärende kan starta med — reminder och/eller debt_collection — och om du kan registrera fakturor direkt (full-service). Detta skiljer sig från avtal till avtal.
  • Din borgenär måste vara aktiv, och dess payout_details (bankkonto) är dit utbetalningar skickas.

Du kan läsa din borgenär med GET /creditors för att se dess aktuella inställningar. Om ett anrop avvisas för att en inställning inte är aktiverad för din borgenär, kontakta din integrationskontakt hos Amili.

Sandbox vs din produktionsborgenär

Sandbox beter sig som produktion på API-nivå. Det som kan skilja är din produktionsborgenärs egen konfiguration (avgifter, payout-intervall, påminnelsetider) — den sätts upp utifrån ditt avtal och kanske inte matchar den generiska testborgenären i sandbox. Bygg mot API-kontraktet snarare än mot specifika sandbox-värden, och bekräfta produktionsspecifika värden med din kontakt hos Amili. Även miljöbeteendet skiljer sig — se Begränsningar i sandbox nedan.

Hur övergångar sker i sandbox

Bra att förstå innan du testar statusuppdateringar:

  • Det normala flödet är tidsstyrt — en automatisk process plockar upp förfallna ärenden ungefär var 10:e minut; det finns ingen tidsacceleration. När den första påminnelsen skickas beror på fakturans förfallodag: en faktura som redan är förfallen vid registrering får sin påminnelse schemalagd till nästa flödeskörning (den går ut samma dag, ca en timme senare), medan en faktura med framtida förfallodag väntar till runt sin förfallodag. Varje senare steg — t.ex. påminnelse → inkasso — väntar sedan på påminnelsebrevets betalningsfönster, oftast ~10 bankdagar (inrikes) plus ett par bankdagar, så de stegen tar verklig kalendertid.
  • Framåtprogression går inte att snabbspola publikt. Det finns inget API-anrop som flyttar ett ärende till nästa steg på begäran; om du behöver ett ärende framflyttat utan att vänta är det en åtgärd på Amilis sida.
  • Vissa övergångar kan utlösas på begäran via domänåtgärder i stället för att vänta på flödet — t.ex. respite och close_case (under /domain-actions/cases/...). Framåtprogression (påminnelse → inkasso) är inte en av dem.
  • Betalningar måste simuleras. Sandbox har ingen riktig bankkoppling. För att pengar ska settla mot ett ärende (och skapa en utbetalning) använder du en demobetalning:

Sandbox kör dessa med fast frekvens (tider i UTC). Ingen av dem accelererar tiden — de agerar på poster vars schemalagda datum redan har passerat:

ProcessFrekvens i sandboxVad den gör
Flödesprogression~var 10:e minSkickar påminnelser och eskalerar påminnelse → inkasso när det är dags
Betalningssettlement~varje timmeSettlar demobetalningar → stänger ärendet → skapar finance--payout-specifications
Utbetalningsaggregeringdagligen (~04:30)Grupperar payout-specifikationer till finance--payouts, enligt borgenärens payout-intervall

En borgenärsbetalning är inte en utbetalning

POST /creditor--payments registrerar pengar som borgenären redan tagit emot direkt. Det stänger ett fullbetalt ärende med orsak capital_paid_to_creditor men skapar ingen utbetalning. För att testa utbetalningsinformation, använd en demobetalning (gäldenär → Amili), inte en borgenärsbetalning.


Scenariomatris

1. Anslutning

ScenarioSå gör duSå verifierar du
Autentisera mot sandboxGET /authenticates/api-code med en JWT signerad med din privata nyckel200 med { token }; token fungerar som X-API-Key
Bekräfta att din borgenär är redoGET /creditors/{creditor_id}is_active: true; payout_details finns (avtal via GET /agreements)

2. Registrera en fordran

Vilka first_action-värden som är tillgängliga — och om du kan registrera fakturor direkt — beror på ditt avtal. Följ den del som matchar den fordringstyp du registrerar.

Vilka testkunder du bör använda

Använd ett riktigt svenskt organisationsnummer — t.ex. en kommun eller ett registrerat företag. Organisationsnummer är offentlig information.

Undvik påhittade identitetsnummer. Själva registreringen returnerar 201, men kunden slås upp i ett efterföljande steg — om identitetsnumret inte kan slås upp misslyckas det steget med Failed to initialize customer och ärendet startar aldrig.

Ärendet startar inte direkt

Registreringen returnerar 201 med en gång, men ärendet skapas med state: "initializing" och status: "initializing". Kunden slås upp och flödet startas av ett efterföljande steg som körs var 10:e minut — räkna med upp till ca 10 minuter innan ärendet når sin riktiga status. Verifieringarna nedan förutsätter att det steget har körts.

2A. Registrera en faktura (full-service)

ScenarioSå gör duSå verifierar du
Registrera en fakturaPOST /invoice--registrations (creditor, customer, matrix, invoice_date, invoice_due_date, currency)201 → svaret innehåller _invoice, _case, _ocr_number, ocr_number_ocr

2B. Registrera ett ärende för påminnelse (PM)

ScenarioSå gör duSå verifierar du
Registrera ett ärende för påminnelsePOST /case--registrations med first_action: "reminder" (plus creditor, currency, customer, debts[])201_cases[0], _ocr_numbers[0], _ocr_numbers_ocr[0].
GET /cases/{_cases[0]}state: "reminder" (när initieringen körts)

2C. Registrera ett ärende direkt till inkasso (IK)

ScenarioSå gör duSå verifierar du
Registrera ett ärende till inkassoPOST /case--registrations med first_action: "debt_collection" (plus creditor, currency, customer, debts[])201_cases[0].
GET /cases/{id} → ärendet ligger i inkassospåret (när initieringen körts)

Gemensamt för alla fordringstyper

ScenarioSå gör duSå verifierar du
Bifoga originalfakturan (PDF)1. Registrera ett ärende (ovan) → _cases[0]
2. POST /media--upload/{case_id} (multipart: file, domain: cases, dotted_path: original_invoice)
200 med { url } (signerad länk)

3. Statusuppdateringar — påminnelse & eskalering

Få ut den första påminnelsen snabbt

Den första påminnelsen schemaläggs utifrån fakturans förfallodag, inte en fast fördröjning. Registrera ärendet med ett fakturadatum / förfallodag som redan passerat, så köas påminnelsen till nästa flödeskörning (samma dag) i stället för att vänta. (first_action_date kan fördröja den första åtgärden men kan inte tidigarelägga den före förfallodagen.)

ScenarioSå gör duSå verifierar du
Ärendet når påminnelsesteget1. POST /case--registrations (first_action: "reminder") → _cases[0]
2. (automatiskt) flödet driver det vidare
GET /cases/{id}state: "reminder", status: "reminder" (eller "soft_reminder" tidigt); next_flow_item.schedule_to_execute är satt
Eskalera påminnelse → inkasso1. Registrera ett påminnelseärende (ovan)
2. Låt verkliga kalenderdagar passera (oftast ~10 bankdagar), eller be Amili flytta fram det
GET /cases/{id}state: "debt_collection", status: "debt_collection"; state_history[] visar övergången
Läs aktuell status vid behovGET /cases/{id}?projection={"state":1,"status":1,"closed":1,"total_remaining_capital_amount":1}Svaret speglar aktuell state, status, återstående kapital
Läs övergångshistorikenGET /cases/{id} (med state_history, status_history)
GET /case--histories?where={"cases.case":"<id>"}
Poster i state_history[] / status_history[]; aktivitetslogg i case--histories

Filtrera case--histories på ärende

case--histories är fältet cases en lista med objekt, så filtrera på den nästlade referensen — where={"cases.case":"<case_id>"}. Att filtrera direkt på cases ger inga träffar.

Stängning ändrar inte state

Vid stängning sätter plattformen status: "closed" och ett closed-underdokument { reason, close_date } men lämnar state oförändrat. Upptäck stängning via status == "closed" och/eller att closed finns, inte via state.

4. Statusuppdateringar — borgenärsåtgärder på ett ärende

Var och en av dessa åtgärder settlar synkront i POST-anropet och returnerar en status per post (completed / warning / error).

ScenarioSå gör duSå verifierar du
Registrera en full betalning (till borgenär)1. Registrera ett ärende (§2) → _cases[0]
2. POST /creditor--payments { creditor, case, amount, currency, bank_transaction_date, origin } (hela saldot)
_payment_status: "completed".
GET /cases/{id}total_remaining_capital_amount: 0, status: "closed", closed.reason: "capital_paid_to_creditor"
Registrera en delbetalning1. Registrera ett ärende (§2)
2. POST /creditor--payments med en del av saldot
_payment_status: "completed".
GET /cases/{id}total_remaining_capital_amount minskat, inget closed
Kreditera del av kapitalet1. Registrera ett ärende (§2)
2. POST /creditor--creditings { case, amount, currency, origin }
_crediting_status: "completed".
GET /cases/{id} → kapitalet minskat; om det nollställs → closed.reason: "credit"
Makulera ett ärende1. Registrera ett ärende (§2)
2. POST /creditor--cancellations { creditor, case, origin }
_cancellation_status: "completed".
GET /cases/{id}status: "closed", closed.reason: "cancellation"
Bevilja anstånd (skjut upp)1. Registrera ett ärende med ett kommande steg (§2)
2. GET /domain-actions/cases/respite/{id} (200 = tillåtet, 206 = problem)
3. POST /domain-actions/cases/respite/{id} { days: 14 }
POST returnerar 200.
GET /cases/{id}next_flow_item.schedule_to_execute framflyttat; state/status oförändrat (se not)

Tillgänglighet för anstånd

Anstånd är tillgängligt fram till att ett ärende lämnas över till Kronofogden (enforcement) — inklusive under påminnelse, inkasso och bevakning. Maxtiden är oftast 30 dagar per anstånd, och antalet anstånd är i praktiken obegränsat i sandbox (dessa gränser konfigureras per borgenär).

5. Betalningar & utbetalningar (demobetalning)

POST /demo--payments finns endast i sandbox — den simulerar en inkommande bankbetalning och anropas med din vanliga token.

En demobetalning adresseras mot OCR-posten, inte mot ärendet. Välj därför först det ärende du vill betala och hämta dess ocr_number_id:

Du harHämta ocr_number_id från
Registreringssvaret (§2)Faktura: _ocr_number · Ärende: _ocr_numbers[n] — samma index som _cases[n]
Bara ett ärende-idGET /ocr-numbers?where={"case.case":"<case_id>"}_items[0]._id
Ett OCR-post-idGET /ocr-numbers/{id} — själva OCR-strängen ligger i fältet ocr

Resursen /ocr-numbers är skrivskyddad. Registreringen returnerar även OCR-strängarna direkt (ocr_number_ocr / _ocr_numbers_ocr[]).

Betala hela saldot, inte bara kapitalet

Ett ärende stängs som fullbetalt först när summan av alla dess transaktioner når noll — kapital, avgifter och ränta. Läs hela saldot från total_remaining_transaction_amount på ärendet och använd det som amount. total_remaining_capital_amount är bara kapitaldelen; betalar du det beloppet blir ärendet delbetalt och stängs inte.

ScenarioSå gör duSå verifierar du
Simulera en gäldenärsbetalning till Amili1. Hämta ocr_number_id för ärendet (ovan)
2. POST /demo--payments { amount, ocr_number_id }
200 med tom body → en köad bankkreditering skapas för ärendet
Ärendet settlar och stängs som betaltAutomatiskt (settlement körs ~varje timme)GET /cases/{id}total_remaining_capital_amount: 0, status: "closed", closed.reason i familjen fully_paid*
Payout-specifikation skapasAutomatiskt vid settlementGET /finance--payout-specifications?where={"references.case":"<id>"} → rader med finance_category (capital, creditor_outlay), amount, booking_date
Aggregerad utbetalning skapasAutomatiskt (aggregering körs dagligen)GET /finance--payouts?where={"creditor":"<id>"} → summeringsrader grupperade per finance_category / period
Följ intäkter (ränta / provision)GET /finance--payouts?where={"creditor":"<id>","finance_category":{"$in":["interest","creditor_commission"]}}Summerade belopp per kategori

Utbetalningstider i sandbox

finance--payout-specifications dyker upp inom ~en timme efter demobetalningen (settlement). De aggregerade finance--payouts dyker upp först när borgenärens payout_interval-period stängs och på en bankdag. I sandbox är intervallen oftast capital och creditor_outlay = daily (en kapitalutbetalning syns nästa bankdag), interest = monthly och creditor_commission = quarterly — så kapital settlar snabbt medan ränta och provision släpar.

6. Uppföljning & avstämning

ScenarioSå gör duSå verifierar du
Exportera öppna ärendenGET /cases?where={"closed":{"$exists":false}}&projection={"state":1,"status":1,"total_remaining_capital_amount":1}&max_results=50_items[] med aktuell state/status/återstående; _meta.total
Exportera stängda ärendenGET /cases?where={"closed.close_date":{"$gt":"Mon, 13 Jan 2026 00:00:00 GMT"}}&sort=-closed.close_date_items[] med closed.reason (betalt vs. förlust)
Koppla en utbetalning tillbaka till ett ärendeGET /finance--payout-specifications?where={"references.case":"<id>"}invoice_number, reference_number, booking_date, references.case

Begränsningar i sandbox — vad du inte kan verifiera fullt ut

OmrådeBeteende i sandbox
BrevGenereras men skickas inte fysiskt
E-postLevereras inte
Kronofogden (enforcement)Ett ärende kan gå in i enforcement-status, men inget exporteras till myndigheten
Bank / utbetalningarInga riktiga betalningar; utbetalningsfiler körs i testläge (valideras men verkställs inte)

Relaterad dokumentation