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

# Automatic anti-fraud device fingerprinting

> Enabling automatic device fingerprinting

A device fingerprint uniquely identifies the device a customer is using
at checkout. Anti-fraud connections use this to determine whether
this device or user has been flagged for fraudulent behavior in the past, allowing
it to reject the transaction and protecting you from fraud.

Each anti-fraud service has a different way of collecting the device fingerprint,
and therefore the `f.js` library wraps around each of
these, allowing focus on the preferred anti-fraud service.

<Info>
  If using Embed or one of the e-commerce plugins, then none of the steps below are necessary. Embed automatically loads the
  right library and ensures the device fingerprint is collected.
</Info>

## Usage without Embed

To create a device fingerprint, load the `f.js` library into your checkout page. This
can be the page on which you render your checkout using Secure Fields, or any other integration.

```html theme={"system"}
<script src="https://api.{instance_id}.gr4vy.app/f.js"></script>
```

<Note>
  In a sandbox environment make sure you use `api.sandbox.{instance_id}
      .gr4vy.app/f.js`.
</Note>

This automatically loads the fingerprinting library for your [**Primary**](/guides/features/anti-fraud/overview#connection-mode) anti-fraud service — and, if any [**Silent**](/guides/features/anti-fraud/silent-mode) services are configured, their libraries too — seeding all of them with the same shared fingerprint value. The value is attached to `window.gr4vyAntiFraud.f` and can be sent as the [`anti_fraud_fingerprint`](/reference/transactions/new-transaction#body-anti-fraud-fingerprint) property when creating a transaction.

## Embed, e-commerce, and custom

When using Embed, or one of the e-commerce plugins like Magento, then the device fingerprint is automatically created
and sent along when creating a transaction. This behavior can be overridden by sending in a custom fingerprint to Embed.

For example, if the anti-fraud service in use is known,
and that service's fingerprint script has already been loaded, then the fingerprint created by that service can be passed directly
to Embed or the API. When the `antiFraudFingerprint` value is set, the device fingerprint libraries are not loaded and, instead,
the fingerprint provided is passed along as-is when creating a transaction.

<CodeGroup>
  ```js React theme={"system"}
  <Embed
      gr4vyId='example'
      antiFraudFingerprint="my-fingerprint-id"
      ...
  />
  ```

  ```js Node / CDN theme={"system"}
  setup({
      gr4vyId: "example",
      antiFraudFingerprint: "my-fingerprint-id",
      ...
  });
  ```
</CodeGroup>

<br />

<Info>
  For most anti-fraud services the `fingerprint` represents either the session
  ID or device fingerprint ID defined by that service's anti-fraud library.
  Please refer to the documentation of your anti-fraud service for more details.
</Info>

## Custom & native fingerprints

In the event the automated solution cannot be used to generate the device fingerprint,
use the anti-fraud fingerprint libraries directly and then pass the fingerprint
by using the [`anti_fraud_fingerprint`](/reference/transactions/new-transaction#body-anti-fraud-fingerprint) when creating a new transaction.

<Warning>
  When accepting PayPal the device fingerprint is sent to both PayPal and
  the Anti-Fraud service. To ensure the same fingerprint works for both
  services, creating a PayPal fingerprint first is recommended, and then passing
  the ID generated by their library to the anti fraud fingerprint library to
  seed the value.
</Warning>

## Native mobile fingerprinting

If you build a native mobile checkout without one of Gr4vy's [Embed SDKs](/guides/payments/native/sdks) wrapping a web view, the providers' web fingerprint scripts cannot run. Instead, integrate each anti-fraud provider's native iOS and Android SDKs and forward a single shared identifier as `anti_fraud_fingerprint`.

The platform forwards that single identifier to every configured provider — Primary and any [Silent](/guides/features/anti-fraud/silent-mode) services — as the device session identifier on each provider's server-side decision request. So the only requirement for native is: **register every provider's device profile under one shared identifier, and pass that exact same identifier to Gr4vy as `anti_fraud_fingerprint` so each provider can correlate the device profile with its decision request.**

There are two viable patterns:

### Pattern A — Merchant-generated identifier, pushed into each provider's SDK

Generate a unique identifier (for example, a UUID) at the start of the checkout session, then push it into each provider's mobile SDK *before* it emits any events. Each provider registers its device profile under that identifier; the same identifier is then forwarded server-side, and each provider can stitch the profile to the transaction. Use whatever format the providers you're integrating with accept.

This is the native equivalent of how `f.js` exposes a fingerprint on `window.gr4vyAntiFraud.f` on web.

<CodeGroup>
  ```swift Swift theme={"system"}
  let fingerprintUUID = UUID().uuidString

  // Push the UUID into the anti-fraud provider SDK BEFORE any events are emitted,
  // so the device profile is registered under this UUID on the provider's backend.
  // The method names below are pseudocode — see your provider's mobile SDK docs.
  ProviderASDK.shared.configure(siteId: PROVIDER_A_SITE_ID)
  ProviderASDK.shared.setDeviceUID(fingerprintUUID)

  // Same UUID seeds the second provider's session.
  ProviderBSDK.profileRequest(sessionID: fingerprintUUID)

  // Forward the same UUID to your own backend, which then includes it
  // as `anti_fraud_fingerprint` when calling Gr4vy's Create transaction API.
  yourCheckoutBackend.startTransaction(
      amount: 12345,
      currency: "AUD",
      antiFraudFingerprint: fingerprintUUID
  )
  ```

  ```kotlin Kotlin theme={"system"}
  val fingerprintUUID = UUID.randomUUID().toString()

  // Method names below are pseudocode — see your provider's mobile SDK docs.
  ProviderASDK.getInstance().configure(context, PROVIDER_A_SITE_ID)
  ProviderASDK.getInstance().setDeviceUID(fingerprintUUID)

  ProviderBSDK.getInstance().profile(
      ProfilingOptions().setSessionID(fingerprintUUID),
      null
  )

  // Forward the same UUID to your own backend, which then includes it
  // as `anti_fraud_fingerprint` when calling Gr4vy's Create transaction API.
  yourCheckoutBackend.startTransaction(
      amount = 12345,
      currency = "AUD",
      antiFraudFingerprint = fingerprintUUID
  )
  ```
</CodeGroup>

<Note>
  The exact "set device UID" / "set event ID" API name varies by provider and SDK version — refer to your provider's mobile SDK documentation.
</Note>

### Pattern B — Use one provider's native UID as the shared identifier

If a provider's mobile SDK auto-generates a stable per-install identifier (for example, a UID derived from iOS's identifier for vendor (IDFV)) and does not expose a setter to inject your own value, let it generate the identifier, read it out, and use it as the seed for any other providers and for Gr4vy.

<CodeGroup>
  ```swift Swift theme={"system"}
  // Method names below are pseudocode — see your provider's mobile SDK docs.
  ProviderASDK.shared.configure(siteId: PROVIDER_A_SITE_ID)
  let providerAUID = ProviderASDK.shared.getDeviceUID()  // SDK-generated

  // Use Provider A's UID as the seed for Provider B's session.
  ProviderBSDK.profileRequest(sessionID: providerAUID)

  // Forward the UID to your own backend, which then includes it
  // as `anti_fraud_fingerprint` when calling Gr4vy's Create transaction API.
  yourCheckoutBackend.startTransaction(
      amount: 12345,
      currency: "AUD",
      antiFraudFingerprint: providerAUID
  )
  ```

  ```kotlin Kotlin theme={"system"}
  // Method names below are pseudocode — see your provider's mobile SDK docs.
  ProviderASDK.getInstance().configure(context, PROVIDER_A_SITE_ID)
  val providerAUID = ProviderASDK.getInstance().getDeviceUID()

  ProviderBSDK.getInstance().profile(
      ProfilingOptions().setSessionID(providerAUID),
      null
  )

  // Forward the UID to your own backend, which then includes it
  // as `anti_fraud_fingerprint` when calling Gr4vy's Create transaction API.
  yourCheckoutBackend.startTransaction(
      amount = 12345,
      currency = "AUD",
      antiFraudFingerprint = providerAUID
  )
  ```
</CodeGroup>

<Note>
  Each provider may have its own format requirements for the session or device identifier it accepts. Refer to your provider's connector documentation for the exact format expected for `anti_fraud_fingerprint`.
</Note>

### Which pattern to use

* **Use Pattern A** when every provider's mobile SDK exposes a way to inject a merchant-generated identifier. It keeps the seed provider-independent — useful if you may add or swap providers later.
* **Use Pattern B** when at least one provider's SDK does not expose an injection hook. It inverts the dependency — that provider becomes the source of the identifier — but always works.

## Merchant accounts

In an environment with multiple merchant accounts it's important to add the `merchant_account_id` as a query
parameter to the fingerprint script. This ensures the script is loaded for the [**Primary**](/guides/features/anti-fraud/overview#connection-mode) anti-fraud service — and any [**Silent**](/guides/features/anti-fraud/silent-mode) services configured — for that specific merchant account.

```html theme={"system"}
<script
  src="https://api.{instance_id}.gr4vy.app/f.js?merchant_account_id=example"
  type="text/javascript"
></script>
```

Please note that when using an Integration API key with Embed or one of the e-commerce platforms, then the `merchantAccountId` needs to be set
explicitly for Embed to load the anti-fraud scripts for that merchant account.

<CodeGroup>
  ```js React theme={"system"}
  <Embed
      gr4vyId='example'
      merchantAccountId="my-merchant-id"
      ...
  />
  ```

  ```js Node / CDN theme={"system"}
  setup({
      gr4vyId: "example",
      merchantAccountId: "my-merchant-id"
      ...
  });
  ```
</CodeGroup>
