Skip to content

Latest commit

 

History

History
428 lines (349 loc) · 10.3 KB

File metadata and controls

428 lines (349 loc) · 10.3 KB
title
Checkout Flow

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

Once the customer has added the desired products to the active order, it's time to check out.

This guide assumes that you are using the default OrderProcess, so if you have defined a custom process, some of these steps may be slightly different.

:::note In this guide, we will assume that an ActiveOrder fragment has been defined, as detailed in the Managing the Active Order guide, but for the purposes of checking out the fragment should also include customer shippingAddress and billingAddress fields. :::

Add a customer

Every order must be associated with a customer. If the customer is not logged in, then the setCustomerForOrder mutation must be called. This will create a new Customer record if the provided email address does not already exist in the database.

:::note If the customer is already logged in, then this step is skipped. :::

mutation SetCustomerForOrder($input: CreateCustomerInput!) {
  setCustomerForOrder(input: $input) {
    ...ActiveOrder
    ...on ErrorResult {
      errorCode
      message
    }
  }
}
{
  "input": {
    "title": "Mr.",
    "firstName": "Bob",
    "lastName": "Dobalina",
    "phoneNumber": "1234556",
    "emailAddress": "b.dobalina@email.com",
  }
}

Set the shipping address

The setOrderShippingAddress mutation must be called to set the shipping address for the order.

mutation SetOrderShippingAddress($input: CreateAddressInput!) {
  setOrderShippingAddress(input: $input) {
    ...ActiveOrder
    ...on ErrorResult {
      errorCode
      message
    }
  }
}
{
  "input": {
    "fullName": "John Doe",
    "company": "ABC Inc.",
    "streetLine1": "123 Main St",
    "streetLine2": "Apt 4B",
    "city": "New York",
    "province": "NY",
    "postalCode": "10001",
    "countryCode": "US",
    "phoneNumber": "123-456-7890",
    "defaultShippingAddress": true,
    "defaultBillingAddress": false
  }
}

If the customer is logged in, you can check their existing addresses and pre-populate an address form if an existing address is found.

query GetCustomerAddresses {
  activeCustomer {
    id
    addresses {
      id
      fullName
      company
      streetLine1
      streetLine2
      city
      province
      postalCode
      country {
        code
        name
      }
      phoneNumber
      defaultShippingAddress
      defaultBillingAddress
    }
  }
}
{
  "data": {
    "activeCustomer": {
      "id": "123456",
      "addresses": [
        {
          "id": "123",
          "fullName": "John Doe",
          "company": "",
          "streetLine1": "123 Main St",
          "streetLine2": "Apt 4B",
          "city": "New York",
          "province": "NY",
          "postalCode": "10001",
          "country": {
            "code": "US",
            "name": "United States"
          },
          "phoneNumber": "123-456-7890",
          "defaultShippingAddress": true,
          "defaultBillingAddress": false
        },
        {
          "id": "124",
          "fullName": "John Doe",
          "company": "",
          "streetLine1": "456 Elm St",
          "streetLine2": "",
          "city": "Los Angeles",
          "province": "CA",
          "postalCode": "90001",
          "country": {
            "code": "US",
            "name": "United States"
          },
          "phoneNumber": "987-654-3210",
          "defaultShippingAddress": false,
          "defaultBillingAddress": true
        }
      ]
    }
  }
}

Set the shipping method

Now that we know the shipping address, we can check which shipping methods are available with the eligibleShippingMethods query.

query GetShippingMethods {
  eligibleShippingMethods {
    id
    price
    description
  }
}
{
  "data": {
    "eligibleShippingMethods": [
      {
        "id": "1",
        "price": 545,
        "description": "Standard Shipping"
      },
      {
        "id": "2",
        "price": 1250,
        "description": "Expedited Shipping"
      },
      {
        "id": "3",
        "price": 1695,
        "description": "Overnight Shipping"
      }
    ]
  }
}

The results can then be displayed to the customer so they can choose the desired shipping method. If there is only a single result, then it can be automatically selected.

The desired shipping method's id is the passed to the setOrderShippingMethod mutation.

mutation SetShippingMethod($id: [ID!]!) {
    setOrderShippingMethod(shippingMethodId: $id) {
        ...ActiveOrder
        ...on ErrorResult {
            errorCode
            message
        }
    }
}

Add payment

The eligiblePaymentMethods query can be used to get a list of available payment methods. This list can then be displayed to the customer, so they can choose the desired payment method.

query GetPaymentMethods {
  eligiblePaymentMethods {
    id
    name
    code
    isEligible
  }
}
{
  "data": {
    "eligiblePaymentMethods": [
      {
        "id": "1",
        "name": "Stripe",
        "code": "stripe",
        "isEligible": true
      },
      {
        "id": "2",
        "name": "Apple Pay",
        "code": "apple-pay",
        "isEligible": true
      }
      {
        "id": "3",
        "name": "Pay on delivery",
        "code": "pay-on-delivery",
        "isEligible": false
      }
    ]
  }
}

Next, we need to transition the order to the ArrangingPayment state. This state ensures that no other changes can be made to the order while the payment is being arranged. The transitionOrderToState mutation is used to transition the order to the ArrangingPayment state.

mutation TransitionToState($state: String!) {
  transitionOrderToState(state: $state) {
    ...ActiveOrder
    ...on OrderStateTransitionError {
      errorCode
      message
      transitionError
      fromState
      toState
    }
  }
}
{
  "state": "ArrangingPayment"
}

At this point, your storefront will use an integration with the payment provider to collect the customer's payment details, and then the exact sequence of API calls will depend on the payment integration.

The addPaymentToOrder mutation is the general-purpose mutation for adding a payment to an order. It accepts a method argument which must corresponde to the code of the selected payment method, and a metadata argument which is a JSON object containing any additional information required by that particular integration.

For example, the demo data populated in a new Vendure installation includes a "Standard Payment" method, which uses the dummyPaymentHandler to simulate a payment provider. Here's how you would add a payment using this method:

mutation AddPaymentToOrder($input: PaymentInput!) {
  addPaymentToOrder(input: $input) {
    ...ActiveOrder
    ...on ErrorResult {
      errorCode
      message
    }
  }
}
{
  "method": "standard-payment",
  "metadata": {
    "shouldDecline": false,
    "shouldError": false,
    "shouldErrorOnSettle": false,
  }
}

Other payment integrations have specific setup instructions you must follow:

Stripe

Our StripePlugin docs describe how to set up your checkout to use Stripe.

Braintree

Our BraintreePlugin docs describe how to set up your checkout to use Braintree.

Mollie

Our MolliePlugin docs describe how to set up your checkout to use Mollie.

Other payment providers

For more information on how to integrate with a payment provider, see the Payment guide.

Display confirmation

Once the checkout has completed, the order will no longer be considered "active" (see the OrderPlacedStrategy) and so the activeOrder query will return null. Instead, the orderByCode query can be used to retrieve the order by its code to display a confirmation page.

query GetOrderByCode($code: String!) {
  orderByCode(code: $code) {
    ...Order
  }
}
{
  "code": "PJGY46GCB1EDU9YH"
}

:::info By default Vendure will only allow access to the order by code for the first 2 hours after the order is placed if the customer is not logged in. This is to prevent a malicious user from guessing order codes and viewing other customers' orders. This can be configured via the OrderByCodeAccessStrategy. :::