flamingo.me/flamingo-commerce/v3@v3.11.0/checkout/Readme.md (about)

     1  # Checkout Package
     2  
     3  This package provides a one page standard checkout with the following features:
     4  
     5  * Concept for PaymentProviders, that can be used to implement specific Payments
     6  * An "offline payment" provider is part of the module
     7  
     8  **Table of content**
     9  
    10  * [Configurations](#configurations)
    11  * [Checkout Controller](#checkout-controller)
    12  * [GraphQL Place Order Process](#graphql-place-order-process)
    13    + [Queries / Mutations](#queries---mutations)
    14    + [Place Order States](#place-order-states)
    15    + [Context store](#context-store)
    16      - [Ports / Implementation](#ports---implementation)
    17    + [Locking](#locking)
    18      - [Ports / Implementation](#ports---implementation-1)
    19  * [Provided Ports](#provided-ports)
    20    + [Process Context Store](#process-context-store)
    21    + [Process Lock](#process-lock)
    22  
    23  ## Configurations
    24  
    25  If your template does not want to ask for all the information required you can also set default values for the checkoutform (strings)
    26  
    27  ```yaml
    28  commerce:
    29    checkout:
    30      # to enable the offline payment provider
    31      enableOfflinePaymentProvider: true
    32  
    33      # checkout flow control flags:
    34      skipStartAction: false
    35      skipReviewAction: false
    36      showReviewStepAfterPaymentError: false
    37      showEmptyCartPageIfNoItems: false
    38      redirectToCartOnInvalideCart: false
    39  
    40      # checkout form settings:
    41      useDeliveryForms: true
    42      usePersonalDataForm: false
    43      privacyPolicyRequired: true
    44  
    45      # GraphQL place order process
    46      placeorder:
    47        lock: 
    48          type: "memory" # only suited for single node applications, use "redis" for multi node setup
    49        contextstore:
    50          type: "memory" # only suited for single node applications, use "redis" for multi node setup
    51  ```
    52  
    53  
    54  ## Checkout Controller
    55  
    56  This module implements a controller for the following checkout flow (the checkout process for the end customer):
    57  
    58  1. StartAction (optional)
    59      * check if user is logged in
    60          * yes: next action
    61          * no: show start template (where the user can login)
    62  1. Checkout Action
    63      * this is the main step, and the template should render the big checkout form (or at least the parts that are interesting). 
    64      * on submit and if everything was valid:
    65          * Action will update the cart - specifically the following information:
    66              * Update billing (on cart level)
    67              * Update deliveryinfos on (each) delivery in the cart (e.g. used to set shipping address)
    68              * Select Payment Gateway and preferred Payment Method
    69              * Optional Save the wished payment split for each item in the cart
    70              * Optional add Vouchers/GiftCards (may already happened before)            
    71          * If Review Action is skipped:
    72              * Start payment and place order if needed (EarlyPlaceOrder)
    73              * Redirect to Payment Action
    74          * If Review Step is not skipped:
    75              * Redirect to Review Action
    76  1. Review Action (Optional)
    77      * Renders "review" template that can be used to review the cart
    78      * After confirming start the payment and place order if needed (EarlyPlaceOrder)
    79  1. Payment Action
    80      * Ask Payment Gateway about FlowStatus and handle it
    81      * FlowStatus:
    82          * Error / Abort by customer: Regenerate Idempotency Key of PaymentSelection, redirect to checkout and reopen cart if needed
    83          * Success / Approved: Redirect to PalceOrderAction
    84          * Unapproved: Render payment template and let frontend decide how to continue in flow (e.g. redirect to payment provider)
    85  1. Place Order Action
    86      * Check if order already placed (EarlyPlaceOrder)
    87      * If order not already placed check FlowStatus and place order
    88      * Put order infos in flash message and redirect to Success Action
    89  1. Success Action:
    90      * Renders order success template
    91  
    92  ## GraphQL Place Order Process
    93  
    94  When we introduced GraphQL, we rethought the checkout process from the ground up. Among other things, we decided to
    95  map the individual steps of the checkout to states of a newly created place order state machine.
    96  This should mainly make the process more robust and make it easier to roll back operations in case of errors.
    97  
    98  **Important:** when you start using the new place order process please ensure that you use the "OnWrite" Flamingo session save mode:
    99  ```
   100  flamingo.session.saveMode: "OnWrite"
   101  ```
   102  
   103  ### Queries / Mutations
   104  
   105  The checkout module exposes the following Mutations and Queries:
   106  
   107  * `mutation Commerce_Checkout_StartPlaceOrder`
   108    starts a place order process and returns the process' UUID. If there is already a running process, it will be replaced by the new one.
   109    The processing is started in background and continues after the return of the mutation until an
   110    action is required or a final state (error or success) is reached.
   111  * `mutation Commerce_Checkout_RefreshPlaceOrder`
   112    refreshes the process and tries to start the background processing again if it is not running anymore. The result is the state
   113    at the moment of the mutation. If the background process is still running, this mutation is non-operational.
   114  * `mutation Commerce_Checkout_RefreshPlaceOrderBlocking`
   115    refreshes the process and starts the background processing again if it is not running anymore. It **waits** with the return
   116    until the background process comes to a final state or need an action.
   117  * `mutation Commerce_Checkout_CancelPlaceOrder` 
   118    cancels the running process if it is not yet in a final state.
   119  * `mutation Commerce_Checkout_ClearPlaceOrder` 
   120    clears the last stored process. (Non-operational if there is no last process)
   121  * `query Commerce_Checkout_ActivePlaceOrder`
   122    checks if there is a place order process in a non-final state.
   123  * `query Commerce_Checkout_CurrentContext`
   124    returns the current state **without** restarting the background processing.
   125  
   126  
   127  ### Place Order States
   128  
   129  We differentiate between internal and exposed states.
   130  
   131  Internal states implement the interface `checkout/domain/placeorder/process.State`. There is a map binding on this interface using the name of the state.
   132  This way, other modules can overwrite specific states to introduce their own implementation.
   133  
   134  The start and failed states are defined by an annotated binding with annotations `startState` and `failedState`, respectively.
   135  
   136  Exposed states implement the interface `checkout/interfaces/graphql/dto.State`. To map internal states to exposed states, 
   137  we use a map binding on the `dto.State` interface with the internal state names as keys and the exposed state as target.
   138  
   139  The default implementation defines the state flow as follows (for an cart that needs payment): 
   140  
   141  ![](domain/placeorder/states/transitions.png)
   142  
   143  Fully discounted carts don't need a payment, therefore the state flow is similar but lacks the payment creation/validation:
   144  
   145  ![](domain/placeorder/states/transitions_zeropay.png)
   146  
   147  ### Context store
   148  
   149  The place order context must be stored aside of the session, since it is manipulated by a background process.
   150  
   151  #### Ports / Implementation
   152  
   153  **In Memory**
   154  
   155  _Important: This context store is only suited for single node applications, please use redis for multi node setup_
   156  
   157  Default context store implementation. Provides a map based in memory adapter for the `ContextStore` port.
   158  
   159  ```yaml
   160  commerce.checkout.placeorder.contextstore.type: "memory"
   161  ```
   162  
   163  **Redis**
   164  
   165  The Redis implementation writes the context into the configured redis instance. The complete entry will be gob-encoded.
   166  
   167  **Be aware that you have to gob-register your own `StateData` if you introduce some.**
   168  
   169  ```yaml
   170  commerce.checkout.placeorder.contextstore:
   171    type: "redis"
   172    redis:
   173      maxIdle: 25
   174      idleTimeoutMilliseconds: 240000
   175      network: "tcp"
   176      address: "localhost:6379"
   177      database: 0
   178  ```
   179  
   180  ### Locking
   181  
   182  To ensure that the state machine cannot be processed multiple times for one process, we have decided to introduce a process lock.
   183  At the start of each place order transaction an attempt is made to obtain a lock, if this is not possible a transaction is already running and we just wait.
   184  
   185  #### Ports / Implementation
   186  
   187  The module offers the `TryLock` port and currently two implementations (Memory, Redis).
   188  
   189  **In Memory**
   190  
   191  _Important: This lock is only suited for single node applications, please use redis for multi node setup_
   192  
   193  Default lock implementation. Provides a mutex based in memory adapter for the `TryLock` port.
   194  
   195  ```yaml
   196  commerce.checkout.placeorder.lock.type: "memory"
   197  ```
   198  
   199  **Redis**
   200  
   201  Provides a redis based lock implementation using the [go-redsync/redsync](https://github.com/go-redsync/redsync) package.
   202  Node acquires the lock and refreshes it every X second, if the node dies the lock is automatically released after the provided max duration.
   203  
   204  ```yaml
   205  commerce.checkout.placeorder.lock:
   206    type: "redis"
   207    redis:
   208      maxIdle: 25
   209      idleTimeoutMilliseconds: 240000
   210      network: "tcp"
   211      address: "localhost:6379"
   212      database: 0
   213  ```
   214  
   215  
   216  ## Provided Ports
   217  
   218  ### Process Context Store 
   219  New GraphQL related process context store. For more details see [Context store](#context-store)
   220  
   221  ### Process Lock
   222  New GraphQL related process lock. For more details see [Locking](#locking)
   223