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

# Fraud Checks: Get Started

export const TxnTag = ({status}) => {
  const getStyles = status => {
    const baseStyle = {
      display: 'inline-block',
      padding: '4px 8px',
      borderRadius: '4px',
      fontSize: '13px',
      fontWeight: '400'
    };
    switch (status) {
      case "PENDING":
        return {
          ...baseStyle,
          backgroundColor: '#ececec',
          color: '#9f9f9f'
        };
      case "AUTHORIZED":
        return {
          ...baseStyle,
          backgroundColor: '#ecfdf5',
          color: '#047857'
        };
      case "SETTLED":
      case "PARTIALLY_SETTLED":
        return {
          ...baseStyle,
          backgroundColor: '#ecfdf5',
          color: '#047857'
        };
      case "DECLINED":
      case "FAILED":
        return {
          ...baseStyle,
          backgroundColor: '#fef2f2',
          color: '#dc2626'
        };
      case "CANCELLED":
        return {
          ...baseStyle,
          backgroundColor: '#fefce8',
          color: '#d78203'
        };
      case "SETTLING":
        return {
          ...baseStyle,
          backgroundColor: '#e0f2fe',
          color: '#0c4a6e'
        };
      default:
        return {
          ...baseStyle,
          backgroundColor: '#f3f4f6',
          color: '#374151'
        };
    }
  };
  return <span style={getStyles(status)}>{status}</span>;
};

