Ga naar de inhoud
agovena.
agovena.
Aan de slag
Community

Voor ontwikkelaars

Winkelwagen- en checkout-API

Winkelwagenidentiteit, gevalideerde checkoutinvoer, betaalinitiatie en idempotentie zonder clienttotalen.

Op deze pagina

Bepaal eerst de winkelwagencontext

De API gebruikt TokenCartRepository, niet de sessiewinkelwagen van de storefront. Als Laravel op het request een User vindt, gebruikt de API het gebruikers-ID als winkelwagensleutel. Anders wordt de header X-Cart-Token gebruikt.

Een gasttoken bestaat uit 64 kleine hexadecimale tekens. Bij ontbrekende of ongeldige invoer wordt een nieuw willekeurig token gemaakt. Winkelwagenresponses retourneren het als data.token en als responseheader X-Cart-Token. Bewaar die waarde voor volgende gastverzoeken. Het is een toegangsbewijs voor de winkelwagen, geen Sanctum-inlogtoken. De inhoud blijft na opslag zeven dagen in de cache en verdwijnt als de bijbehorende cachewaarde wordt gewist.

Gastwinkelwagens en ingelogde winkelwagens worden niet automatisch samengevoegd. De openbare winkelwagenroutes voeren zelf geen auth:sanctum uit. Een bearer-header toevoegen is dus geen gedocumenteerde overdracht van gast naar klant. Checkout vereist wel auth:sanctum en leest de winkelwagen van de gevonden gebruiker. Alleen hetzelfde gasttoken meesturen bewijst daarom niet dat checkout dezelfde inhoud ziet. Gebruik voor een ingelogde first-party client dezelfde ondersteunde sessie bij API-winkelwagenverzoeken en checkout. Controleer voor een bearer-only client de werkelijke winkelwagencontext in een integratietest voordat je daarop een aankoopflow bouwt. De huidige routes hebben geen endpoint om een gastwinkelwagen te claimen.

Ook de gewone winkelwagen op de website is afzonderlijk. Een product dat op een webpagina is toegevoegd, staat niet automatisch in de API-winkelwagen. Bron: repositorybinding.

Regels toevoegen, wijzigen en verwijderen

Handeling Gevalideerde invoer
GET /api/v1/cart Geen body
POST /api/v1/cart Verplichte integer product_id; nullable integer quantity van 1 tot 99, standaard 1; nullable array selections
PATCH /api/v1/cart/{lineKey} Verplichte integer quantity van 0 tot 99
DELETE /api/v1/cart/{lineKey} Geen body

Een aantal van nul verwijdert de regel. Gebruik bij wijzigen en verwijderen de ontvangen line_key, niet het product-ID. Verschillende keuzes kunnen verschillende regels voor hetzelfde product opleveren. Neem optiesleutels en keuzewaarden over uit de catalogusresource. De winkelwagenservice valideert de configuratie en berekent de prijzen.

Gastvoorbeelden met installatiegebonden ID's en het ontvangen token:

bash
curl --request POST 'https://shop.example.test/api/v1/cart' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"product_id":42,"quantity":1,"selections":{}}'

curl 'https://shop.example.test/api/v1/cart' \
  --header 'Accept: application/json' \
  --header "X-Cart-Token: $CART_TOKEN"

curl --request PATCH "https://shop.example.test/api/v1/cart/$LINE_KEY" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header "X-Cart-Token: $CART_TOKEN" \
  --data '{"quantity":2}'

curl --request DELETE "https://shop.example.test/api/v1/cart/$LINE_KEY" \
  --header 'Accept: application/json' \
  --header "X-Cart-Token: $CART_TOKEN"

Elke handeling retourneert de bijgewerkte winkelwagen:

json
{
  "data": {
    "token": "<64-character-cart-token>",
    "item_count": 1,
    "requires_shipping": false,
    "subtotal_amount": 1200,
    "currency": "EUR",
    "lines": [{
      "line_key": "<returned-line-key>",
      "product_id": 42,
      "label": "Voorbeeldproduct",
      "quantity": 1,
      "unit_amount": 1200,
      "line_total_amount": 1200,
      "currency": "EUR",
      "selections": []
    }]
  }
}

Bij een lege winkelwagen kunnen subtotal_amount en currency null zijn. selections bevat de door de server genormaliseerde keuzes; een lege PHP-array wordt [] in JSON. Bedragen zijn uitgedrukt in de kleinste munteenheid. Bereken uit dit voorbeeld geen gezaghebbend besteltotaal.

Bron: AccountController.

Vraag de checkoutvereisten op

GET /api/v1/checkout/requirements leest de huidige API-winkelwagen en retourneert:

Veld onder data Structuur
requirements Array met vereiste-ID's
requires_shipping Boolean
payment_methods Array van {id, label, gateway_id?, icon?}

Core voegt facturatie, betaling en controle toe als vereisten. Andere contributors kunnen capabilitygebonden vereisten toevoegen. Betaalmethoden komen uit de actieve gatewayregistratie. Leg dus geen vaste providerlijst vast en veronderstel niet dat methode-ID en gateway-ID altijd gelijk zijn.

bash
curl 'https://shop.example.test/api/v1/checkout/requirements' \
  --header 'Accept: application/json' \
  --header "X-Cart-Token: $CART_TOKEN"

