Skip to content

Commande & checkout

Le tunnel de commande appartient au front ; le cœur possède la transformation panier → commande et l'agrégation des choix. Voici comment l'étendre.

Le tunnel : des étapes

Le frontend enregistre des étapes dans le CheckoutStepRegistry (un registre), triées par priorité — par défaut user (10), addresses (20), shipping (30), payment (40).

Ajouter une étape :

php
use Slab\Frontend\Checkout\Contracts\CheckoutStepRegistry;

$this->app->make(CheckoutStepRegistry::class)->add('cadeau', GiftStepController::class, priority: 25);

Réordonner sans code : config/checkout.php. Remplacer toute l'orchestration : bind le contrat CheckoutFlow.

Les choix : des options en donnée

Une feature qui ajoute un choix (transporteur, paiement) n'expose que de la donnée via un CheckoutOptionProviderjamais de HTML. Elle décrit une exigence (shipping, payment…) et renvoie des options (id, libellé, prix, méta). Le frontend les rend génériquement :

php
use Slab\Framework\Core\Checkout\Contracts\CheckoutOptionRegistry;

$this->app->make(CheckoutOptionRegistry::class)->register(MonOptionProvider::class);

Ajouter un transporteur le fait apparaître au checkout, sans toucher au front. C'est le modèle de slab/carrier et slab/payment.

La commande : un snapshot immuable

À la dernière étape, CartService::createOrder() délègue à l'OrderPlacementPipeline — une classe final, transactionnelle et idempotente (la contrainte unique orders.cart_id interdit de convertir deux fois le même panier). En une transaction, il :

  1. crée l'en-tête de commande (adresses répliquées, checkout_selections copiées, jeton unique) ;
  2. fige les lignes dans des OrderProduct (référence, nom, quantité, prix HT/TTC du moment) ;
  3. fige les totaux dans price_components (JSON) + des colonnes, en devise de référence et du client ;
  4. émet OrderPlaced.

Résultat : une commande se relit sans aucun package installé (l'OrderPriceService lit les colonnes figées, sans jamais recalculer). Supprimer un transporteur après coup ne change pas une commande passée. Le pipeline n'est pas extensible directement — on s'y branche par l'événement.

Réagir à une commande

Pour réagir, écoutez les événements :

ÉvénementPour…
OrderPlacede-mail, stock, ERP, fidélité
OrderStatusChangednotifications de suivi

Points d'extension de ce domaine

Je veux…Point d'extension
ajouter une étape de tunnelCheckoutStepRegistry (frontend)
ajouter un mode de livraison / paiementCheckoutOptionProvider
changer l'orchestration du tunnelCheckoutFlow (bind)
réagir à une commandeOrderPlaced, OrderStatusChanged
greffer une relation sur OrderresolveRelationUsing

Voir aussi