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

# Riskified

> Connect to Riskified for e-commerce fraud prevention and risk assessment.

export const ConnectorHeader = ({data, name: nameProp, method: methodName, logo, category: categoryProp, catalog, providers}) => {
  const [logoStage, setLogoStage] = useState(0);
  const [chipLogoFailed, setChipLogoFailed] = useState(false);
  const [anchors, setAnchors] = useState({});
  useEffect(() => {
    const found = {};
    for (const id of ["capabilities", "supported-countries", "supported-currencies", "supported-payment-methods"]) {
      found[id] = Boolean(document.getElementById(id));
    }
    setAnchors(found);
  }, []);
  const hasData = Boolean(data && data.id);
  if (!hasData && !(nameProp && logo)) return null;
  const CATEGORY_LABELS = {
    card: "Cards",
    bank: "Banking",
    bnpl: "BNPL",
    cash: "Cash vouchers",
    crypto: "Crypto",
    wallet: "Wallets",
    tokenization: "Tokenization"
  };
  const DISPLAY_NAME_OVERRIDES = {
    authorizenet: "Authorize.net",
    cardpointe: "CardPointe",
    cybersource: "Cybersource",
    dlocal: "dLocal",
    shift4i4go: "Shift4 i4go",
    tokenex: "TokenEx",
    "worldine travelhub": "Worldline TravelHub"
  };
  const HIGHLIGHTS = [{
    keys: ["three_d_secure_pass_through", "three_d_secure_hosted"],
    label: "3-D Secure",
    cardOnly: true
  }, {
    keys: ["network_tokens_default", "network_tokens_toggle"],
    label: "Network tokens",
    cardOnly: true
  }, {
    keys: ["digital_wallets"],
    label: "Digital wallets"
  }, {
    keys: ["delayed_capture"],
    label: "Delayed capture"
  }, {
    keys: ["partial_capture"],
    label: "Partial capture"
  }, {
    keys: ["refunds"],
    label: "Refunds"
  }, {
    keys: ["partial_refunds"],
    label: "Partial refunds"
  }, {
    keys: ["zero_auth"],
    label: "Zero auth"
  }, {
    keys: ["settlement_reporting"],
    label: "Settlement reporting"
  }];
  const d = hasData ? data : {};
  const method = d.method || "";
  const provider = !hasData ? "" : method && d.id.endsWith(`-${method}`) ? d.id.slice(0, -(method.length + 1)) : d.id.split("-")[0];
  const fix = value => DISPLAY_NAME_OVERRIDES[(value || "").toLowerCase()] || value || "";
  const name = fix(d.provider) || nameProp || fix(d.displayName) || provider;
  const displayName = fix(d.displayName);
  const productName = !hasData ? "" : method === "card" ? d.provider ? displayName : "" : methodName || (d.provider && displayName !== name ? displayName : "");
  const methodLed = Boolean(productName);
  const cardProduct = methodLed && method === "card";
  const category = categoryProp || (method === "card" && !cardProduct ? "" : CATEGORY_LABELS[d.category] || "");
  const flowLabel = d.category !== "bank" ? "" : d.mode === "bank" ? "Stored in Gr4vy" : d.mode === "redirect" ? "Redirect" : "";
  const providerLogo = hasData ? `/assets/connectors/providers/${provider}.svg` : logo;
  const methodLogo = `/assets/connectors/methods/${method}.svg`;
  const title = methodLed ? productName : name;
  const chipLabel = !hasData ? "" : methodLed ? `via ${name}` : methodName;
  const chipLogo = cardProduct ? "" : methodLed ? providerLogo : methodLogo;
  const logos = methodLed && !cardProduct ? [methodLogo, providerLogo] : [providerLogo];
  const primaryLogo = logos[logoStage] || null;
  const enabled = new Set((d.features || "").split(/\s+/).filter(Boolean));
  const highlights = HIGHLIGHTS.filter(h => !(h.cardOnly && method !== "card") && h.keys.some(k => enabled.has(k)));
  const codes = value => (value || "").split(/\s+/).filter(Boolean);
  const providerSet = new Set(codes(providers));
  const members = !hasData && catalog && providerSet.size > 0 ? catalog.filter(e => providerSet.has(e.provider)) : [];
  const union = key => new Set(members.flatMap(e => codes(e[key]))).size;
  const methodsCount = members.length;
  const countries = hasData ? codes(d.supportedCountries).length : union("countries");
  const currencies = hasData ? codes(d.supportedCurrencies).length : union("currencies");
  const border = "1px solid rgba(128, 128, 128, 0.2)";
  const labelStyle = {
    fontSize: "0.6875rem",
    fontWeight: 600,
    letterSpacing: "0.05em",
    textTransform: "uppercase",
    opacity: 0.6
  };
  const chipStyle = {
    display: "inline-flex",
    alignItems: "center",
    gap: "0.3rem",
    padding: "0.1rem 0.5rem",
    borderRadius: "999px",
    border,
    fontSize: "0.8125rem",
    whiteSpace: "nowrap"
  };
  const renderStat = (label, value, anchor) => <a href={anchors[anchor] ? `#${anchor}` : undefined} style={{
    display: "flex",
    flexDirection: "column",
    gap: "0.1rem",
    textDecoration: "none",
    borderBottom: "none",
    color: "inherit",
    minWidth: "6rem"
  }}>
      <span style={labelStyle}>{label}</span>
      <span style={{
    fontSize: "1.25rem",
    fontWeight: 600
  }}>{value}</span>
    </a>;
  return <div className="not-prose" style={{
    border,
    borderRadius: "0.75rem",
    padding: "1.25rem",
    margin: "1rem 0 1.5rem",
    display: "flex",
    flexDirection: "column",
    gap: "1rem"
  }}>
      <div style={{
    display: "flex",
    alignItems: "center",
    gap: "1rem"
  }}>
        {primaryLogo ? <img src={primaryLogo} alt={`${title} logo`} width="56" height="56" onError={() => setLogoStage(logoStage + 1)} style={{
    width: "3.5rem",
    height: "3.5rem",
    borderRadius: "0.5rem",
    margin: 0,
    flexShrink: 0
  }} /> : <span aria-hidden="true" style={{
    width: "3.5rem",
    height: "3.5rem",
    borderRadius: "0.5rem",
    border,
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    fontSize: "1.5rem",
    fontWeight: 600,
    flexShrink: 0
  }}>
            {title.charAt(0).toUpperCase()}
          </span>}
        <div style={{
    display: "flex",
    flexDirection: "column",
    gap: "0.35rem",
    minWidth: 0
  }}>
          <span style={{
    fontSize: "1.25rem",
    fontWeight: 600,
    lineHeight: 1.2
  }}>{title}</span>
          <span style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "0.4rem",
    alignItems: "center"
  }}>
            {chipLabel ? <span style={chipStyle}>
                {chipLogoFailed || !chipLogo ? null : <img src={chipLogo} alt="" width="16" height="16" onError={() => setChipLogoFailed(true)} style={{
    width: "1rem",
    height: "1rem",
    borderRadius: "0.2rem",
    margin: 0
  }} />}
                {chipLabel}
              </span> : null}
            {category ? <span style={{
    ...chipStyle,
    opacity: 0.75
  }}>{category}</span> : null}
            {flowLabel ? <span style={{
    ...chipStyle,
    opacity: 0.75
  }}>{flowLabel}</span> : null}
          </span>
        </div>
      </div>

      {methodsCount > 0 || countries > 0 || currencies > 0 || highlights.length > 0 ? <div style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "1rem 2rem",
    paddingTop: "1rem",
    borderTop: border
  }}>
        {methodsCount > 0 ? renderStat("Payment methods", methodsCount, "supported-payment-methods") : null}
        {}
        {countries > 0 ? renderStat("Countries", countries >= 200 ? "No limit" : countries, "supported-countries") : null}
        {currencies > 0 ? renderStat("Currencies", currencies >= 150 ? "No limit" : currencies, "supported-currencies") : null}
        {highlights.length > 0 ? <div style={{
    display: "flex",
    flexDirection: "column",
    gap: "0.35rem",
    flex: "1 1 16rem"
  }}>
            <span style={labelStyle}>Highlights</span>
            <span style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "0.35rem"
  }}>
              {highlights.map(h => <span key={h.label} style={chipStyle}>
                  <span aria-hidden="true" style={{
    color: "#16a34a",
    fontWeight: 700
  }}>✓</span>
                  {h.label}
                </span>)}
              {anchors.capabilities ? <a href="#capabilities" style={{
    ...chipStyle,
    borderStyle: "dashed",
    textDecoration: "none",
    color: "inherit"
  }}>
                  All capabilities →
                </a> : null}
            </span>
          </div> : null}
      </div> : null}
    </div>;
};

