Knox för Craft CMS

Användning

När en faktura skapas

Tre val, under När fakturering sker:

  • När Commerce slutför ordern — standard.
  • När ordern når en status — för butiker som plockar, packar och sedan fakturerar.
  • Bara på begäran — inget automatiskt; du trycker på knappen eller kör kommandot.

Fakturering sker alltid via kön. Hanteraren för slutförd order lägger jobbet i en try/catch, så ett avbrott hos bokföringen är aldrig kundens problem. Ingenting Knox gör kan förstöra en kassagång.

Du kan också kräva att en order är helt betald innan den faktureras, och begränsa Knox till vissa butiker.

Orderskärmen

Varje slutförd order får en Fortnox-panel inuti Commerce egen orderskärm: fakturanumret som en länk in i Fortnox, totalsumman, verifikatet när den bokförts, momstypen och eventuell anledning till att den stoppats. En order utan faktura får en Skicka till Fortnox-knapp.

Fakturalistan

Knox → Fakturor listar allt Knox skapat eller försökt skapa, filtrerbart på tillstånd:

TillståndBetyder
I FortnoxSkapad, och summorna stämmer.
Stämmer inte med ordernSkapad, men Fortnox summa skiljer sig från vad som debiterades. Båda siffrorna finns på den.
StoppadBygget nekade. Ingenting skickades, och anledningen står på raden.
OkäntFortnox svarade aldrig. Fakturan kan finnas där eller inte.
MisslyckadesFortnox avvisade den. Säker att försöka igen när orsaken är åtgärdad.
PågårEtt försök var igång.

Öppna en för hela avstämningen — debiterat, fakturerat, avrundning, netto, moms, kvar att betala — plus momsmotiveringen och exakt vilken data som skickades.

Aldrig två gånger

En svensk kundfaktura är ett numrerat dokument i en löpande serie. En dubblett är inte en olägenhet; den är en kreditfaktura, en förklaring och en fråga från din revisor.

Därför upprepar Knox aldrig ett skapande den inte kan bevisa misslyckades. En timeout lämnar fakturan som Okänt och stannar. Ingenting gör om det, inte heller du som trycker på knappen igen.

För att lösa det tittar Knox efter:

php craft knox/sync/reconcile

Varje faktura Knox skapar bär Craft-orderns referens i ExternalInvoiceReference1, och Fortnox tillåter filtrering på det fältet — så det här är en uppslagning, inte en gissning. Antingen gör den anspråk på fakturan Fortnox redan har, eller rapporterar att det inte finns någon och att det är säkert att skicka igen. Samma sak finns som knappen Kontrollera mot Fortnox på fakturans detaljsida.

Bokföring

Att bokföra en faktura lägger den i redovisningen och tilldelar ett verifikat. Det går inte att ångra — en bokförd faktura kan krediteras men aldrig ändras eller tas bort — så det är avstängt som standard.

Före bokföring kontrollerar Knox att ett räkenskapsår täcker fakturadatumet. Det här är det vanligaste januarifelet i varje Fortnox-integration: ingen har skapat det nya året än, och Fortnox eget felmeddelande nämner aldrig räkenskapsår. Knox säger:

Fortnox har inget räkenskapsår som täcker 2027-01-04, så faktura 1042 kan inte bokföras. Skapa året i Fortnox och försök igen.

Att trycka på Bokför i kontrollpanelen frågar Fortnox på nytt i stället för att lita på ett cachat svar, vilket är det som gör att ”jag har just fixat det” fungerar direkt.

Betalningar

Två riktningar, och de flesta butiker vill bara ha den ena.

Registrera betalningar i Fortnox — din butik tog pengarna i kassan, så fakturan är redan betald innan den finns. Utan det här fylls Fortnox med obetalda fakturor och kundreskontran blir meningslös. Kräver bokförda fakturor och behörigheten payment.

Läs av betalningar från Fortnox — för butiker som fakturerar mot konto. Kör det schemalagt:

php craft knox/payments/poll

