> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fusioncore.us/llms.txt
> Use this file to discover all available pages before exploring further.

# Guest Checkout

> Let shoppers buy from the Store without an account: placeholder records, how a guest is matched to a Contact and Account, the details they provide, and reCAPTCHA protection.

## Overview

Guest checkout lets someone buy without signing in. The shopper fills in their details at checkout, and fusionCore resolves them to a real Contact and Account behind the scenes — matching an existing person where it can, creating records where it cannot.

Until that point a guest's cart is not a Salesforce record at all: it lives in their browser. The Order is created only when they continue from the Cart page, and it is parented to placeholder records until they identify themselves at checkout.

> [!NOTE]
>
> Guest checkout is off by default. Turn it on with **Continue as Guest User** on the [Store Settings](https://docs.fusioncore.us/end-user-guides/portal/store/setting-up-store-settings.md) record.

## Prerequisites

* Guests can reach your Store pages — see [Enabling Guest Portal Users](https://docs.fusioncore.us/end-user-guides/portal/enabling-guest-portal-users.md).
* A placeholder Account and Contact exist, dedicated to this purpose.
* You have decided how guests should map to Accounts.

## Set Up Guest Checkout

**1. Create the placeholder records**

Create one Account and one Contact to own guest orders before the shopper is identified. Name them so no one mistakes them for real records — for example `Store Guest Checkout Placeholder`.

> [!NOTE]
>
> These records are never shown to the shopper. They exist so an Order can be saved before anyone knows who is buying.

**2. Turn guest checkout on**

On the Store Settings record, check **Continue as Guest User** and set **Placeholder Account Id** and **Placeholder Contact Id**.

> [!WARNING]
>
> A validation rule (`FS_PORTAL_Placeholder_Ids_Required`) blocks the save if either placeholder Id is missing while **Continue as Guest User** is on — the record cannot be left in a state that fails at runtime.

**3. Decide how guests map to Accounts**

Set **Guest Account Logic**:

| Value | Behavior |
| - | - |
| `Bucket Account` | Every guest is placed on one shared Account, named in **Guest Bucket Account Id** |
| `Individual Account` | A new Account is created per guest, named by **Guest Account Name Pattern** — for example `{!FirstName} {!LastName}` |

> [!NOTE]
>
> If **Person Accounts** are enabled in your org, this setting is ignored: fusionCore creates a Person Account for the guest instead. That is usually what you want, since a Person Account is the natural home for an individual buyer.

`Bucket Account` requires **Guest Bucket Account Id**, enforced by the `FS_PORTAL_Guest_Bucket_Acc_Id_Required` validation rule.

**4. Choose what details to collect**

Set **Additional Details Field Set** to a Contact field set, and its fields appear to guests as an **Additional Details** sub-section at checkout, on top of the name, email, and billing address always collected. Leave it blank to hide the sub-section.

The sub-section is shown to **guests only** — a member already has a Contact, so there is nothing to collect. Values a guest enters are used to create a new Contact when no existing one matches; they never overwrite a matched Contact.

> [!TIP]
>
> Keep the field set short. Every field is one more thing between a shopper and a completed purchase — and required fields in the set are enforced, so a long set becomes a wall.

**5. Turn on reCAPTCHA**

Check **Validate reCAPTCHA For Guests** so a guest must pass a Google reCAPTCHA challenge on the Cart page before continuing. It applies only to guests who chose **Continue as Guest** — members never see it.

## What the Shopper Sees

**1. Choose how to continue**

On the Cart page a guest picks **Continue as Guest** or **Login / Create an account**. With **Continue as Guest User** turned off, only the login choice appears.

**2. Pass the challenge**

When reCAPTCHA is enabled, the guest completes it here. Failing it stops **Continue** with a message rather than proceeding.

**3. Provide details at checkout**

On the Checkout page, **Your Details** has three parts, and each behaves differently for a guest than for a member.

| Sub-section | Guest sees | Member sees |
| - | - | - |
| First Name, Last Name, Email | Blank, editable inputs | Their Contact's values, read-only |
| **Additional Details** | Blank, editable inputs for the field set's fields | Hidden entirely |
| Billing Address | Editable address fields | Their Contact's mailing address, editable |

Whatever is submitted here overrides the Billing Address on the Order, for guests and members alike — so a member buying on behalf of someone else can bill elsewhere without their Contact record changing.

> [!NOTE]
>
> Guest orders hide the Account and Bill To Contact fields, and the Notification Email field — those are resolved from what the guest enters, so showing them would be confusing and editable in the wrong direction.

**4. Pay**

On submit, fusionCore resolves the Contact and Account, re-parents the Order from the placeholders to those real records, and processes the payment.

## How a Guest Becomes a Contact

On submit, fusionCore matches the guest to an existing Contact **by email** and reuses it if found — so a repeat buyer accumulates orders against one Contact rather than a new one each time.

| Situation | Result |
| - | - |
| A Contact matches the email | That Contact is reused. Its existing field values are **not** overwritten |
| No Contact matches | A new Contact is created from the form, flagged **Guest Contact** (`FS_PORTAL_Guest_Contact__c`) |
| Person Accounts are enabled | A Person Account is created, with the billing address as its mailing address |

> [!NOTE]
>
> To match on something other than email, write an Apex class implementing `FS_PORTAL_StoreContactMatcher` and name it in **Contact Matcher Class**. Matching on a membership number or an external id are the usual reasons.

The **Guest Contact** checkbox marks records the storefront created this way, which makes them easy to find and merge later. It is set automatically — do not edit it by hand.

> [!WARNING]
>
> Email matching is only as good as your data. Two people sharing an email address resolve to the same Contact, and a guest who typos their email creates a new Contact rather than matching their own. Plan on periodic de-duplication of `Guest Contact` records.

## Guest Order Token Encryption Key

In Setup → Custom Metadata Types → Constants you will need to ensure that the Guest Order Token Encryption Key for your org is set properly, like shown in the screenshot below.

This code can be generated with the following code in the execute anonymous window: System.debug(EncodingUtil.base64Encode(Crypto.generateAesKey(256)));

![Image](https://mintcdn.com/fusionspan/XDzICb2WNqgAWbUY/images/image-11.png?fit=max\&auto=format\&n=XDzICb2WNqgAWbUY\&q=85\&s=396e72cfad69e4c14da7fa716d91161e)

## Limitations and Common Pitfalls with Guest Checkout

* **A guest's cart is browser-local and unrecoverable.** No Order exists until they continue from the Cart page, so an abandoned guest cart leaves nothing behind to follow up on.
* **Placeholder records must be dedicated to this.** Pointing at a real Account or Contact parents every unidentified guest order onto it, polluting a customer's record.
* **Existing Contact data is never overwritten.** A matched Contact keeps its current name and address even when the guest typed something different — the new address goes on the Order, not onto the person.
* **`Bucket Account` makes guest revenue hard to attribute.** Every guest sits on one Account. Prefer `Individual Account`, or Person Accounts, when you care about reporting per buyer.
* **Person Accounts override Guest Account Logic.** If they are enabled, your Bucket or Individual choice is ignored, which surprises people who set it and saw no effect.
* **A long Additional Details field set costs conversions**, and required fields in it are enforced at submit.
* **reCAPTCHA covers the guest path only.** It protects record creation at the Cart page; it is not a defense on pages a member reaches.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.