Gå til innhold

Gavekort

Åtte endepunkter dekker hele kortets liv gjennom API'et: utsted, list, slå opp, innløs, omgjør, gjenfs, kanseller og refunder.

Kanseller kan ikke angres. Det finnes ingen reaktivering, fordi et kort som ble avsluttet og senere stille gjenopplivet, er en forpliktelse ingen har sagt ja til. Refunder er det eneste endepunktet som flytter penger: Stripe sender beløpet tilbake til kortet som betalte, og ingen andre steder.

Prøv det her på siden

Konsollen herunder kjører de samme skjemaene og samme innløsningsregel som API'et, mot et kort som bare finnes i nettleseren din. Rett i kroppen, og se hvilken status ditt eget kall ville fått.

Konsollen

Kort
KUV-DLT2-9GPW
Saldo
500,00 DKK
Status
active

Forespørsel

GET /v1/api/giftcards/KUV-DLT2-9GPW

Authorization: Bearer pk_test_…

Ingen kropp. Koden er i stien.

Svar

200 OK

{
  "giftCard": {
    "id": "gc_3n8qk2vh",
    "code": "KUV-DLT2-9GPW",
    "orderId": null,
    "status": "active",
    "initialOre": 50000,
    "balanceOre": 50000,
    "expiresAt": "2029-01-15T12:00:00.000Z",
    "merchantSlug": "cafe-noir",
    "origin": "b2b",
    "reference": "Faktura 2026-114",
    "punchValueOre": null,
    "noCashClaim": false,
    "productName": null
  }
}

Saldoen regnes ut fra posteringene i stedet for å bli lest fra et felt. Derfor stemmer den alltid med innløsningene.

Svar 200 OK. Saldoen regnes ut fra posteringene i stedet for å bli lest fra et felt. Derfor stemmer den alltid med innløsningene.

Konsollen kaller ikke ut på nettet. Den kjører de samme skjemaene og den samme innløsningsregelen som API-et, mot et kort som bare finnes i nettleseren din. Statuskoder og feilmeldinger er derfor de samme som din egen integrasjon får.

Idempotens

Utsted og innløs kan begge ha en nøkkel som gjør kallet trygt å gjenta. Samme nøkkel to ganger svarer med resultatet fra den FØRSTE gangen (samme kort, samme postering) i stedet for å utstede eller trekke to ganger. De to verbene oppdager likevel ikke det samme: ved INNLØS svarer vi 409 idempotency_key_conflict hvis nøkkelen allerede er brukt på et annet kort eller på en utbetaling, i stedet for å treffe feil. Ved UTSTED sammenligner vi ikke kallet. Gjenbruker du en nøkkel med et annet beløp, får du 201 og det FØRSTE kortets data tilbake, uten feil. Bruk én nøkkel pr. kort.

Nøkkelen kan stå tre steder. Vi leser idempotencyKey i kroppen først, og ellers headeren Idempotency-Key og deretter X-Request-Guid. Kroppen vinner når det er både og.

HvorNavn
KroppenidempotencyKey: det eksplisitte valget, og det som vinner.
HeaderIdempotency-Key: navnet Stripe har gjort til standard.
HeaderX-Request-Guid, så en integrasjon som flytter fra Lifepeaks, virker uten å skrives om.

Utsted et kort

POST/v1/api/giftcards

Utsteder et kort utenom betalingsflyten, for eksempel solgt fra ditt eget system, fakturert til en bedrift eller gitt bort på huset.

origin er påkrevd her, hvor det er valgfritt i dashbordet. Et system utsteder uten at noen ser på, og valget følger kortet resten av dets levetid: sold betyr at en kunde har betalt for det, og så bærer kortet kundens rett til å få restbeløpet utbetalt kontant. b2b og comp gjør ikke.

curl -X POST https://api.kuvert.dk/v1/api/giftcards \
  -H "Authorization: Bearer $KUVERT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amountOre": 50000,
    "origin": "b2b",
    "reference": "Faktura 2026-114",
    "idempotencyKey": "faktura-2026-114"
  }'
201 CreatedJSON
{
  "giftCard": {
    "id": "gc_4f1c9a2e7b3d48e6a0c5d9f2b8e1a7c3",
    "code": "KUV-7K9F-2XQD",
    "orderId": null,
    "status": "active",
    "initialOre": 50000,
    "balanceOre": 50000,
    "expiresAt": "2029-09-29T08:00:00.000Z",
    "merchantSlug": "cafe-noir",
    "origin": "b2b",
    "reference": "Faktura 2026-114",
    "punchValueOre": null,
    "noCashClaim": false,
    "productName": null
  }
}
Prøv det i konsollen