<ConnectorHeader name="Riskified" logo="/assets/connectors/anti-fraud/riskified.svg" category="Anti-fraud" />

Riskified is an e-commerce fraud prevention platform that uses machine learning
and behavioral analytics to provide real-time fraud decisions. Riskified's
anti-fraud decisions can be used in Flow to trigger any action.

## Credentials

To configure a Riskified connection, you need to set the
following credentials.

| Credential | Description |
| :- | :- |
| Shop Domain | Your unique shop domain with Riskified |
| Auth Token | The authentication token for the Riskified API |

## Limited actions

By default, Gr4vy sends transaction status updates to Riskified for all transaction events, including refunds and voids. However, you can enable the **Limited Actions** flag in the connector configuration to limit these updates.

When the **Limited Actions** flag is enabled, Gr4vy only sends transaction status updates to Riskified during the initial transaction processing. Status updates for `refund` or `void` events are not sent to Riskified.

## Decision mapping

Decisions received from Riskified are mapped to the decisions according to the following logic.

| Riskified decision | Decision |
| :- | :- |
| `approve` | `accept` |
| `decline` | `reject` |
| `captured` | `skipped` |

As Riskified's product does not have a manual review queue, only `accept` or `reject` decisions are returned. A `captured` response can also be returned by Riskified, if you have set up a configuration with Riskified to only review a part of your volume.

