Build Baskets and Place Orders

B2C Commerce API (SCAPI) supports checkout through the Shopper Baskets, Shopper Customers, and Shopper Orders API families.

This topic outlines best practices for constructing and submitting baskets, and provides high-level guidance on how to approach payment processing with SCAPI.

Never pass payment card data to B2C Commerce. Instead, have the shopper provide payment card data directly to the payment provider using the provider’s script/iframe, and pass the token returned from the provider to the API. Validate the token, and if the token is valid, accept the order, otherwise reject it.

This article assumes that you are interacting with a payment gateway from which you get a payment token.

Important

Only existing customers can access some of the links on this page. Visit Salesforce Commerce Cloud GitHub Repositories and Access for information about how to get access to the repositories.

Tip

Prerequisites 

Make sure that you have implemented:

  • A payment gateway
  • A strategy for how you will create orders. In SCAPI, the recommended strategy is to create an order before you validate payment.
  • A SLAS private client or SLAS public client. The code examples provided in this topic use a private client. For details, see Create a SLAS Client.

Build a Basket 

You have two options for building baskets:

  • Build a basket incrementally
  • Build a basket with a single request

Build a Basket Incrementally 

When you build a basket incrementally, you enter the information as the shopper provides it. This persists the basket in the B2C Commerce backend, and is useful if you can’t easily persist the basket. It also performs validation and returns API errors as you go, as shown in the following code examples. Note that the comments included in the code examples are provided for clarity and must be removed for the code to work.

1#!/bin/bash
2set -euo pipefail
3
4CODE='kv7kzm78'
5ORG='f_ecom_zzrf_001'
6SITE='RefArchGlobal'
7CLIENT=
8SECRET=
9
10BASE="https://$CODE.api.commercecloud.salesforce.com"
11BASE_AUTH="$BASE/shopper/auth/v1/organizations/$ORG"
12BASE_BASKETS="$BASE/checkout/shopper-baskets/v1/organizations/$ORG"
13
14# 1. Get guest token (Note: The following code provides a rough flow using a private client. The commands for getting a token for a public client differ.)
15TOKEN=$(
16  curl "$BASE_AUTH/oauth2/token" \
17    -sS --fail-with-body \
18    -u "$CLIENT:$SECRET" \
19    -d 'grant_type=client_credentials' | jq -r .'access_token'
20)
21
22# 2. Create basket (Note: When you create a basket, you store a reference to the basket, and use the reference in subsequent calls.)
23BASKET=$(
24  curl "$BASE_BASKETS/baskets?siteId=$SITE" \
25    -sS --fail-with-body \
26    -H "Authorization: Bearer $TOKEN" \
27    -H "Content-Type: application/json" \
28    -d '{ "productItems": [{ "quantity": 1, "productId": "682875090845M"}]}' | jq -r '.basketId'
29)
30
31# 3. Set basket customer
32curl "$BASE_BASKETS/baskets/$BASKET/customer?siteId=$SITE" \
33  -sS --fail-with-body -o /dev/null \
34  -X 'PUT' \
35  -H "Authorization: Bearer $TOKEN" \
36  -H "Content-Type: application/json" \
37  -d '{ "email": "shopper@salesforce.com" }'
38
39# 4. Set shipping address. All baskets have a shipment called `me`. For multiple shipments, you must create those shipments yourself. See [createShipmentForBasket](https://developer.salesforce.com/docs/commerce/commerce-api/references/shopper-baskets?meta=createShipmentForBasket).
40curl "$BASE_BASKETS/baskets/$BASKET/shipments/me?siteId=$SITE" \
41  -sS --fail-with-body -o /dev/null \
42  -X 'PATCH' \
43  -H "Authorization: Bearer $TOKEN" \
44  -H "Content-Type: application/json" \
45  -d '{
46        "shippingAddress": {
47          "firstName": "Joe",
48          "lastName": "Shopper",
49          "address1": "415 Mission St.",
50          "city": "San Francisco",
51          "postalCode": "94105",
52          "stateCode": "CA",
53          "countryCode": "US"
54        }
55      }'
56
57# 5. Get applicable shipping methods (Note: This example defaults to the first shipping method that is available.)
58SHIPPING_METHOD=$(
59  curl "$BASE_BASKETS/baskets/$BASKET/shipments/me/shipping-methods?siteId=$SITE" \
60    -sS --fail-with-body \
61    -H "Authorization: Bearer $TOKEN" | jq -r '.applicableShippingMethods[0].id'
62)
63
64# 6. Set shipping method
65curl "$BASE_BASKETS/baskets/$BASKET/shipments/me/shipping-method?siteId=$SITE" \
66  -sS --fail-with-body -o /dev/null \
67  -X 'PUT' \
68  -H "Authorization: Bearer $TOKEN" \
69  -H "Content-Type: application/json" \
70  -d '{"id": "'$SHIPPING_METHOD'"}'
71
72# 7. Set payment instrument (Note: This example uses PayPal.)
73curl "$BASE_BASKETS/baskets/$BASKET/payment-instruments?siteId=$SITE" \
74  -sS --fail-with-body -o /dev/null \
75  -H "Authorization: Bearer $TOKEN" \
76  -H "Content-Type: application/json" \
77  -d '{ "paymentMethodId": "PayPal" }'
78
79# 8. Set billing address
80curl "$BASE_BASKETS/baskets/$BASKET/billing-address?siteId=$SITE&useAsShipping=false" \
81  -sS --fail-with-body -o /dev/null \
82  -X 'PUT' \
83  -H "Authorization: Bearer $TOKEN" \
84  -H "Content-Type: application/json" \
85  -d '{
86        "firstName": "Joe",
87        "lastName": "Shopper",
88        "address1": "415 Mission St",
89        "city": "San Francisco",
90        "postalCode": "94105",
91        "stateCode": "CA",
92        "countryCode": "US"
93      }'
94
95# 9. Submit order
96curl "$BASE/checkout/shopper-orders/v1/organizations/$ORG/orders?siteId=$SITE" \
97  -sS --fail-with-body \
98  -H "Authorization: Bearer $TOKEN" \
99  -H "Content-Type: application/json" \
100  -d '{ "basketId": "'$BASKET'"}' | jq

