> ## 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.

# reCAPTCHA for Guest Checkout

> Require guest (unauthenticated) Portal users to pass a Google reCAPTCHA challenge on the Cart and Checkout pages before they can pay.

fusionCore can challenge guest (unauthenticated) Portal visitors with Google reCAPTCHA before they pay. Logged-in users are never challenged. The challenge applies in two independently controlled places — turning one on does not turn on the other:

* The **Cart page** (the **FS Portal - Cart** component), when a guest picks **Continue as guest**.
* The **Checkout page**.

Where reCAPTCHA is configured for both v3 and v2, v3 (invisible, score-based) runs first and the v2 "I'm not a robot" checkbox is the fallback.

## Prerequisites

* At least one Google reCAPTCHA key pair (site key + secret key), v3 or v2, registered for your Portal site's domain in the Google reCAPTCHA admin console. Register both for v3-first with a v2 fallback. *Keys can be registered [here](https://www.google.com/recaptcha/admin/create)*
* A base64-encoded 256-bit (32-byte) AES key for token encryption.
* A Portal site with guest access already set up — see [Enabling Guest Portal Users](https://docs.fusioncore.us/end-user-guides/portal/enabling-guest-portal-users.md).
* Admin access to **Custom Metadata Types** and **Remote Site Settings** in **Setup**.

## How to generate the AES key

\*\*1. Generate key \*\*

Go to Developer Console (can be turned on in Set Up → Web Console) and paste the following code into the execute anonymous window:

`System.debug(EncodingUtil.base64Encode(Crypto.generateAesKey(256)));`

**2. Run the code**

Run the code and from the debug log, copy/paste the code into the AES key field on the Google reCAPTCHA Config metadata record and save.

## How to Configure reCAPTCHA

**1. Add a Remote Site Setting for Google**

In **Setup**, search for **Remote Site Settings** in the Quick Find box, click **New Remote Site**, enter a **Remote Site Name**, set **Remote Site URL** to `https://www.google.com`, and click **Save**. This isn't shipped with the package; without it, reCAPTCHA verification fails with **"Failed to verify Google reCAPTCHA"**.

**2. Create the Google reCAPTCHA Config record**

Go to **Setup → Custom Metadata Types → Google reCAPTCHA Config → Manage Records**, then click **New**. This creates a `FCORE_PORTAL__Google_reCAPTCHA_Config__mdt` record. The **Developer Name** must be exactly `DEFAULT` (uppercase) — fusionCore only reads a record with that exact name.

Fill in the fields you need, grouped by the record's layout sections:

| Section | Field | What it does |
| - | - | - |
| General Settings | **Token Encryption Key** (`FCORE_PORTAL__Token_Encryption_Key__c`) | The base64-encoded AES-256 key used to encrypt and decrypt reCAPTCHA verification tokens. Required (not enforced on the record) — leaving it blank produces **"Invalid Google reCAPTCHA config"**. An invalid (non-AES-256) key fails after the challenge with a message beginning "Failed to create Google reCAPTCHA token!" |
| General Settings | **Token Expiration Time In Minutes** (`FCORE_PORTAL__Token_Expiration_Time_In_Minutes__c`) | How long a passed challenge stays valid, in minutes. Drives both the token's validity and the browser cookie's expiry. Required (not enforced on the record). |
| V2 Settings | **V2 Site Key** / **V2 Secret Key** (`FCORE_PORTAL__V2_Site_Key__c` / `FCORE_PORTAL__V2_Secret_Key__c`) | The client-side site key and server-side secret key for the v2 checkbox challenge. Both must be filled for v2 to count as configured. |
| V3 Settings | **V3 Site Key** / **V3 Secret Key** (`FCORE_PORTAL__V3_Site_Key__c` / `FCORE_PORTAL__V3_Secret_Key__c`) | The client-side site key and server-side secret key for the invisible v3 challenge. Both must be filled for v3 to count as configured. |
| V3 Settings | **V3 Score Threshold** (`FCORE_PORTAL__V3_Score_Threshold__c`) | The minimum score Google must return for v3 to pass. Must be **strictly between 0 and 1** (for example, `0.50`) — a value of `0.00` or `1.00` silently disables v3; if v2 isn't configured either, guests see **"Invalid Google reCAPTCHA config"**. |

> [!NOTE]
>
> If no Portal `DEFAULT` record exists, but a legacy `FS_Google_reCAPTCHA_Configuration__mdt` `DEFAULT` record exists (from the [New User Registration](https://docs.fusioncore.us/end-user-guides/accelerators/new-user-registration.md) accelerator), fusionCore reuses those keys automatically, with a fixed v3 threshold of 0.95. Create a Portal `DEFAULT` record of your own to control the settings directly.

**3. Turn on the challenge for Checkout**

Go to **Setup → Custom Metadata Types → Constant → Manage Records**, then open **Validate Google reCAPTCHA On Checkout** (a `FCORE_BASE__Constant__mdt` record with developer name `Validate_Google_reCAPTCHA_On_Checkout`). Check **Checkbox Value** (`FCORE_BASE__Checkbox_Value__c`) and click **Save**. This Constant ships unchecked, so the Checkout page never challenges guests until you turn it on.

**4. Turn on the challenge for the Cart**

Go to **Setup → Custom Metadata Types → Store Settings → Manage Records**, then click **New**. This creates a `FS_PORTAL_Store_Settings__mdt` record — no record ships. Name it to match the **FS Portal - Cart** component's **Store Settings** property in Experience Builder (default `Default`).

* Check **Continue as Guest User** (`FS_PORTAL_Continue_As_Guest_User__c`) to let a guest proceed without logging in.
* Check **Validate reCAPTCHA For Guests** (`FS_PORTAL_Validate_reCAPTCHA_For_Guests__c`) to challenge them on the Cart page. The Cart's reCAPTCHA challenge only appears when both checkboxes are checked.
* Click **Save**.

> [!WARNING]
>
> If the Store Settings record named by the component's **Store Settings** property does not exist, the Cart page shows `Store Settings "Default" could not be found. Please contact support.` instead of the cart.

**5. Give the guest user the FC Portal - Checkout permission set**

The Site Guest User needs the **FC Portal - Checkout** permission set for the reCAPTCHA challenge to load, on both the Cart and the Checkout page. It's already included in the **fusionCore - Portal Guest User** permission set group described in [Enabling Guest Portal Users](https://docs.fusioncore.us/end-user-guides/portal/enabling-guest-portal-users.md). The Store's own permission sets — **FS Portal - Store** and **FS Portal - Checkout** — are not the same as **FC Portal - Checkout** and do not grant what the challenge needs.

If **fusionCore - Portal Guest User** is not assigned, assign it from the Site Guest User's **Permission Set Group Assignments → Edit Assignments**, or assign **FC Portal - Checkout** directly to the Site Guest User.

## What Guests See

### Cart Page

When **Validate reCAPTCHA For Guests** is on and a guest picks **Continue as guest**, the reCAPTCHA widget renders inline. Clicking **Continue** without a verified challenge shows the inline error **"Google reCAPTCHA has to be verified."**

### Checkout Page

When **Validate Google reCAPTCHA On Checkout** is on, the widget renders for a guest when all of the following are true:

* The user is a guest (not logged in).
* No payment restriction message is showing.
* The "pay next installment" prompt is not showing.
* The selected payment method is not Google Pay or Apple Pay — those two are never challenged.

Submitting without a verified challenge shows the toast **"Google reCAPTCHA has to be verified."**, and the v2 checkbox (if configured) is shown or reset so the guest can retry.

### The Challenge Itself

* **v3 (invisible)** runs first when configured: Google's badge appears fixed in the bottom-right corner, and the guest sees nothing else if they pass.
* **v2 (checkbox)** appears when v3 isn't configured, or when v3 fails (a low score or a wrong v3 secret key). Clicking the checkbox may open Google's image challenge, shown enlarged for readability.
* **Shared pass across pages.** A guest who passes the challenge on the Cart page is not re-challenged on Checkout, as long as they check out within the token's expiration window.
* **Misconfiguration** shows an inline notification titled **"Failed to load Google reCAPTCHA"**, with **"Missing Google reCAPTCHA config"** (no `DEFAULT` record), **"Invalid Google reCAPTCHA config"** (a required field is blank, or neither version is fully configured), or an access error (the Site Guest User is missing **FC Portal - Checkout**).
* **A failed verification** (wrong secret key, or a v2 attempt that doesn't pass) shows **"Failed to verify Google reCAPTCHA"**. For v2, the widget then stays hidden until the guest reloads the page.

## Limitations and Common Pitfalls wtih Guest Checkout reCAPTCHA

* **The Cart and Checkout challenges are controlled separately.** All three checkboxes — the Checkout Constant and the two Store Settings checkboxes — ship unchecked. Turn on the Constant to challenge guests at Checkout, and turn on the Store Settings checkboxes to challenge them on the Cart; enabling one does not enable the other.
* **A v3-only configuration has no fallback.** If a guest scores below the threshold, or their token expires right at submit, there is nothing to fall back to and they're blocked until they reload the page. Configure a v2 pair as well if you want a way forward for those guests.
* **A wrong site key fails silently.** Nothing renders and no error is shown until the guest tries to submit — double-check the site key first if the widget never appears.
* **Google Pay and Apple Pay are never challenged**, even when the Checkout challenge is on — they use a separate payment path.
* **An expired or invalid token at submit does not silently retry v3.** The guest sees "Google reCAPTCHA has to be verified." and the v2 checkbox (if configured) is shown or reset for them to try again.
* **Switching to a different Portal site re-triggers the challenge**, even within the token expiration window.
* **The guest user needs a specific permission set.** Only **FC Portal - Checkout** grants what the challenge needs — the Store's own permission sets, **FS Portal - Store** and **FS Portal - Checkout**, do not include it, so an otherwise fully-configured challenge won't load for the guest without it.
* **Double-check the basics first if guests can't get past the challenge.** Confirm the Google reCAPTCHA Config record's Developer Name is exactly `DEFAULT`, both **Token Encryption Key** and **Token Expiration Time In Minutes** are filled in, the key is a valid base64-encoded AES-256 key, **V3 Score Threshold** is strictly between 0 and 1, and the Remote Site Setting for `https://www.google.com` exists.

## Related Features

> [card] [Checkout (LWC) Overview](https://docs.fusioncore.us/end-user-guides/portal/checkout-lwc/index.md)
>
> See how the Checkout page is built from managed and unmanaged components.

> [card] [Enabling Guest Portal Users](https://docs.fusioncore.us/end-user-guides/portal/enabling-guest-portal-users.md)
>
> Set up guest access and assign the permission set group reCAPTCHA depends on.

> [card] [New User Registration](https://docs.fusioncore.us/end-user-guides/accelerators/new-user-registration.md)
>
> A separate accelerator with its own reCAPTCHA configuration for the registration flow.


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