Kropp

amountOreintegerPåkrevd
Kortets verdi i øre, minst 1 øre og høyst 100.000,00 DKK.
origin"sold" | "b2b" | "comp"Påkrevd
sold: en kunde har betalt. b2b: fakturert til en bedrift. comp: spandert av huset.
validityMonthsintegerValgfri
Gyldighet i måneder, minst 36 og høyst 600. Utelates den, gjelder kortet i 36.
referencestring | nullValgfri
Ditt eget notat, for eksempel et fakturanummer. Høyst 200 tegn.
noCashClaimbooleanValgfri
Merk kortet «kan ikke byttes inn i kontanter», for eksempel når det gjelder en bestemt ting. Det gjør ikke i seg selv en ansattgave skattefri: SKAT, den danske skattemyndigheten, regner digitale gavekort som skattepliktige. Bare på b2b og comp.
idempotencyKeystringValgfri
Samme nøkkel to ganger utsteder bare ett kort. Høyst 120 tegn. Kan også sendes som header (se Idempotens).

Svarfelter

Kortet ligger under giftCard, i samme form som ved Slå et kort opp, der feltene er beskrevet.

Statuskoder

  • 201

    Kortet er utstedt. Med en idempotencyKey som er brukt før, er svaret kortet nøkkelen utstedte første gang.

  • 400invalid_issue_request

    Kroppen stemmer ikke med det utstedelse krever.

  • 404merchant_not_found

    Nøkkelen er gyldig, men bedriften bak den finnes ikke lenger. Det skjer sjelden og kan ikke rettes av en klient. Kontakt oss.

  • 409cash_claim_cannot_be_denied

    noCashClaim på et sold-kort. Kunden har betalt, og retten til å få restbeløpet utbetalt kan et flagg ikke fjerne.

En feil har alltid formen { "error": "…" }. Alle kall kan dessuten svare 401, 403, 429 og 500. Se Feil.

List kort

GET/v1/api/giftcards

Alle bedriftens kort, nyeste først, med saldoen regnet ut fra posteringene i samme øyeblikk. Listen er ikke sidedelt.

curl https://api.kuvert.dk/v1/api/giftcards \
  -H "Authorization: Bearer $KUVERT_API_KEY"
200 OKJSON
{
  "giftCards": [
    {
      "id": "gc_4f1c9a2e7b3d48e6a0c5d9f2b8e1a7c3",
      "code": "KUV-7K9F-2XQD",
      "orderId": null,
      "status": "active",
      "initialOre": 50000,
      "balanceOre": 50000,
      "expiresAt": "2029-09-29T08:00:00.000Z",
      "merchantSlug": "cafe-noir",
      "origin": "b2b",
      "reference": "Faktura 2026-114",
      "punchValueOre": null,
      "noCashClaim": false,
      "productName": null
    },
    {
      "id": "gc_9b2e61d04c7f4a3e8d5b1c6a0f2e9d47",
      "code": "KUV-M4TQ-8WZR",
      "orderId": "ord_7d3f0b9c1e2a45f68b4c9d0e1f2a3b5c",
      "status": "active",
      "initialOre": 50000,
      "balanceOre": 43600,
      "expiresAt": "2029-06-12T14:31:07.000Z",
      "merchantSlug": "cafe-noir",
      "origin": "paid",
      "reference": null,
      "punchValueOre": null,
      "noCashClaim": false,
      "productName": "Gavekort"
    }
  ]
}

Svarfelter

Kortene ligger under giftCards, hvert i samme form som ved Slå et kort opp.

Statuskoder

  • 200

    Listen, eventuelt tom.

En feil har alltid formen { "error": "…" }. Alle kall kan dessuten svare 401, 403, 429 og 500. Se Feil.

Slå et kort opp

GET/v1/api/giftcards/{code}

Et kort ut fra koden, med saldoen slik den står akkurat nå.

curl https://api.kuvert.dk/v1/api/giftcards/KUV-7K9F-2XQD \
  -H "Authorization: Bearer $KUVERT_API_KEY"
200 OKJSON
{
  "giftCard": {
    "id": "gc_4f1c9a2e7b3d48e6a0c5d9f2b8e1a7c3",
    "code": "KUV-7K9F-2XQD",
    "orderId": null,
    "status": "active",
    "initialOre": 50000,
    "balanceOre": 50000,
    "expiresAt": "2029-09-29T08:00:00.000Z",
    "merchantSlug": "cafe-noir",
    "origin": "b2b",
    "reference": "Faktura 2026-114",
    "punchValueOre": null,
    "noCashClaim": false,
    "productName": null
  }
}
Prøv det i konsollen