export const ApiEndpoint = ({method, path}) => {
  const getMethodColor = method => {
    switch (method?.toUpperCase()) {
      case "GET":
        return "#0285c7";
      case "POST":
        return "#008d71";
      case "PUT":
        return "#16a34a";
      case "PATCH":
        return "#808080";
      case "DELETE":
        return "#dc2626";
      default:
        return "#6b7280";
    }
  };
  const getEndpointUrl = (method, path) => {
    const endpoints = {
      "POST /client-session": "/api-reference/v2.4/api-reference/client-session-api/create-a-client-session",
      "PATCH /client-session": "/api-reference/v2.4/api-reference/client-session-api/update-client-session",
      "POST /payments": "/api-reference/v2.4/api-reference/payments-api/create-a-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/api-reference/v2.4/api-reference/payments-api/resume-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/api-reference/v2.4/api-reference/payments-api/adjust-authorized-amount",
      "POST /payments/<PAYMENT_ID>/cancel": "/api-reference/v2.4/api-reference/payments-api/cancel-payment",
      "POST /payments/<PAYMENT_ID>/refund": "/api-reference/v2.4/api-reference/payments-api/refund-payment",
      "GET /payments/<PAYMENT_ID>": "/api-reference/v2.4/api-reference/payments-api/get-a-payment",
      "GET /payment-instruments": "/api-reference/v2.4/api-reference/payment-methods-api/list-saved-payment-methods",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/api-reference/v2.4/api-reference/payment-methods-api/delete-payment-method-payment-methods-token-delete"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return endpoints[key] || "#";
  };
  const getPrettyPath = (method, path) => {
    const pathMapping = {
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/payments/{paymentId}/resume",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/payments/{paymentId}/adjust-authorization",
      "POST /payments/<PAYMENT_ID>/cancel": "/payments/{paymentId}/cancel",
      "POST /payments/<PAYMENT_ID>/refund": "/payments/{paymentId}/refund",
      "GET /payments/<PAYMENT_ID>": "/payments/{paymentId}",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/payment-instruments/{paymentMethodToken}"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return pathMapping[key] || path;
  };
  const methodColor = getMethodColor(method);
  const url = getEndpointUrl(method, path);
  const displayPath = getPrettyPath(method, path);
  return <div style={{
    display: "inline-flex",
    alignItems: "center",
    cursor: "pointer",
    margin: "2px 0",
    padding: "4px",
    paddingRight: "6px",
    background: "rgb(245, 245, 245)",
    borderRadius: "6px",
    whiteSpace: "nowrap",
    textDecoration: "none"
  }}>
      <a href={url} target="_blank" rel="noopener noreferrer" style={{
    textDecoration: "none",
    border: "none"
  }}>
        <span style={{
    display: "inline-block",
    whiteSpace: "nowrap",
    padding: "0 8px",
    fontSize: "13px",
    lineHeight: "23px",
    borderRadius: "6px",
    fontWeight: 400,
    backgroundColor: methodColor,
    color: "white",
    border: "none"
  }}>
          {method.toUpperCase()}
        </span>
        <code style={{
    padding: "0",
    marginLeft: "4px",
    fontFamily: "monospace",
    color: methodColor,
    border: "none",
    textDecorationColor: methodColor
  }}>
          {displayPath}
        </code>
      </a>
    </div>;
};

## Configuration steps

### Step 1: Connect your fraud detection provider

<Note>
  You need at least one fraud detection provider connected to begin processing fraud checks through Primer.
</Note>

This process is very similar to [connecting a processor](/get-started/connect-a-processor). Set up the connection by following the steps below to enable Primer to communicate with the fraud detection provider on your behalf:

1. Select the fraud prevention provider you want to add via the [Primer Dashboard](https://dashboard.primer.io/integrations?status=active)
2. Add your provider by populating and submitting the form

![Connecting a fraud detection provider example](https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/embedded-fraud-checks/get-started/connect-provider-example.png)

### Step 2: Add fraud checks to your payment workflow

<Note>
  This guide assumes you already have a payment workflow configured. To learn more about how to set up a payment flow, read more **[here](/get-started/create-workflow)**.
</Note>

Add pre-authorization and/or post-authorization fraud checks to any of your “Authorize payment” Actions in your workflows.

In the Action side drawer, the Fraud Checks input section contains all the configurations required to set up your fraud checks.

![Select Fraud Provider Example](https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/embedded-fraud-checks/get-started/select-fraud-provider.png)

Select the fraud detection provider you will use for your fraud checks (pre-authorization and/or post-authorization) from the dropdown menu. This will be populated with all fraud detection providers connected in Step 1.

#### Pre-authorization fraud check

Toggle on “Apply pre-auth check” by selecting the checkbox. This means that every payment that is processed by this Action will attempt a pre-authorization fraud check.

![Activate Pre-Authorization Fraud Check](https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/embedded-fraud-checks/get-started/activate-pre-auth-check.png)

To enable your pre-authorization fraud check to dictate when to show 3DS, set the "3D Secure preference" to `Pre-auth fraud check settings`.

![3D Secure Preference Example](https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/embedded-fraud-checks/get-started/3ds-preference.png)

<Warning>
  If this is not set, regardless of the outcome of the pre-authorization fraud check, the "3D Secure preference" will take priority.
</Warning>

You need to determine the business logic for your pre-authorization fraud check and configure it appropriately. For each possible pre-authorization fraud check outcome, decide whether to show 3DS, run a 3DS exemption, go straight to authorization, or reject the payment.

This is configured by selecting one of the options from the dropdown for each outcome.

![Example of where to configure how to handle pre-auth check outcomes](https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/embedded-fraud-checks/get-started/select-pre-auth-outcomes.png)

<Note>
  If you decide to reject a payment after a fraud recommendation, the payment will either be:

  * automatically declined after a pre-authorization fraud check
  * or automatically cancel after a post-authorization fraud check

  In any case, this status will be visible in the payment status and payment timeline. See more below on this in the [How to monitor fraud checks](#how-to-monitor-fraud-checks) section. If it’s a customer-initiated payment, the customer will see the fail screen.
</Note>

#### Post-authorization fraud check

Toggle on “Apply post-auth check” by selecting the checkbox. This means that every payment that is processed by this Action will attempt a post-authorization fraud check.

Similarly to the pre-authorization fraud check, you need to decide how to handle scenarios where there’s a technical problem preventing the fraud check and the request fails: either the payment remains authorized or cancel the payment.

![Activate Post-Authorization Fraud Check](https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/embedded-fraud-checks/get-started/activate-post-auth-check.png)

<Note>
  If the fraud check does not pass, the payment will be canceled automatically. If it’s a customer-initiated payment, the customer will see the fail screen.
</Note>

### Step 3: Pass additional data in the client session

<Note>
  The same applies if you use the [advanced manual SDK flow](/checkout/advanced/manual-payment-creation) and send the <ApiEndpoint method="POST" path="/payments" /> request.
</Note>

The `customer` and `order` objects that can be passed in <ApiEndpoint method="POST" path="/client-session" /> and <ApiEndpoint method="POST" path="/payments" /> are used to populate the request to your fraud detection provider.

It’s recommended you agree with your provider on what fields should be passed to ensure optimum accuracy of the fraud check as this does vary based on which fraud detection provider you use.

The following additional data points will also be used in the fraud request if they are passed:

| Field                                                   | Type   |
| ------------------------------------------------------- | ------ |
| `fraud_context.device_details.device_id`                | string |
| `fraud_context.device_details.referring_site`           | string |
| `fraud_context.device_details.source`                   | string |
| `fraud_context.device_details.browser_ip`               | string |
| `fraud_context.device_details.accept_language`          | string |
| `fraud_context.device_details.user_agent`               | string |
| `fraud_context.device_details.cookie_token`             | string |
| `fraud_context.merchant_details.merchant_name`          | string |
| `fraud_context.merchant_details.merchant_provider_id`   | string |
| `fraud_context.merchant_details.merchant_category_code` | string |

To pass these, add the `fraud_context` object to the `metadata` object passed in the request. Below is an example:

```json theme={"dark"}
// POST /client-session
{
  "customerId": "customer-123",
  "amount": 2000,
  "currencyCode": "GBP",
  "orderId": "order-123",
  "order": {
    "lineItems": [
      {
        "itemId": "item 1",
        "name": "item 1",
        "description": "description of item 1",
        "amount": 1900,
        "quantity": 1
      }
    ],
    "countryCode": "GB",
    "shipping": {
      "amount": 100
    }
  },
  "customer": {
    "emailAddress": "user@email.com",
    "mobileNumber": "07777777777",
    "firstName": "firstname",
    "lastName": "lastname",
    "billingAddress": {
      "firstName": "firstname",
      "lastName": "lastname",
      "addressLine1": "address line 1",
      "addressLine2": "address line 2",
      "city": "city",
      "state": "state",
      "countryCode": "GB",
      "postalCode": "W1 2AW"
    },
    "shippingAddress": {
      "firstName": "firstname",
      "lastName": "lastname",
      "addressLine1": "address line 1",
      "addressLine2": "address line 2",
      "city": "city",
      "state": "state",
      "countryCode": "GB",
      "postalCode": "W1 2AW"
    }
  },
  "paymentMethod": {
    "vaultOnSuccess": true
  },
  "metadata": {
    "fraud_context": {
      "device_details": {
        "device_id": "id-123",
        "referring_site": "https://google.com",
        "source": "web",
        "browser_ip": "127.0.0.1",
        "accept_language": "EN",
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
        "cookie_token": "9dc6f83f78b0490"
      },
      "merchant_details": {
        "merchant_name": "merchant-name",
        "merchant_provider_id": "id-123",
        "merchant_category_code": "4414"
      }
    }
  }
}
```

## How to monitor fraud checks

You can monitor your fraud checks using the:

* payment timeline
* payment object

### Payment timeline

Primer is not a black box - your fraud check events will be visible in the payment timeline.

![Payment timeline example](https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/embedded-fraud-checks/get-started/payment-timeline-example.png)

Select a specific event to see the full requests and responses with your fraud detection provider.

![Side drawer example](https://goat-assets.production.core.primer.io/marketing/payment-capabilities/external-docs/embedded-fraud-checks/get-started/side-drawer-example.png)

### Payment object

For <ApiEndpoint method="POST" path="/payments" /> & <ApiEndpoint method="GET" path="/payments/<PAYMENT_ID>" /> (>=v2.2), the response includes the following object:

```json theme={"dark"}
"riskData": {
  "fraudCheck": {
    "source": "FRAUD_PROVIDER", // name of provider
    "preAuthorizationResult": "THREE_DS", // standardised result status
    "postAuthorizationResult": "ACCEPT"  // standardised result status
  }
}
```

preAuthorizationRecommendation clarifies which SCA exemption to apply when `preAuthorizationResult` is `THREE_DS_EXEMPTION`. See the API enum for possible values:

* [PreAuthorizationRecommendationEnum](/api-reference/v2.4/api-reference/payments-api/authorize-a-payment#response-risk-data-fraud-checks-pre-authorization-recommendation)

Note: `preAuthorizationRecommendation` is only returned when `preAuthorizationResult` is `THREE_DS_EXEMPTION`.

This is also part of the [Payment Status Update webhook](/api-reference/endpoints/v2.4/payment-webhooks/payment-status-update) notification as well.

## Testing

<Note>
  [Read the detailed guide on how to test pre-authorization and post-authorization fraud checks on Primer.](/testing/fraud-checks)
</Note>

## Notes

* The `riskData.fraudCheck.postAuthorizationResult` field won't be included in the [Payment Status Update webhook](/api-reference/endpoints/v2.4/payment-webhooks/payment-status-update) as the payment status updates before the post authorization fraud check is run.
  * If this field is required when you receive this webhook, use the <ApiEndpoint method="GET" path="/payments/<PAYMENT_ID>" /> request. The field will only be present once the post-authorization fraud check is complete.
  * If the payment is <TxnTag status="CANCELLED" /> due to the post-authorization fraud check, a new webhook notification will be sent and this field will be included.
