# Implement guest checkout To implement a guest checkout, you can assign Carts and Orders to an anonymous session and later associate them with a Customer account during sign-in or sign-up. This tutorial focuses on the request patterns you can implement with anonymous-session tokens and regular API tokens. For the full token model and customer-assignment behavior, see [Tokens for anonymous sessions](/api/authorization.md#tokens-for-anonymous-sessions) and [Cart merge during sign-in and sign-up](/api/customers-overview.md#cart-merge-during-sign-in-and-sign-up). ## Identifier for Anonymous Sessions [Carts](/api/projects/carts.md#cart) and [Orders](/api/projects/orders.md#order) have an `anonymousId` field that defines which Anonymous Session they belong to. The `anonymousId` can be freely chosen. For example, you could re-use an identifier from an analytics library or a Device ID on a mobile device. However, if you do not use OAuth access tokens to manage the session, ensure that no other session with that identifier already exists. ## Use Anonymous Sessions with special OAuth tokens If you use anonymous-session OAuth tokens, resources created with the [My Carts](/api/projects/me-carts.md) and [My Orders](/api/projects/me-orders.md) endpoints are automatically scoped to that session. The [My Customers Profile](/api/projects/me-profile.md) endpoint assigns the carts and orders automatically to the customer account during [sign up](/search.md?urn=ctp:api:endpoint:/{projectKey}/me/signup:POST) and [sign in](/search.md?urn=ctp:api:endpoint:/{projectKey}/me/login:POST). Before using this flow, configure an API Client with anonymous-session support and the storefront scopes you need. To request this token, configure your API Client with the `create_anonymous_token:{projectKey}` scope. In the OAuth token request, set the `scope` parameter to the storefront scopes that the session needs. For example, use `view_products:{projectKey}`, `manage_my_orders:{projectKey}`, and `manage_my_profile:{projectKey}`. ![Screenshot Create New Mobile API Client](https://docs.commercetools.com/tutorials/images/create_new_mobile_api_client.png) Copy or download the client credentials. They cannot be revealed after creation for security reasons. For the full setup rules and scope requirements, see [Tokens for anonymous sessions](/api/authorization.md#tokens-for-anonymous-sessions). ### Create a token with a new Anonymous Session Use the OAuth client to request an anonymous-session token. In the first example, the API generates the session identifier for you. ```bash $curl https://auth.{region}.commercetools.com/oauth/{projectKey}/anonymous/token --basic --user "{client_id}:{client_secret}" -X POST -d "grant_type=client_credentials&scope=view_products:{projectKey} manage_my_orders:{projectKey} manage_my_profile:{projectKey}" ``` In this example, we supply the identifier `phone-123`. If this identifier is already in use, the request will fail. ```bash $curl https://auth.{region}.commercetools.com/oauth/{projectKey}/anonymous/token --basic --user "{client_id}:{client_secret}" -X POST -d "grant_type=client_credentials&scope=view_products:{projectKey} manage_my_orders:{projectKey} manage_my_profile:{projectKey}&anonymous_id=phone-123" ``` The response contains the token in the field `access_token`: ```json { "access_token": "vkFuQ6oTwj8_Ye4eiRSsqMeqLYNeQRJi", "token_type": "Bearer", "expires_in": 172800, "refresh_token": "{projectKey}:OWStLG0eaeVs7Yx3-mHcn8iAZohBohCiJSDdK1UCJ9U", "scope": "view_products:{projectKey} manage_my_orders:{projectKey} manage_my_profile:{projectKey}" } ``` By default, access tokens issued for anonymous sessions expire after **48** hours. You can then use this token with the My endpoints and other allowed scopes, for example to query Product Projections: ```bash $curl -sH "Authorization: Bearer vkFuQ6oTwj8_Ye4eiRSsqMeqLYNeQRJi" https://api.{region}.commercetools.com/{projectKey}/product-projections?staged=true&limit=10 ``` ### Best practice: Create Anonymous Sessions only once necessary Refer to the [best practice](/api/authorization.md#create-anonymous-sessions-only-once-necessary) on when to create a new anonymous session. ### Use the token to create a cart and order We can create a [new cart](/search.md?urn=ctp:api:endpoint:/{projectKey}/me/carts:POST) that belongs to the Anonymous Session: `POST /{projectKey}/me/carts` with: ```json { "currency": "USD", "country": "US" } ``` The new cart will have the `anonymousId` automatically set, for example to `phone-123`. We can now use this cart much like we're using any other cart, for example we can add a [line item](/api/projects/me-carts.md#add-lineitem): `POST /{projectKey}/me/carts/` with: ```json { "version": , "actions": [{ "action": "addLineItem", "productId": "", "variantId": 1, "quantity": 1 }] } ``` We can also [order the cart](/search.md?urn=ctp:api:endpoint:/{projectKey}/me/orders:POST). The new order will automatically belong to the same Anonymous Session, so its `anonymousId` will also be `phone-123`. ### Keep the refresh token With the refresh token, you can get new access tokens for the Anonymous Session by using the [Refresh token flow](/api/authorization.md#refresh-token-flow). The refresh token can live for a long time and can contain as many carts and orders as you need. However, if the refresh token is lost, there's no other way to claim this Anonymous Session. Depending on your platform, you can save the refresh token for later usage. For example, a browser app may save it in local storage, or an iOS app in the keychain. ### End an Anonymous Session by assigning it to a Customer If a customer signs up or signs in, the Carts and Orders belonging to the Anonymous Session are automatically assigned to the Customer account. The field `anonymousId` is still set. After the session ends, the access token and refresh token are immediately invalid. In this example, a customer [signs up](/search.md?urn=ctp:api:endpoint:/{projectKey}/me/signup:POST). After we have collected important information like name, email, and password from the customer, we can send their data to the API: `POST /{projectKey}/me/signup` with: ```json { "firstName": "Alice", "lastName": "Doe", "email": "alice@example.com", "password": "secret" } ``` Now we need to get new access and refresh tokens with the password flow: ```bash $curl https://auth.{region}.commercetools.com/oauth/{projectKey}/customers/token --basic --user "{client_id}:{client_secret}" -X POST -d "grant_type=password&username=alice@example.com&password=secret&scope=view_products:{projectKey} manage_my_orders:{projectKey} manage_my_profile:{projectKey}" ``` A `GET /{projectKey}/me/carts` with the new access token returns the same Carts, but we'll notice that the `customerId` is the one of the newly created account. The `anonymousId` is still set to `phone-123`. If we create another Cart, it has the `customerId` set, but not the `anonymousId`. ## Use Anonymous Sessions with regular OAuth tokens If you use regular OAuth tokens, you must create and persist the `anonymousId` yourself. You can assign it to a Cart during [creation](/search.md?urn=ctp:api:endpoint:/{projectKey}/carts:POST): `POST /{projectKey}/carts` with: ```json { "currency": "USD", "country": "US", "anonymousId": "foobar" } ``` If the Cart is ordered, the `anonymousId` will also be set on the new order. To obtain all Carts belonging to the Anonymous Session, use the [query predicate](/api/predicates/query.md) `anonymousId = "foobar"`: `GET /{projectKey}/carts?where=anonymousId%20%3D%20%22foobar%22` When the customer later signs in or signs up, pass the same `anonymousId` in the customer flow you implement. Passing the same `anonymousId` lets the platform associate the guest resources correctly. For the exact behavior by sign-in and sign-up method, see [Cart merge during sign-in and sign-up](/api/customers-overview.md#cart-merge-during-sign-in-and-sign-up). For example, when you sign up a Customer with regular OAuth tokens, include the same `anonymousId` in the request body: `POST /{projectKey}/customers` with: ```json { "firstName": "Alice", "lastName": "Doe", "email": "alice@example.com", "password": "secret", "anonymousId": "foobar" } ``` This lets the platform associate the guest Cart and other guest resources with the new Customer account. ## Conclusion You've seen how to implement guest checkout with anonymous-session tokens and with regular API tokens. The main design choice is whether you want the platform to manage the session context through the My endpoints or whether you want to manage the `anonymousId` lifecycle yourself. ## Related pages - [Area overview page with navigation](/tutorials.md) - [Next page: Reserve stock on Cart](/tutorials/reserve-stock-on-cart.md) - [Search documentation and API specs](/search.md)