Stiparametere

codestringPåkrevd
Kortets kode, for eksempel KUV-7K9F-2XQD.

Svarfelter

Kortet ligger under giftCard:

idstring
Kortets id (gc_…). Det er koden du slår opp med.
codestring
Koden som står på kortet.
orderIdstring | null
Ordren kortet kom fra. null for et kort utstedt for hånd eller gjennom API'et.
status"active" | "redeemed" | "expired" | "void" | "disputed"
Kortets tilstand. Bare active kan innløses.
initialOreinteger
Kortets verdi i øre, før noe er innløst.
balanceOreinteger
Saldoen i øre, regnet ut fra posteringene og ikke lest fra et felt.
expiresAtstring
Når kortet utløper, ISO 8601 i UTC.
merchantSlugstring
Butikkens adresse på shop.kuvert.dk.
origin"paid" | "sold" | "b2b" | "corporate" | "comp"
Hvor verdien kom fra. paid er kjøpt i butikken og corporate kjøpt som bedriftsgave; sold, b2b og comp er utstedt for hånd eller gjennom API'et.
referencestring | null
Ditt eget notat fra utstedelsen. null på et kjøpt kort.
punchValueOreinteger | null
Verdien av ett klipp hvis kortet er et klippekort, ellers null. Et klippekort løses inn i hele klipp.
noCashClaimboolean
Kortet kan ikke byttes inn i kontanter.
productNamestring | null
Produktets navn slik det lød da kortet ble utstedt. null på et kort utstedt for hånd.

Statuskoder

  • 200

    Kortet.

  • 400not_a_gift_card

    Koden i stien er en billettkode (TKT-…), ikke et gavekort.

  • 404gift_card_not_found

    Koden finnes ikke på din bedrift.

En feil har alltid formen { "error": "…" }. Alle kall kan dessuten svare 401, 403, 429 og 500. Se Feil.

Innløs

POST/v1/api/giftcards/{code}/redeem

Trekker et beløp fra kortets saldo. Koden står i stien, beløpet i kroppen.

Gem id. Det er posteringen, og det er det eneste som kan angre nettopp denne innløsningen.

Går det ikke igjennom, er svaret én av disse. De er ikke like for kassen: noen er noe gjesten skal ha vite, og noen er noe bedriften skal ringes opp om.

curl -X POST https://api.kuvert.dk/v1/api/giftcards/KUV-7K9F-2XQD/redeem \
  -H "Authorization: Bearer $KUVERT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amountOre": 6400,
    "location": "Vesterbro",
    "idempotencyKey": "pos-3-20260929-0142"
  }'
200 OKJSON
{
  "id": "red_8f21c0b45d3e4a9b8c7d6e5f4a3b2c1d",
  "code": "KUV-7K9F-2XQD",
  "amountOre": 6400,
  "remainingBalanceOre": 43600,
  "status": "active"
}
Prøv det i konsollen

Stiparametere

codestringPåkrevd
Kortets kode, for eksempel KUV-7K9F-2XQD.

Kropp

amountOreintegerPåkrevd
Beløpet i øre, minst 1. Et klippekort tar bare et helt antall klipp.
locationstring | nullValgfri
Hvor det skjedde, for eksempel «Vesterbro». Høyst 120 tegn.
idempotencyKeystringValgfri
Samme nøkkel to ganger trekker bare én gang. Høyst 120 tegn. Kan også sendes som header (se Idempotens).

Svarfelter

Svaret er posteringen:

idstring
Posteringens id (red_…), som du angrer den med.
codestring
Kortets kode.
amountOreinteger
Det trukne beløpet i øre.
remainingBalanceOreinteger
Saldoen etter innløsningen.
status"active" | "redeemed" | "expired" | "void" | "disputed"
status er kortets tilstand etter innløsningen, en av active, redeemed, expired, void, disputed. Er saldoen brukt opp, skifter den til redeemed.

