Innan du börjar
Anropa Custas från din backend, aldrig från webbläsaren
En API-nyckel kan lösa in presentkort och läsa medlemsdata, så den får aldrig hamna i en webbläsare. API:et tar ändå inte emot anrop från andra webbplatsers sidor: dess CORS-policy tillåter bara Custas-portalen. Din butiksfront pratar med din backend, och din backend pratar med Custas.
En nyckel med webbshopens behörigheter
| Behörighet | Används till |
|---|---|
members:read |
Slå upp medlemmar, poäng, stämpelkort och Wallet-kort |
members:write |
Skapa medlemmar, registrera samtycke, varukorgshändelser (§8) |
carts:evaluate |
Prissättning |
redemptions:write |
Reservera, slutföra, släppa, returer, återföring |
redemptions:read |
Hitta köpet för en order; orderhistorik i Mitt konto |
giftcards:read, giftcards:write |
Presentkortssaldo; sälja, mejla och återbetala presentkort (bara om du tar emot eller säljer dem) |
settings:read |
Identitetsregler och samtyckestexter |
messaging:write (valfri) |
Mejl för dubbel opt-in, mejla ett presentkort som sålts |
Bygg mot en cust_test_…-nyckel: testmiljön är helt separat från live.
Nycklarna har en anropsgräns per minut som beror på planen (Starter 60, Growth 600,
Enterprise 6 000 anrop), vilket spelar roll för prissättningen (§3).
Samma konventioner som i en kassa
-
Belopp anges som heltal i minsta valutaenhet (
19900är 199,00 kr), priser är inklusive moms om inte handlaren använder nettopriser, och den momsfördelning som Custas returnerar är den du ska visa och fakturera. -
Idempotency-Keykrävs när du reserverar, slutför, släpper, återför och gör returer, och när du utfärdar och mejlar presentkort. Härled den från din order, till exempelWEB-100231-commit, så att ett nytt försök, en dubbelklickad knapp och en betalningswebhook som kommer samtidigt som omdirigeringen alla skickar samma nyckel. -
Varje varukorg anger
"channel": "online"och ett stabiltstoreIdför webbshopen, till exempel"web". Kampanjer kan begränsas till kanaler och butiker, så kom överens med handlaren om id:t: ett erbjudande som bara gäller fysiska butiker gäller då, som det ska, inte online.
1. Kundkonton och medlemmar
En kassa känner igen en medlem på ett kort eller ett telefonnummer som hen visar upp. En webbshop känner sina kunder genom deras kundkonto, och det är inloggningen som avgör vem de är. Koppla ihop de två en gång och använd sedan medlemmens id.
Koppla en inloggad kund till rätt medlem
POST /v1/members/lookup
{ "keyType": "email", "value": "anna.svensson@example.com" }
# → 200: medlemmen, med "id". Spara det på kundkontot.
# → 404: inte medlem än. Erbjud medlemskap (§2).
- Slå bara upp den verifierade e-postadressen för ett inloggat konto: en adress som din webbshop har bekräftat att kunden har kontroll över, till exempel med en bekräftelselänk när kontot skapades.
-
Spara medlemmens
idpå kundkontot och använd det överallt efter det. Om kunden byter e-postadress i din webbshop håller kopplingen ändå. -
Be handlaren göra
emailtill en unik identifierare i identitetsreglerna (GET /v1/tenant/identity-rulesvisar dem). Om den inte är unik kan två medlemmar dela adress, och då returnerar en uppslagning en av dem.
Låt aldrig en anonym besökare utlösa en uppslagning. Uppslagningen returnerar medlemmens poäng, nivå och köpbelopp, och Custas kan inte avgöra åt din webbshop att den som skriver in en e-postadress också äger den. Ett fält i gästkassan för ”din medlemsadress” skulle låta vem som helst kolla vem som är medlem, se saldot och använda poängen. Gäster handlar som gäster; medlemsförmåner kräver ett inloggat konto.
Gäster
Prissätt en gästs varukorg utan member. Publika kampanjer och rabattkoder
gäller fortfarande; erbjudanden för medlemmar och nivåer gör det inte. Efter ordern
kan du erbjuda kunden att skapa ett konto och gå med, så att nästa order ger poäng.
2. Registrering och samtycke
Skapa medlemmen när en kund går med i lojalitetsprogrammet: när kontot skapas, eller med en kryssruta ”gå med och tjäna poäng” i kassan. Även här bara för en e-postadress som din webbshop har verifierat.
POST /v1/members
{
"displayName": "Anna Svensson",
"locale": "sv-SE",
"country": "SE",
"externalRef": "shop-customer-58213", # ditt eget kund-id, unikt per handlare
"identities": [
{ "keyType": "email", "value": "anna.svensson@example.com", "isPrimary": true }
],
"attributes": { "signupChannel": "web" }
}
-
Skicka alla identifierartyper som identitetsreglerna markerar som obligatoriska. Ett
formulär som bara frågar efter e-post misslyckas med
422om handlaren kräver telefonnummer. -
409 identity_conflict: e-postadressen tillhör redan en medlem, kanske någon som gick med i en butik. Slå upp hen och koppla den medlemmen; skapa ingen ny. -
Det här anropet tar ingen
Idempotency-Key. Om svaret försvinner är ett nytt försök ändå säkert: det andra försöket svarar409(e-postadressen eller dittexternalRefär upptaget), och då slår du upp medlemmen.
Marknadsföringssamtycke: en egen fråga, inte förkryssad
Att gå med i programmet är inte samtycke till marknadsföring. Fråga med en egen
kryssruta, inte förkryssad, som visar den exakta texten i handlarens aktiva
samtyckestext (GET /v1/consent-wordings). Registrera bara ett ja:
PUT /v1/members/{id}/consents/email/marketing
{
"state": "granted",
"source": "api",
"sourceDetail": "webshop sign-up form, shop.example.com",
"wordingId": "0199a4f1-…",
"actor": "customer:shop-customer-58213"
}
-
sourceärapiför en webbshop. Beskriv var det skedde isourceDetail; det är en del av bevisningen. - Custas registrerar anropets IP-adress och user agent, som här är din servers, inte kundens. Vill du spara kundens egen IP-adress i din dokumentation får du lagra den själv.
-
Dubbel opt-in är starkare bevis online, där vem som helst kan
skriva in vems adress som helst. Skicka den i stället för att registrera samtycket
direkt:
POST /v1/members/{id}/consent-confirmationsmedchannel,purpose,templateKeyochwordingId(krävermessaging:write). Kunden bekräftar på en sida hos Custas, och länken fungerar i sju dagar. -
Om handlaren har satt en lägsta ålder för marknadsföring och medlemmen enligt sitt
födelsedatum är yngre än så, svarar ett samtycke
422medreason: "below_marketing_min_age". Själva medlemskapet har ingen åldersgräns. -
Erbjud återkallelse i kontoinställningarna också (
"state": "withdrawn"). Den nekas aldrig.
3. Prissätt varukorgen
Utvärdera när varukorgssidan visas, när varukorgen eller en rabattkod ändras, och i varje steg i kassan som ändrar frakt eller betalmedel. Anropet läser bara och reserverar ingenting.
POST /v1/carts/evaluate
{
"currency": "SEK",
"channel": "online",
"storeId": "web",
"country": "SE",
"member": { "memberId": "0199a4f0-1c2d-7e3f-8a4b-5c6d7e8f9a0b" },
"codes": ["SUMMER20"],
"lines": [
{ "id": "item-8812", "sku": "TSH-SPORT-2PK", "quantity": 2,
"unitPriceMinor": 19900, "taxRateBp": 2500,
"categories": ["clothing"], "brands": ["Acme"], "description": "Sport T-shirt (2-pack)" }
],
"shipping": { "methodId": "postnord-home", "amountMinor": 4900, "taxRateBp": 2500 }
}
-
Rad-id:n är stabila under hela varukorgens livstid: använd ditt
eget id för varukorgsraden, inte radens position. Skicka alla attribut som kampanjer
kan rikta sig mot (
categories,brands,collections,tags,isSale,productId,variantId), som i kassasystemguiden. -
Frakt skickas i
shipping, med egen momssats, inte som en rad. Kampanjer för fri frakt och fraktrabatt verkar på den, och prisberäkningen returnerarshippingMinorochshippingDiscountMinor. -
excludeFromDiscounts: trueför allt som webbshopen aldrig rabatterar;isGiftCard: trueför presentkort som säljs (§10). - Tänk på anropsgränsen. Utvärdera vid händelser, inte vid varje rendering, och återanvänd den senaste prisberäkningen så länge varukorgen inte har ändrats. Med Starters 60 anrop per minut tar det snabbt slut om du räknar om vid varje sidvisning.
Fältet för rabattkod
Lägg det kunden skrev i codes. Stora och små bokstäver, mellanslag,
bindestreck och förväxlingsbara I/L/O förlåts. En kod som inte gäller får aldrig
anropet att misslyckas: resten av varukorgen prissätts, och koden kommer tillbaka i
rejectedCodes med en orsak som du kan förklara under fältet.
reason |
Säg till kunden |
|---|---|
not_found |
Den koden finns inte |
not_started, expired |
Den koden gäller inte än / inte längre |
exhausted, budget_exhausted |
Erbjudandet är slut |
member_limit_reached |
Du har redan använt koden så många gånger som det går |
assigned_to_other_member |
Det här är en personlig kod för någon annan |
no_member |
Logga in för att använda den här medlemskoden |
wrong_channel, wrong_store |
Den här koden gäller i butik |
below_min_subtotal |
Handla för lite mer för att kunna använda koden |
combination_conflict |
Den här koden kan inte kombineras med ditt andra erbjudande |
| allt annat | Den koden kan inte användas på den här ordern |
Nya orsaker kan tillkomma, så ha alltid med den sista raden. Vill du ta reda på varför
ett automatiskt erbjudande inte gällde kan du lägga till ?explain=true
medan du felsöker.
Visa prisberäkningens priser per rad, appliedPromotions och
vatBreakdown som de är, och spara quoteHash till när ordern
läggs.
4. Presentkort och poäng som betalning
Båda är betalmedel i samma varukorg, precis som i en kassa (kassasystemguiden §4): de minskar amountDueMinor, och resten tar du betalt för via din
betalleverantör.
"tenders": [
{ "type": "gift_card", "code": "GC-7Q4M-XK2P-9TND" },
{ "type": "points", "points": 500 }
]
-
Poäng bara för en inloggad medlem. Visa vad de är värda med
GET /v1/members/{id}/points(redeemablePoints,redeemableMinor). Poäng kan inte användas för att betala presentkort som köps. - Presentkort har ingen PIN-kod: koden räcker för att använda saldot. Skydda presentkortsfältet mot botar på samma sätt som din inloggning (en CAPTCHA och en gräns per besökare), och visa aldrig saldot för en kod för en besökare som inte har lagt den på sin egen order.
-
Ett avvisat betalmedel anger orsaken i
reason(not_found,expired,no_balance, …). Resten av ordern kan fortfarande betalas.
5. Lägg order och betala
Skillnaden mot en kassa: en onlinebetalning tar tid och bekräftas asynkront, ofta med en webhook från din betalleverantör, flera minuter efter att kunden lämnade kassan. Custas håller rabatterna, kodanvändningarna, presentkortsbeloppen och poängen reserverade under tiden, så att ingen annan kan ta dem.
Reservera när kunden trycker på ”Lägg order”
Utvärdera en sista gång med den slutliga varukorgen och reservera sedan mot den prisberäkningen:
POST /v1/redemptions
Idempotency-Key: WEB-100231-1-reserve
{
"cart": { …exakt den varukorg du nyss utvärderade… },
"quoteHash": "7f3a9c…e21b",
"externalRef": "WEB-100231-1",
"ttlSeconds": 1800
}
-
Varje
409innehåller en nyquote: priset har ändrats sedan kunden senast såg det (en kod tog slut, ett erbjudande upphörde, handlaren ändrade en kampanj). Visa den nya totalsumman, låt kunden bekräfta och reservera igen påquote.quoteHashmed en ny nyckel. Det är samma enda väg som i en kassa (kassasystemguiden §5). -
Spara reservationens
idpå ordern och debitera dessamountDueMinor, där presentkort och poäng redan är avdragna. -
En order från en gäst utan rabatt, kod, presentkort eller poäng har inget att
reservera, och att reservera den ger svaret
409 conflict. Hoppa över Custas för sådana ordrar.
externalRef: ditt ordernummer plus ett försöksnummer
externalRef är unikt per handlare, inklusive
reservationer som har släppts eller löpt ut. Om kundens första betalning misslyckas
och hen försöker igen behöver ordern en ny reservation, och den kan inte återanvända
samma referens. Använd ordernumret med en försöksräknare (WEB-100231-1,
WEB-100231-2, …). För att hitta köpet senare söker du på referensen för
det försök som slutfördes, och den har du sparat på ordern.
ttlSeconds: längre än betalningen kan ta
Reservationen gäller i ttlSeconds: 900 (15 minuter) som standard och
högst 3600 (en timme). Den kan inte förlängas. Välj ett värde som täcker den längsta
tid din betalsida kan vara öppen, och
låt betalsessionen gå ut innan reservationen gör det. De flesta
betalleverantörer låter dig ställa in sessionens livslängd. Då kan en kund aldrig
betala efter att rabatterna hen blev lovad har gått tillbaka till poolen.
Slutför (commit) när betalleverantören bekräftar
POST /v1/redemptions/{id}/commit
Idempotency-Key: WEB-100231-1-commit
{
"payments": [
{ "method": "invoice", "label": "Klarna", "reference": "kl-7f2a91c0",
"amountMinor": 33740 }
]
}
- Slutför från det ställe där du får veta att betalningen lyckades: omdirigeringen tillbaka till webbshopen, leverantörens webhook eller båda. Båda skickar samma Idempotency-Key, så den som kommer sist får samma svar som den första, och köpet slutförs bara en gång.
-
paymentsmåste summera till reservationensamountDueMinor.methodärcard,swish,invoice,voucherellerother. Ange leverantören ilabel("Klarna","PayPal") och dess transaktions-id ireference. För kort skickar du bara det maskerade numret om du har det: ett fullständigt kortnummer nekas. -
receiptär valfritt och byggt för kassor: dessnumberär ett löpnummer för kvitton i form av ett heltal. Utelämna det om inte handlaren skickar digitala kvitton till Kivra; ditt ordernummer finns redan iexternalRef. - Slutför även när inget rabatterades, för en inloggad medlem. Det är så hen tjänar poäng och stämplar, och så räknas ordern in i hens historik.
Släpp när betalningen misslyckas eller avbryts
POST /v1/redemptions/{id}/release
Idempotency-Key: WEB-100231-1-release
{ "reason": "cancelled" }
Släpp så fort du vet: när leverantören rapporterar ett fel eller när betalsessionen går ut. Då går en kods sista användning direkt till nästa kund, i stället för först när reservationen löper ut.
Referens: inlösen (redemptions)6. När betalningen bekräftas efter att reservationen löpt ut
Om betalsessionen trots allt varade längre än reservationen svarar commit-anropet
409 reservation_not_held, och kunden har betalat. Custas kan inte
slutföra ett köp vars rabatter har gått tillbaka till poolen, så:
-
Utvärdera orderns varukorg igen och reservera den under nästa försöks referens
(
WEB-100231-2). -
Om det nya
amountDueMinorär lika med det kunden betalade slutför du direkt. Inget går förlorat. -
Om det är högre (en kod tog slut under tiden) släpper du reservationen. Leverera
ordern till det pris kunden betalade, vilket är en sak mellan dig och kunden, och ge
kunden poäng för ordern utan rabatten:
POST /v1/members/{id}/points/earnmedamountMinoroch det rena ordernumret somexternalRef(WEB-100231). Anropet är idempotent på den referensen, och den får inte vara en som en reservation redan har använt.
Prenumerera på redemption.released. En leverans med
reason: "ttl" för en order som du fortfarande ser som öppen är din tidiga
varning om att reservationen har löpt ut.
7. Mitt konto
För en inloggad medlem fungerar de här med webbshopens nyckel:
GET /v1/members/{id}/points # saldo, värde, nivå, poäng som snart går ut
GET /v1/members/{id}/stamp-cards # stämplar och intjänade belöningskoder
GET /v1/members/{id}/wallet/google # → { "saveUrl" } för en knapp ”Lägg till i Google Wallet”
GET /v1/members/{id}/wallet/apple # → .pkpass för ”Lägg till i Apple Wallet”
GET /v1/redemptions?memberId={id} # köp med Custas-förmåner, nyaste först
-
Belöningskoder från stämpelkort med
status: "active"är medlemmens att använda: visa dem på kontot, så gäller de när de skrivs in i kodfältet. - Poäng som tjänats in på en order kan användas direkt; det finns ingen väntetid.
- Medlemmens personliga erbjudanden är inte tillgängliga för en API-nyckel. De visas i Custas medlemsapp, så länka till den från kontosidan.
8. Övergivna varukorgar
För att skicka ”du har glömt något i varukorgen” berättar du för Custas vad en inloggad medlem har i sin varukorg, från din backend, varje gång den ändras. Handlaren ställer in en automation för kvarlämnad varukorg i portalen (till exempel 4 timmar senare, med en rabattkod), och Custas skickar den, med samtycket kontrollerat som för alla marknadsföringsutskick. Inget skript körs i webbläsaren, och inget registreras för besökare som inte har loggat in.
POST /v1/webshop-carts/events
{
"type": "cart_updated", # eller checkout_started, cart_abandoned,
# checkout_completed, cart_cleared
"cartId": "c-7f3a91", # ditt varukorgs-id
"member": { "memberId": "0190f0f0-…" }, # eller { "keyType": "email", "value": … }
"currency": "SEK",
"lines": [
{ "sku": "W-DIVER-300", "name": "Diver 300", "quantity": 1, "unitPriceMinor": 489500,
"imageUrl": "https://shop.example.se/img/diver-300.jpg" }
],
"recoveryUrl": "https://shop.example.se/cart"
}
# → 200: { "cart": { …, "status": "open", "ignored": false } }
-
Skicka hela varukorgen vid varje
cart_updatedochcheckout_started; den ersätter det som fanns. Det går bra att skicka vid varje ändring. Påminnelsen räknas från den senaste. -
Skicka
checkout_completednär ordern läggs ochcart_clearednär varukorgen töms. Att slutföra ett köp för medlemmen (§5) stoppar också påminnelsen, så ett missatcheckout_completedleder inte till en påminnelse om något hen redan har köpt. -
Varje varukorg får en påminnelse. Om samma
cartIdanvänds igen efter att varukorgen stängts (slutförd, tömd eller följd av ett köp) börjar den om och kan få en ny påminnelse. Långlivade varukorgar för inloggade kunder fungerar som de är. -
Skickar du från en kö? Ange
occurredAt. En händelse som är äldre än varukorgens senaste aktivitet kommer tillbaka med"ignored": trueoch ändrar ingenting, så ett sentcart_updatedkan inte öppna en avslutad varukorg igen. -
recoveryUrlär länken i meddelandet ({{cart.url}}): din egen https-sida som återställer varukorgen när kunden har loggat in. Mallen kan också skriva ut{{cart.items}},{{cart.value}}och{{cart.imageUrl}}. - Varukorgar är personuppgifter: Custas sparar dem i 90 dagar efter senaste aktivitet, raderar dem tillsammans med medlemmen och tar med dem i medlemmens registerutdrag.
9. Returer
Hitta köpet med referensen du sparade på ordern:
GET /v1/redemptions?externalRef=WEB-100231-1
Några varor kommer tillbaka
POST /v1/redemptions/{id}/returns
Idempotency-Key: WEB-100231-return-1
{
"lines": [{ "lineId": "item-8812", "quantity": 1 }],
"reason": "wrong size"
}
-
Varje enhet återbetalas med vad den kostade när den såldes,
rabatten inräknad. Läs beloppet, med moms, från den nya posten i svarets
returnsoch återbetala exakt det via din betalleverantör. Räkna inte ut det själv. - Poängen som varorna gav dras tillbaka, så långt medlemmen fortfarande har kvar dem.
- Frakt är ingen rad, så den kan inte returneras på det här sättet. Om din policy är att återbetala frakt gör du det via din betalleverantör; det ändrar ingenting i Custas.
-
En delretur ger inte tillbaka koden eller erbjudandet, och inte heller presentkortet
eller poängen som betalade. För att sätta tillbaka pengar på ett presentkort
använder du
POST /v1/gift-cards/{id}/refundmed beloppet och ettexternalRef. - Custas tillämpar ingen returperiod. Din webbshops returpolicy avgör vad som godtas.
Hela ordern avbryts eller returneras
POST /v1/redemptions/{id}/reverse
Idempotency-Key: WEB-100231-reverse
{ "reason": "order cancelled" }
Det här ångrar allt: kodanvändningar och erbjudandebudgetar kommer tillbaka, och presentkort och poäng som betalade återbetalas till kortet och medlemmen. Efter delreturer tas bara det som återstår tillbaka, och en andra återföring ändrar ingenting.
10. Sälja presentkort
-
Lägg presentkortet i varukorgen som en rad med
"isGiftCard": true. Inget rabatterar det, och det kan inte betalas med poäng. Utvärdera, reservera, betala och slutför som vanligt. -
Utfärda kortet när köpet har slutförts. Härled nyckeln från orderraden, så att ett
nytt försök returnerar samma kort i stället för att ladda ett kort till:
POST /v1/gift-cards Idempotency-Key: WEB-100231-gc-item-8813 { "amountMinor": 50000, "memberId": "0199a4f0-…", "note": "order WEB-100231" } -
Mejla det till mottagaren. Mallen måste innehålla koden; handlaren ställer in den i
portalen.
POST /v1/gift-cards/{id}/deliveries Idempotency-Key: WEB-100231-gc-item-8813-send { "templateKey": "gift-card", "email": "erik@example.com", "message": "Happy birthday!", "locale": "sv-SE" }
-
Mejlutskick kräver
messaging:write. Att skicka till en inskriven adress kräver ocksåmembers:reveal, om inte samma nyckel utfärdade kortet under de senaste 30 minuterna, vilket är det normala direkt efter köpet. - Det finns inget schemalagt utskick. För ”leverera på hennes födelsedag” sparar du kortets id och anropar deliveries på dagen.
-
Det utfärdade kortets
codefinns bara i svaret när kortet utfärdas. Spara eller logga den inte, utöver att lämna den vidare till leveransen.
11. Webhooks
Orderflödet fungerar utan webhooks: svaret på varje steg kommer tillbaka i anropet. Prenumerera för att hålla webbshopen i takt med det som händer på annat håll (kräver Growth-planen eller högre):
| Händelse | Varför en webbshop vill ha den |
|---|---|
redemption.released |
En reservation löpte ut (reason: "ttl") på en order som du tror
är öppen
|
member.merged |
Peka om kundkontot från den sammanslagna medlemmens id till den som behölls |
member.deleted |
Medlemmen har raderats: ta bort kopplingen och radera det du kopierat |
consent.changed |
Håll ditt nyhetsbrevsverktyg i takt när samtycket ändras i en butik |
tier.changed |
Flytta kunden till en annan kundgrupp i webbshopen |
12. Fel
| Svar | Var | Webbshopen |
|---|---|---|
404 not_found |
Uppslagning | Erbjuder medlemskap |
404 med mergedInto |
Hämta medlem | Sparar det nya id:t på kundkontot |
409 identity_conflict |
Skapa medlem | Slår upp samma e-postadress och kopplar den medlemmen |
409 med en quote |
Reservera |
Visar den nya totalsumman; reserverar igen på quote.quoteHash
|
409 conflict |
Reservera |
externalRef är redan använt (använd nästa försök), eller så har
en anonym order inget att reservera (hoppa över Custas)
|
409 reservation_not_held |
Slutför | Följer §6 |
409 idempotency_request_in_progress |
Alla anrop med nyckel | Väntar retryAfter och gör ett nytt försök med samma nyckel |
422 med below_marketing_min_age |
Samtycke | Förklarar att marknadsföring inte är tillgänglig under den åldern |
422 validation_failed |
Alla | errors[].field anger vilket fält som ska rättas |
429 rate_limited |
Alla | Väntar Retry-After; utvärderar mer sällan |
5xx, timeout |
Alla | Gör nya försök med samma nyckel för anrop med nyckel. Om Custas inte går att nå vid ”Lägg order”: sälj till ordinarie pris, utan koder och lojalitetsförmåner, i stället för att blockera kassan |
13. Checklista
- API-nyckeln finns i backend; butiksfronten anropar aldrig Custas
- Kundkonton sparar medlemmens id; uppslagning bara för verifierade e-postadresser hos inloggade kunder
- Gäster prissätts utan medlem; ingen anonym uppslagning någonstans
- Registreringen skickar handlarens obligatoriska identifierare; en konflikt leder till koppling
- Marknadsföringssamtycke efterfrågas separat, inte förkryssat, med textens id
-
Varje varukorg har
channel: "online"och det överenskomnastoreId - Frakt skickas som
shipping, inte som en rad - Avvisade koder förklaras under kodfältet, med ett reservmeddelande
- Presentkortsfältet är skyddat mot gissning
- Reservera vid ”Lägg order”, med en enda 409-väg som visar den nya totalsumman
externalRefinnehåller ett försöksnummer- Betalsessionen går ut före reservationen
- Slutför från omdirigeringen och leverantörens webhook med samma nyckel
- Släpp vid misslyckad eller avbruten betalning
- En plan för en betalning som bekräftas efter reservationen
-
Varukorgshändelser skickas för inloggade medlemmar, med
checkout_completedför varje order - Returer per rad, med frakt återbetald utanför Custas
- Presentkort utfärdas och mejlas med nycklar härledda från ordern
member.mergedochmember.deletedhanteras- Byggt mot en
cust_test_-nyckel innan du går live