Dit verzoek maakt geen bestelling of betaalpoging aan en retourneert geen catalogus met verzendtarieven. Direct afrekenen met de ontwikkelgateway is alleen beschikbaar onder de expliciete niet-productievoorwaarde en als er geen echte gatewaymethoden beschikbaar zijn. Zie AvailablePaymentMethods.

Plaats een bestelling

POST /api/v1/checkout vereist authenticatie en, bij een bearer-token, orders.create. Naam, e-mail en klant-ID komen van de huidige klant, niet uit door de client opgegeven identiteitsvelden. De requestvelden zijn:

Veld Regel
billing Verplichte array
billing.name, billing.line1 Verplichte strings, maximaal 255
billing.city Verplichte string, maximaal 120
billing.postal_code Verplichte string, maximaal 20
billing.country Verplichte string, precies twee tekens
billing.company, billing.line2 Nullable strings, maximaal 255
billing.region Nullable string, maximaal 120
billing.phone Nullable string, maximaal 40
payment_method Nullable string, maximaal 40; gebruik een beschikbare methode
idempotency_key Nullable string, maximaal 64
shipping Nullable adresarray, omgezet naar AddressData
shipping_same_as_billing Optionele boolean, standaard true
shipping_method_id Nullable integer
discount_code Nullable string, maximaal 40
custom_properties Nullable array

De controller controleert shipping als array zonder alle geneste factuuradresregels te herhalen. Dat betekent niet dat willekeurige verzendgegevens geldig zijn: AddressData en PlaceOrder voeren hun domeinlogica nog steeds uit. Producten, totalen, valuta, referralvelden en verzendoffertesleutels zijn in deze controller geen toegestane checkoutoverrides.

Onderstaand checkout-request.json is illustratief. Het gaat ervan uit dat de ingelogde API-winkelwagen al gevuld en geconfigureerd is. Dit is geen voorbeeld van een overdracht van een gastwinkelwagen.

json
{
  "idempotency_key": "customer-checkout-example-01",
  "billing": {
    "name": "Alex Voorbeeld",
    "line1": "Voorbeeldstraat 1",
    "city": "Brussel",
    "postal_code": "1000",
    "country": "BE"
  },
  "shipping_same_as_billing": true,
  "payment_method": "<discovered-method-id>",
  "custom_properties": {}
}
bash
curl --request POST 'https://shop.example.test/api/v1/checkout' \
  --header "Authorization: Bearer $AGOVENA_TOKEN" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data-binary @checkout-request.json

De response is een bestelresource, met regels, betaling, facturen en creditnotasamenvattingen. Een bestelling plaatsen betekent niet automatisch dat die betaald is. Lege of verkeerd geconfigureerde winkelwagens en niet-vervulde domeinvoorwaarden geven validatiefouten.

Gebruik één idempotentiesleutel per bedoelde bestelling. PlaceOrder zoekt eerst een bestaande bestelling van dezelfde eigenaar met die sleutel en kan deze hervatten voordat een nieuwe winkelwagen wordt beoordeeld. Een sleutel opnieuw gebruiken wijzigt de eerdere bestelling niet met de nieuwe body. Deze controller leest de sleutel uit JSON en neemt, anders dan betaalinitiatie, geen Idempotency-Key-header over.

Start een betaling via een gateway

POST /api/v1/orders/{order}/pay vereist orders.pay en een eigen bestelling. Verplichte velden zijn gateway (string, maximaal 40), return_url en cancel_url (URL's, elk maximaal 500 tekens). De optionele idempotency_key is een string van maximaal 64 tekens. Ontbreekt die sleutel in de body, dan accepteert de controller de header Idempotency-Key.

Beide redirect-origins moeten voorkomen in agovena.payments.return_url_origins. De instelling gebruikt AGOVENA_PAYMENT_RETURN_ORIGINS en valt standaard terug op APP_URL. URL's met inloggegevens of fragmenten worden geweigerd. Bij originvergelijking tellen protocol en een expliciete poort mee.

bash
curl --request POST "https://shop.example.test/api/v1/orders/$ORDER_ID/pay" \
  --header "Authorization: Bearer $AGOVENA_TOKEN" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: customer-payment-example-01' \
  --data '{"gateway":"<registered-gateway-id>","return_url":"https://shop.example.test/payment-return","cancel_url":"https://shop.example.test/payment-cancel"}'

Gebruik terugkeer- en annuleringsroutes die je client echt implementeert. De voorbeeldpaden zijn geen ingebouwde Agovena-routes. De response bevat integer data.attempt_id, string data.status voor de poging, nullable string data.redirect_url en nullable string data.payment_status voor de betaling van de bestelling. Domeinvalidatie uit StartOrderPayment krijgt 422 payment_failed. Eerdere request- of URL-validatie blijft validation_error.

Volg de providerredirect als die aanwezig is, maar bepaal de eindstatus via de bestelling of geverifieerde betaalwebhookverwerking. Gebruik verschillende sleutels voor bestellen en betalen. Start na een onduidelijke netwerktime-out niet zomaar een nieuwe betaalpoging zonder de vorige te controleren.

Bronnen en regressiecontroles

Voeg voor je eigen integratie expliciet een test voor de overgang van gast naar ingelogde klant toe. De bestaande gastwinkelwagentest bewijst geen volledige bearer-only aankoopflow.

Doorzoek de documentatie

Zoek handleidingen, commando’s en API-endpoints

Waar ben je naar op zoek?

Documentatie