Det är en avläsning och inte en webhook, med flit. Fortnox webhook-täckning är en liten och rörlig uppsättning resurser, och en webhook som aldrig kommer fram går inte att skilja från en lugn vecka — tystnad är det enda felläge en bokföringsintegration inte får ha. En avläsning mot lastmodified kan inte missa något och kostar en handfull anrop per körning.

Valfritt kan en Fortnox-betalning skriva en Commerce-transaktion och flytta ordern till en status. Båda är avstängda som standard: att skriva en transaktion skapar pengar i Commerce redovisning, och en butik som redan tagit betalt i kassan vill inte ha en andra notering om det.

Krediteringar

Med Kreditfakturor vid återbetalning påslaget ger en återbetalning i Commerce en kreditfaktura.

En hel återbetalning använder Fortnox egen krediteringsåtgärd, som kopierar raderna och länkar de två dokumenten. Det är både enklare och mer korrekt än att bygga om dem.

En delvis återbetalning nekas som standard, och säger det. Fortnox dokumenterar kreditering av en hel faktura och publicerar inget sätt att kreditera en del av en, så Knox hittar inte på ett bakom ryggen på dig. Det finns ett valbart läge som skapar en separat länkad kreditfaktura — formen Fortnox egen datamodell beskriver, via en väg de inte dokumenterar. Bekräfta att det fungerar på ditt konto innan du förlitar dig på det.

Två återbetalningar blir två kreditfakturor; samma återbetalning som spelas upp igen blir en. Commerce transaktionshash är det som gör det sant.

Konsolen

php craft knox/connect/status               # vad Knox vet om anslutningen
php craft knox/connect/refresh              # förnya tokens nu
php craft knox/connect/rounding             # läs av företagets öresutjämning

php craft knox/sync/order <orderId> --dry   # vad som skulle skickas, utan att skicka det
php craft knox/sync/order <orderId>         # fakturera en order
php craft knox/sync/backfill --dry          # vad varje ofakturerad order skulle göra
php craft knox/sync/backfill --since=2026-01-01 --queue
php craft knox/sync/reconcile               # lös varje okänt utfall

php craft knox/payments/poll
php craft knox/log/prune
php craft knox/log/last-error               # avslutar med felkod om något är fel

Värda en cron-rad

*/15 * * * * php craft knox/payments/poll
0 3 * * *    php craft knox/sync/reconcile

Och i en butik med lite trafik, en till. Fortnox ogiltigförklarar en refresh-token 45 dagar efter att den utfärdats, och klockan startar om först när den används — så en butik utan ordrar under en lugn säsong kommer tillbaka till en död anslutning:

0 4 * * 0    php craft knox/connect/refresh

Knox varnar också i kontrollpanelen när deadlinen är inom fjorton dagar.

Twig

{% set invoice = craft.knox.invoice(order) %}
{% if invoice and invoice.existsInFortnox() %}
    <p>Faktura {{ invoice.documentNumber }}</p>
    {% set url = craft.knox.downloadUrl(order) %}
    {% if url %}<a href="{{ url }}">Ladda ner PDF</a>{% endif %}
{% endif %}

{# Berätta för en EU-företagsköpare vad som kommer att hända, innan de betalar #}
{% set tax = craft.knox.taxTreatment(cart) %}
{% if tax.zeroRated %}
    <p>Omvänd betalningsskyldighet — ingen moms tas ut.</p>
{% endif %}
MetodReturnerar
craft.knox.invoice(order)Fakturadokumentet, eller null
craft.knox.documents(order)Fakturan och eventuella kreditfakturor
craft.knox.invoiceNumber(order)Fortnox fakturanummer, eller null
craft.knox.downloadUrl(order)En nedladdnings-URL för kunden, eller null
craft.knox.taxTreatment(order)Momstyp, kategori, nollskatteflagga och motivering
craft.knox.isConnected()Om Knox har en levande Fortnox-anslutning

craft.knox är skrivskyddat. Ingenting i det skapar, krediterar eller bokför något — en mallrendering är inte en plats att skriva till någons redovisning från, och en sida som laddats om två gånger får inte ge två fakturor.

Kundnedladdningar hämtar PDF:en från Fortnox på begäran i stället för att cacha den, så en faktura som krediterats eller rättats slutar gå att ladda ner i sin gamla form.