If there is a technical issue reaching Riskified, the decision returns as an `exception`.

## Data requirements

To receive accurate anti-fraud recommendations from Riskified, it is important to provide comprehensive transaction data. While Riskified attempts to process transactions with limited data, providing the following fields significantly improves the quality and accuracy of fraud decisions.

### Recommended fields

For optimal fraud detection, it is highly recommended to include billing details with the following fields:

* `billing_details.first_name`
* `billing_details.last_name`
* `billing_details.phone_number`
* `billing_details.address.line1`
* `billing_details.address.country`
* `billing_details.address.city`
* `billing_details.address.postal_code`
* `billing_details.address.state`

If shipping details are provided, it is recommended to include the following fields:

* `shipping_details.first_name`
* `shipping_details.last_name`
* `shipping_details.phone_number`
* `shipping_details.address.line1`
* `shipping_details.address.country`
* `shipping_details.address.city`
* `shipping_details.address.postal_code`
* `shipping_details.address.state`

### Browser information

For optimal fraud detection accuracy, Riskified benefits from the following browser data being associated with a transaction.

| Requirement | Description |
| :- | :- |
| Language | The value of the `ACCEPT-LANGUAGE` header |
| User agent | The browser user agent |
| IP | The browser IP |

When using Embed or one of the e-commerce plugins, all of these values are automatically set.