Statuskoder

  • 200

    Beløpet er trukket. Med en idempotencyKey som er brukt før på samme kort, er svaret det fra første gang, uten at det trekkes igjen.

  • 400invalid_redeem_request

    Kroppen stemmer ikke med det innløsning krever, typisk et beløp som ikke er et helt antall øre, eller som er null.

  • 400not_a_gift_card

    Koden i stien er en billettkode (TKT-…), ikke et gavekort.

  • 404gift_card_not_found

    Koden finnes ikke på din bedrift.

  • 409card_inactive

    Kortet er ikke aktivt: brukt opp, annullert, satt til utløpt eller fryst under en innsigelse. Det går ikke over av seg selv, så bedriften må kontaktes.

  • 409redeem_too_soon

    Bedriften har satt en innløsningsforsinkelse, og den er ikke utløpt ennå. Kortet feiler ingenting; det kan bare ikke brukes ennå. Prøv igjen senere.

  • 409idempotency_key_conflict

    Nøkkelen er allerede brukt på et annet kort eller på en utbetaling fra det samme kortet. Se Idempotens.

  • 410gift_card_expired

    Kortet står stadig som aktivt, men gyldighetssdatoen er passert. Til forskjell fra card_inactive er det tiden og ikke en beslutning som har lukket kortet.

  • 422insufficient_balance

    Beløpet er større enn saldoen. Vi trekker aldri et delbeløp på eget initiativ. Slå opp kortet, trekk saldoen, og ta resten på annen måte.

  • 422invalid_amount

    Innløsningsregelen sitt eget svar på et ulovlig beløp. Skjemaet fanger det normalt allerede som 400 invalid_redeem_request, så en klient bør kunne lese begge.

  • 422punch_amount_not_whole

    Kortet er et klippekort, og beløpet er ikke et helt antall klipp. Det er ikke noe galt med tallet, men det er feil type kort for det. Slå opp kortet, les punchValueOre, og send den verdien eller et multiplum av den. Et klippekort som står igjen med en rest under ett klipp, er penger verken kassen eller kunden kan nå.

En feil har alltid formen { "error": "…" }. Alle kall kan dessuten svare 401, 403, 429 og 500. Se Feil.

Angre en innløsning

POST/v1/api/redemptions/{id}/reverse

Legger beløpet tilbake på kortet. Det skjer som en ny postering med negativt beløp, som peker på den den angrer. Ingenting slettes, og begge linjene blir stående i kortets historikk. Var kortet brukt helt opp, blir det aktivt igjen.

curl -X POST https://api.kuvert.dk/v1/api/redemptions/red_8f21c0b45d3e4a9b8c7d6e5f4a3b2c1d/reverse \
  -H "Authorization: Bearer $KUVERT_API_KEY"
200 OKJSON
{
  "id": "red_2c77af90e1d24b3c9a8f7e6d5c4b3a21",
  "code": "KUV-7K9F-2XQD",
  "amountOre": -6400,
  "remainingBalanceOre": 50000,
  "status": "active"
}

Stiparametere

idstringPåkrevd
Innløsningens id (red_…), som du fikk tilbake fra Innløs.

Svarfelter

Svaret er posteringen som la beløpet tilbake, i samme form som ved Innløs, med negativt amountOre.

Statuskoder

  • 200

    Beløpet er lagt tilbake.

  • 404redemption_not_found

    Posteringen finnes ikke på din bedrift.

  • 409already_reversed

    Den er angret før. Én gang, aldri to.

  • 409not_reversible

    Posteringen er selv en angring eller en kontant utbetaling.

  • 409card_inactive

    Kortet er annullert eller fryst under en innsigelse.

  • 409order_refunded

    Ordren bak kortet er refundert. Kjøperen har allerede fått pengene tilbake, så en angring ville gi dem verdien to ganger.

En feil har alltid formen { "error": "…" }. Alle kall kan dessuten svare 401, 403, 429 og 500. Se Feil.

Brukes ofte sammen med

Send kortet igjen

POST/v1/api/giftcards/{code}/resend

Sender kortet til mottakeren på nytt. Det er det en kasse gjør når en kunde sier at e-posten aldri kom.

Uten recipient sender vi det kortets ordre ennå ikke har fått levert, til adressen som står på det. Et kort som allerede er levert, sendes ikke på nytt. Med recipient retter du adressen på akkurat dette kortet og sender det dit, også hvis det er levert før. Bare aktive kort sendes.

curl -X POST https://api.kuvert.dk/v1/api/giftcards/KUV-M4TQ-8WZR/resend \
  -H "Authorization: Bearer $KUVERT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": "ny-adresse@dit-domaene.dk"
  }'
200 OKJSON
{
  "delivered": 1
}

Stiparametere

codestringPåkrevd
Kortets kode, for eksempel KUV-7K9F-2XQD.

Kropp

recipientstringValgfri
En ny e-postadresse til kortet. Kroppen kan utelates helt.

Svarfelter

Svaret sier hvor mye som ble sendt:

deliveredinteger
Antall kort som ble sendt. 0 betyr at det ikke var noe å sende.