Build Basket with a Single Request 

Create the basket with just one request, and provide the relevant parts you want to fill. The following example builds an entire basket and its nested documents with one request:

1#!/bin/bash
2set -euo pipefail
3
4CODE='kv7kzm78'
5ORG='f_ecom_zzrf_001'
6SITE='RefArchGlobal'
7CLIENT=
8SECRET=
9
10BASE="https://$CODE.api.commercecloud.salesforce.com"
11BASE_AUTH="$BASE/shopper/auth/v1/organizations/$ORG"
12BASE_BASKETS="$BASE/checkout/shopper-baskets/v1/organizations/$ORG"
13
14# 1. Get guest token
15TOKEN=$(
16    curl "$BASE_AUTH/oauth2/token" \
17        -sS --fail-with-body \
18        -u "$CLIENT:$SECRET" \
19        -d 'grant_type=client_credentials' | jq -r .'access_token'
20)
21
22# 2. Create a basket
23BASKET=$(
24    curl "$BASE_BASKETS/baskets?siteId=$SITE" \
25        -sS --fail-with-body \
26        -H "Authorization: Bearer $TOKEN" \
27        -H "Content-Type: application/json" \
28        -d '{
29              "productItems": [{ "quantity": 1, "productId": "682875090845M" }],
30              "customerInfo": { "email": "shopper@salesforce.com" },
31              "shipments": [
32                {
33                  "shipmentId": "me",
34                  "shippingAddress": {
35                    "firstName": "Joe",
36                    "lastName": "Shopper",
37                    "address1": "415 Mission St.",
38                    "city": "San Francisco",
39                    "postalCode": "94105",
40                    "stateCode": "CA",
41                    "countryCode": "US"
42                  },
43                  "shippingMethod": { "id": "GBP001" }
44                }
45              ],
46              "paymentInstruments": [{ "paymentMethodId": "PayPal" }],
47              "billingAddress": {
48                "firstName": "Joe",
49                "lastName": "Shopper",
50                "address1": "415 Mission St",
51                "city": "San Francisco",
52                "postalCode": "94105",
53                "stateCode": "CA",
54                "countryCode": "US"
55              }
56            }' | jq -r '.basketId'
57)
58
59# 3. Submit order
60curl "$BASE/checkout/shopper-orders/v1/organizations/$ORG/orders?siteId=$SITE" \
61    -sS --fail-with-body \
62    -H "Authorization: Bearer $TOKEN" \
63    -H "Content-Type: application/json" \
64    -d '{ "basketId": "'$BASKET'"}'

Retrieve an Existing Basket 

To retrieve an existing basket, use the Shopper Customers API getCustomerBaskets endpoint.

The following example retrieves customer baskets using a customer ID:

1curl  "$BASE/customer/shopper-customers/v1/organizations/$ORG/customers/$CUSTOMERID/baskets?siteId=$SITE' \
2  -sS --fail-with-body \
3    -H "Authorization: Bearer $TOKEN" \
4    -H "Content-Type: application/json" \

The following example retrieves a basket using a basket ID:

1curl  "$BASE_BASKETS/baskets/$BASKETID?siteId=$SITE' \
2  -sS --fail-with-body \
3    -H "Authorization: Bearer $TOKEN" \
4    -H "Content-Type: application/json" \