If you create transactions by using direct API calls, it is recommended to include all `transaction.browser_info` fields. For the full list of fields, see the [`browser_info` object in the new transaction API reference](/reference/transactions/new-transaction#body-browser-info-one-of-0).

Please refer to the [IP address forwarding guide](/guides/api/ip-address-forwarding) for
more details on passing the IP address when making direct API calls.

### Custom options

You can pass Riskified-specific options using [connection options](/reference/transactions/new-transaction#body)
under the `riskified-anti-fraud` key.

<Note>
  These options mirror Riskified's own API format, including its field names. Where a
  field also exists on a Gr4vy address, the Riskified name and format take precedence,
  so that you can write these options directly from Riskified's reference.
</Note>

| Options | Description |
| :- | :- |
| `line_items` | Per-item overrides, matched by position against the cart items sent to Riskified. |
| `shipping_lines` | Per-delivery-charge overrides, matched by position against the `shipping_fee` cart items. |
| `additional_shipping_addresses` | Extra destinations for orders shipped to more than one address. |

#### Line items

| Field | Description |
| :- | :- |
| `delivered_to` | The delivery destination for the item. Valid values: `shipping_address`, `store_pickup`. |
| `shipping_address_id` | The address this item ships to. See [Multiple shipping addresses](#multiple-shipping-addresses). |

#### Shipping lines

| Field | Description |
| :- | :- |
| `shipping_address_id` | The address this delivery charge applies to. |

<Warning>
  Both options are matched by position, against two separate sequences.

  `line_items` entries are matched against the cart items Gr4vy sends to Riskified,
  which excludes `discount`, `shipping_fee`, `sales_tax`, `surcharge` and `store_credit`
  items. A shipping fee in the middle of your `cart_items` shifts every override after it.

  `shipping_lines` entries are matched against the `shipping_fee` items only, in the
  order they appear in `cart_items`.
</Warning>

### Multiple shipping addresses

A transaction holds one set of shipping details. For split shipments, supply the other
destinations in `additional_shipping_addresses`. The transaction's address is always
sent first, and these are appended after it.

| Field | Description |
| :- | :- |
| `id` | **Required.** Unique identifier, referenced by `shipping_address_id`. Cannot be `base-shipping-address`. |
| `first_name`, `last_name`, `phone` | The recipient at this address. `phone` must be formatted according to the E164 standard. |
| `address1`, `address2` | The first and second lines of the address. |
| `city`, `zip`, `company` | The city, zip or postal code, and company name for the address. |
| `country_code` | The country for the address in ISO 3166 format, for example `US`. |
| `province`, `province_code` | The state or province, and its code. |

The `country` name sent to Riskified is derived from `country_code` and cannot be
supplied directly.

<Note>
  `province_code` follows Riskified's format, which is the subdivision code on its own,
  for example `NY`. This differs from the Gr4vy `state_code` field on a buyer or
  transaction address, which is ISO 3166-2 and includes the country prefix, for example
  `US-NY`. Gr4vy converts `state_code` to Riskified's format automatically for the
  transaction's own address.
</Note>

#### Address ids

The address derived from the transaction always uses the reserved id
`base-shipping-address`. Ids are only sent when an order ships to more than one
destination, so a single-destination order sends no ids at all and
`shipping_address_id` must not be provided in that case.

`shipping_address_id` is optional on every entry. When an order ships to more than
one destination, Gr4vy sends an address id on every line item and shipping line,
using the transaction's address for anything you did not target.

```json theme={"system"}
{
  "cart_items": [
    { "name": "Blue Shirt", "quantity": 1, "unit_amount": 4999, "product_type": "physical" },
    { "name": "Shipping", "quantity": 1, "unit_amount": 500, "product_type": "shipping_fee" },
    { "name": "Red Shoes", "quantity": 1, "unit_amount": 8000, "product_type": "physical" }
  ],
  "connection_options": {
    "riskified-anti-fraud": {
      "additional_shipping_addresses": [
        {
          "id": "secondary-address",
          "first_name": "Jane",
          "last_name": "Roe",
          "address1": "456 Market Street",
          "city": "New York",
          "province": "New York",
          "province_code": "NY",
          "zip": "10001",
          "country_code": "US"
        }
      ],
      "line_items": [
        { "delivered_to": "shipping_address" },
        { "delivered_to": "shipping_address", "shipping_address_id": "secondary-address" }
      ],
      "shipping_lines": [{ "shipping_address_id": "secondary-address" }]
    }
  }
}
```

The overrides line up as follows. Note that the shipping fee sits between the two
products in `cart_items`, but does not take up a position in `line_items`:

| Override | Applies to |
| :- | :- |
| `line_items[0]` | Blue Shirt |
| `line_items[1]` | Red Shoes |
| `shipping_lines[0]` | Shipping |

Blue Shirt ships to the transaction's address, since its override sets no
`shipping_address_id`. Red Shoes and the delivery charge ship to
`secondary-address`.

### Cart items

Gr4vy maps `cart_items` to the Riskified order based on each item's `product_type`.

| Product type | Sent to Riskified as |
| :- | :- |
| `physical`, `digital`, `gift_card`, or not set | An entry in `line_items`. |
| `shipping_fee` | An entry in `shipping_lines`. |
| `discount` | Added to the order's `total_discounts`. |
| `store_credit` | An entry in `charge_free_payment_details`, with the gateway `store_credit`. |
| `sales_tax` or `surcharge` | Not sent. |

The amount of each cart item is calculated as `unit_amount` multiplied by `quantity`,
plus `tax_amount`.

#### Line item fields

Each cart item sent as a line item maps to the following Riskified fields.

| Riskified field | Cart item field |
| :- | :- |
| `title` | `name`. |
| `quantity` | `quantity`. |
| `price` | The cart item amount, including `tax_amount`. |
| `sku` | `sku`. |
| `product_id` | An identifier Gr4vy generates for the cart item. |
| `category` | The first entry in `categories`. Defaults to `unknown` when `categories` isn't set. |
| `sub_category` | The first entry in `subcategories`. Omitted when `subcategories` isn't set. |
| `brand` | `brand`. Omitted when `brand` isn't set. |
| `product_type` | `product_type`, sent as `physical`, `digital`, or `giftcard`. |
| `requires_shipping` | `true` when `product_type` is `physical`, otherwise `false`. |
| `delivered_to` | Not mapped from the cart item. Set it with the [`line_items` option](#line-items). |
| `shipping_address_id` | Not mapped from the cart item. See [Multiple shipping addresses](#multiple-shipping-addresses). |

For `digital` and `gift_card` items, Gr4vy also sets `sender_name` to the buyer's full
name, and `recipient` to the buyer's email address and phone number.

The `discount_amount` of each line item isn't subtracted from its `price`. Instead, it's
added to the order's `total_discounts`, together with the amount of any `discount`
cart items.

#### Shipping line fields

Each `shipping_fee` cart item maps to the following Riskified fields.

| Riskified field | Cart item field |
| :- | :- |
| `title` | `name`. |
| `price` | The cart item amount, including `tax_amount`. |
| `shipping_address_id` | Not mapped from the cart item. Set it with the [`shipping_lines` option](#shipping-lines). |

Other cart item fields, such as `external_identifier`, `upc`, `product_url`, and
`image_url`, aren't sent to Riskified.

#### Requirements

* The sum of all cart item amounts must equal the transaction's total amount.
* It is recommended to include a shipping line item if there are physical items.
* If a shipping line item is included, its title is mandatory. Set the title to `store_pickup` for store pickup orders.
* If the order is not a store pickup order, shipping details must be attached to the transaction. You can provide them in one of the following ways:
  * Store them against the buyer using the [new buyer shipping detail API](/reference/buyers/new-buyer-shipping-detail).
  * Include them directly on the transaction using the [`buyer.shipping_details` field in the new transaction API](/reference/transactions/new-transaction#body-buyer-one-of-0-shipping-details-one-of-0).

## Device fingerprinting

Device fingerprinting is recommended when using Riskified. Please refer to the
[device fingerprinting guide](/guides/features/anti-fraud/fingerprint) for more information on the universal solution.

If needed, you could load the <a href="https://developers.riskified.com/docs/beacon-for-web">fingerprint script for Riskified</a> directly and pass the `session_id` value as the `anti_fraud_fingerprint` to the <a>new transaction API</a>.


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