Statuskoder

  • 200

    Sendt, eller ingenting å sende.

  • 400not_a_gift_card

    Koden i stien er en billettkode (TKT-…), ikke et gavekort.

  • 404gift_card_not_found

    Koden finnes ikke på din bedrift.

  • 404order_not_found

    Gjenfs fant kortet, men ikke ordren det kom fra. Et kort utstedt i hånden har ingen ordre og kan derfor ikke gensendes på den måten.

  • 409card_has_no_delivery

    Kortet har aldri blitt sendt av oss, for det ble utlevert over disken. Det er ingen levering å gjenta.

  • 422invalid_recipient

    recipient i kroppen på gjenfs er ikke en e-postadresse vi kan sende til. Utelat feltet for å sende til den adressen kortet allerede står med.

  • 502delivery_failed

    Vi nådde leverandøren vår, og den avviste forsendelsen. Det er ingenting galt med kortet, og ingenting er trukket. Prøv igjen, eller kontroller adressen.

En feil har alltid formen { "error": "…" }. Alle kall kan dessuten svare 401, 403, 429 og 500. Se Feil.

Brukes ofte sammen med

Annuller et kort

POST/v1/api/giftcards/{code}/cancel

Annullerer kortet med en gang. Saldoen blir stående på kortet, men kan ikke lenger brukes, og det kan ikke angres. Er kortet allerede annullert, får du det tilbake slik det er, uten feil.

curl -X POST https://api.kuvert.dk/v1/api/giftcards/KUV-7K9F-2XQD/cancel \
  -H "Authorization: Bearer $KUVERT_API_KEY"
200 OKJSON
{
  "giftCard": {
    "id": "gc_4f1c9a2e7b3d48e6a0c5d9f2b8e1a7c3",
    "code": "KUV-7K9F-2XQD",
    "orderId": null,
    "status": "void",
    "initialOre": 50000,
    "balanceOre": 50000,
    "expiresAt": "2029-09-29T08:00:00.000Z",
    "merchantSlug": "cafe-noir",
    "origin": "b2b",
    "reference": "Faktura 2026-114",
    "punchValueOre": null,
    "noCashClaim": false,
    "productName": null
  }
}

Stiparametere

codestringPåkrevd
Kortets kode, for eksempel KUV-7K9F-2XQD.

Svarfelter

Kortet ligger under giftCard, nå med status void.

Statuskoder

  • 200

    Kortet er annullert, eller var det allerede.

  • 400not_a_gift_card

    Koden i stien er en billettkode (TKT-…), ikke et gavekort.

  • 404gift_card_not_found

    Koden finnes ikke på din bedrift.

En feil har alltid formen { "error": "…" }. Alle kall kan dessuten svare 401, 403, 429 og 500. Se Feil.

Refunder en ordre

POST/v1/api/orders/{id}/refund

Sender hele betalingen for ordren tilbake til kortet som betalte, med kjøperens ekspedisjonsgebyr, og Kuverts gebyr på salget går tilbake til deg. Det er det eneste endepunktet som flytter penger.

Når Stripe har bekreftet refusjonen, tas verdien av ordrens kort, billettene annulleres, og order.refunded sendes. Det skjer som regel noen sekunder etter svaret.

Kallet tar ingen idempotensnøkkel, fordi ordrens egen status er sperren. En ordre som allerede er refundert, svarer 409 order_not_refundable.

curl -X POST https://api.kuvert.dk/v1/api/orders/ord_7d3f0b9c1e2a45f68b4c9d0e1f2a3b5c/refund \
  -H "Authorization: Bearer $KUVERT_API_KEY"
200 OKJSON
{
  "orderId": "ord_7d3f0b9c1e2a45f68b4c9d0e1f2a3b5c",
  "refundId": "re_3PqX9aLkT2mN8vRb1c4D7eFg",
  "amountOre": 50500
}

Stiparametere

idstringPåkrevd
Ordrens id (ord_…): orderId på kortet eller i order.paid.

Svarfelter

Svaret er refusjonen slik Stripe tok imot den:

orderIdstring
Ordren.
refundIdstring
Stripes id for refusjonen (re_…), som du finner den under i Stripe.
amountOreinteger
Beløpet som sendes tilbake, i øre.

Statuskoder

  • 200

    Stripe har tatt imot refusjonen.

  • 404order_not_found

    Ordren finnes ikke hos bedriften din.

  • 409order_not_refundable

    Ordren kan ikke refunderes: den er ikke betalt, allerede refundert eller frosset under en innsigelse.

  • 409merchant_not_payment_ready

    Stripe-kontoen din er ikke koblet til.

  • 503stripe_not_configured

    Betalinger er midlertidig utilgjengelige hos oss. Prøv igjen senere.

En feil har alltid formen { "error": "…" }. Alle kall kan dessuten svare 401, 403, 429 og 500. Se Feil.

Var siden nyttig?