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

# Fraud Prevention & Blocking

> Proactively block IPs, emails, and card BINs. Detect unusual order amounts and auto-block repeat offenders.

# Fraud Prevention & Blocking

Niftipay gives you tools to proactively block fraud — without waiting for chargebacks. You can manually block IPs, emails, and card BINs, and the system automatically blocks identifiers associated with unusual order patterns.

These APIs work across **fiat orders** and **onramping** flows.

This page covers:

* [Overview — how it works](#overview)
* [Block an IP address](#block-an-ip-address) (`POST /api/fraud/blocked-ips`)
* [List blocked IPs](#list-blocked-ips) (`GET /api/fraud/blocked-ips`)
* [Unblock an IP](#unblock-an-ip) (`DELETE /api/fraud/blocked-ips/:id`)
* [Block an email](#block-an-email) (`POST /api/fraud/blocked-emails`)
* [List blocked emails](#list-blocked-emails) (`GET /api/fraud/blocked-emails`)
* [Unblock an email](#unblock-an-email) (`DELETE /api/fraud/blocked-emails/:id`)
* [Block a card BIN](#block-a-card-bin) (`POST /api/fraud/blocked-bins`)
* [List blocked BINs](#list-blocked-bins) (`GET /api/fraud/blocked-bins`)
* [Unblock a BIN](#unblock-a-bin) (`DELETE /api/fraud/blocked-bins/:id`)
* [Unusual amount detection](#unusual-amount-detection) — automatic
* [Velocity auto-blocking](#velocity-auto-blocking) — automatic
* [Fraud alerts](#fraud-alerts) (`GET /api/fraud/alerts`) — view flagged orders
* [Updated fraud signals](#updated-fraud-signals)

***

## Overview

Niftipay provides **three layers** of proactive fraud prevention on top of the existing [chargeback-based blocking](/api/chargebacks):

### 1. Manual blocking (IP, email, BIN)

You can block an IP address, email, or card BIN at any time using the APIs below. Blocked customers see a block page with their case number instead of the payment form.

* **IP blocking** — block a specific IP address you know is fraudulent
* **Email blocking** — block a specific email address
* **BIN blocking** — block an entire card range by its BIN (first 6 digits of the card number, identifying the issuing bank). Useful when you see a pattern of fraud from cards issued by the same bank.

### 2. Unusual amount detection

Niftipay automatically monitors your order amounts. When an order is significantly higher than your historical average, it is flagged as an **amount anomaly**. This helps catch fraud attempts using stolen cards for unusually large purchases.

* The system computes your average order amount per currency using your completed orders
* Orders with a [z-score](https://en.wikipedia.org/wiki/Standard_score) of 3.0 or higher are flagged as **warning** severity
* Orders with a z-score of 5.0 or higher are flagged as **critical** severity
* Anomaly detection activates after you have at least **10 completed orders** in a given currency

Flagged orders are **not automatically blocked** — they appear as fraud signals in the [fraud signals API](/api/chargebacks#fraud-signals-order-risk-check) and in fraud alert emails so you can review them.

### 3. Velocity auto-blocking

If the **same IP address** or **same email** submits **2 or more** amount-anomaly orders within a 24-hour window, Niftipay automatically blocks that IP or email. This catches attackers who rapidly test stolen cards with high amounts.

Auto-blocked identifiers appear in your [chargeback cases](/api/chargebacks#chargeback-cases-blocked-ips--emails) and can be unblocked from the dashboard or via the API.

### Dashboard

In the Niftipay dashboard, you can find these features under **Fraud Protection**:

* **Chargeback Cases** — view all blocked IPs and emails (automatic, manual, and velocity-based)
* **Alerts** — view orders flagged with suspicious activity, and block/unblock IPs and emails with one click

You can also use the [Fraud Alerts API](#fraud-alerts) to integrate alerts into your own systems.

***

## Authentication

All endpoints below require **API key** or **session** authentication.

```bash theme={null}
curl -X GET "https://www.niftipay.com/api/fraud/blocked-ips" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

***

# Block an IP Address

## Endpoint

`POST /api/fraud/blocked-ips`

Manually block an IP address. Blocked customers from this IP will see a block page instead of the payment form.

### Request body

```json theme={null}
{
  "ipAddress": "203.0.113.42",
  "reason": "Multiple failed payment attempts"
}
```

| Field       | Type   | Required | Notes                         |
| ----------- | ------ | -------- | ----------------------------- |
| `ipAddress` | string | Yes      | IPv4 or IPv6 address.         |
| `reason`    | string | No       | Optional reason for blocking. |

### Example request

```bash theme={null}
curl -X POST "https://www.niftipay.com/api/fraud/blocked-ips" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ipAddress": "203.0.113.42", "reason": "Multiple failed payment attempts"}'
```

### Example response (201)

```json theme={null}
{
  "ok": true,
  "blockedIp": {
    "id": 15,
    "caseNumber": "CB-00015",
    "ipAddress": "203.0.113.42",
    "reason": "Multiple failed payment attempts"
  }
}
```

### Error: already blocked (409)

```json theme={null}
{
  "ok": false,
  "error": "IP 203.0.113.42 is already blocked (case CB-00015)"
}
```

***

# List Blocked IPs

## Endpoint

`GET /api/fraud/blocked-ips`

Returns all currently blocked IPs for your account — including both manually blocked and automatically blocked (from chargebacks or velocity detection).

### Example request

```bash theme={null}
curl -X GET "https://www.niftipay.com/api/fraud/blocked-ips" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

### Example response

```json theme={null}
{
  "ok": true,
  "blockedIps": [
    {
      "id": 15,
      "caseNumber": "CB-00015",
      "kind": "ip_manual",
      "ipAddress": "203.0.113.42",
      "cardNames": [],
      "truncatedPans": [],
      "orderEmails": [],
      "createdAt": "2026-04-15T10:00:00.000Z"
    },
    {
      "id": 3,
      "caseNumber": "CB-00003",
      "kind": "ip",
      "ipAddress": "198.51.100.10",
      "cardNames": ["John Doe"],
      "truncatedPans": ["460332******1234"],
      "orderEmails": ["john@example.com"],
      "createdAt": "2026-04-10T12:00:00.000Z"
    }
  ]
}
```

### Response fields

| Field           | Type      | Description                                                                                                                             |
| --------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `id`            | number    | Case ID (used for unblocking).                                                                                                          |
| `caseNumber`    | string    | Human-readable case number (e.g. `CB-00015`).                                                                                           |
| `kind`          | string    | How the IP was blocked: `"ip_manual"` (you blocked it), `"ip"` (chargeback auto-block), or `"ip_amount_anomaly"` (velocity auto-block). |
| `ipAddress`     | string    | The blocked IP address.                                                                                                                 |
| `cardNames`     | string\[] | Cardholder names from related orders (if any).                                                                                          |
| `truncatedPans` | string\[] | Card numbers from related orders (if any).                                                                                              |
| `orderEmails`   | string\[] | Emails from related orders (if any).                                                                                                    |
| `createdAt`     | string    | ISO 8601 timestamp when the block was created.                                                                                          |

***

# Unblock an IP

## Endpoint

`DELETE /api/fraud/blocked-ips/:id`

Unblocks a previously blocked IP address.

### Path parameters

| Name | Type   | Notes                               |
| ---- | ------ | ----------------------------------- |
| `id` | number | The case ID from the list response. |

### Query parameters

| Name     | Type   | Required | Notes                           |
| -------- | ------ | -------- | ------------------------------- |
| `reason` | string | No       | Optional reason for unblocking. |

### Example request

```bash theme={null}
curl -X DELETE "https://www.niftipay.com/api/fraud/blocked-ips/15?reason=False+positive" \
  -H "x-api-key: YOUR_API_KEY"
```

### Example response

```json theme={null}
{
  "ok": true,
  "unblocked": {
    "id": 15,
    "caseNumber": "CB-00015",
    "ipAddress": "203.0.113.42"
  }
}
```

***

# Block an Email

## Endpoint

`POST /api/fraud/blocked-emails`

Manually block an email address.

### Request body

```json theme={null}
{
  "email": "fraudster@example.com",
  "reason": "Confirmed fraud"
}
```

| Field    | Type   | Required | Notes                                           |
| -------- | ------ | -------- | ----------------------------------------------- |
| `email`  | string | Yes      | Valid email address (automatically lowercased). |
| `reason` | string | No       | Optional reason for blocking.                   |

### Example request

```bash theme={null}
curl -X POST "https://www.niftipay.com/api/fraud/blocked-emails" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "fraudster@example.com", "reason": "Confirmed fraud"}'
```

### Example response (201)

```json theme={null}
{
  "ok": true,
  "blockedEmail": {
    "id": 16,
    "caseNumber": "CB-00016",
    "email": "fraudster@example.com",
    "reason": "Confirmed fraud"
  }
}
```

### Error: already blocked (409)

```json theme={null}
{
  "ok": false,
  "error": "Email fraudster@example.com is already blocked (case CB-00016)"
}
```

***

# List Blocked Emails

## Endpoint

`GET /api/fraud/blocked-emails`

Returns all currently blocked emails for your account.

### Example request

```bash theme={null}
curl -X GET "https://www.niftipay.com/api/fraud/blocked-emails" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

### Example response

```json theme={null}
{
  "ok": true,
  "blockedEmails": [
    {
      "id": 16,
      "caseNumber": "CB-00016",
      "kind": "email_manual",
      "email": "fraudster@example.com",
      "cardNames": [],
      "truncatedPans": [],
      "orderEmails": ["fraudster@example.com"],
      "createdAt": "2026-04-15T11:00:00.000Z"
    }
  ]
}
```

### Response fields

| Field           | Type      | Description                                                                                                                                         |
| --------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`            | number    | Case ID (used for unblocking).                                                                                                                      |
| `caseNumber`    | string    | Human-readable case number.                                                                                                                         |
| `kind`          | string    | How the email was blocked: `"email_manual"` (you blocked it), `"email"` (chargeback auto-block), or `"email_amount_anomaly"` (velocity auto-block). |
| `email`         | string    | The blocked email address.                                                                                                                          |
| `cardNames`     | string\[] | Cardholder names from related orders (if any).                                                                                                      |
| `truncatedPans` | string\[] | Card numbers from related orders (if any).                                                                                                          |
| `orderEmails`   | string\[] | Emails from related orders (if any).                                                                                                                |
| `createdAt`     | string    | ISO 8601 timestamp.                                                                                                                                 |

***

# Unblock an Email

## Endpoint

`DELETE /api/fraud/blocked-emails/:id`

### Example request

```bash theme={null}
curl -X DELETE "https://www.niftipay.com/api/fraud/blocked-emails/16?reason=Customer+verified" \
  -H "x-api-key: YOUR_API_KEY"
```

### Example response

```json theme={null}
{
  "ok": true,
  "unblocked": {
    "id": 16,
    "caseNumber": "CB-00016",
    "email": "fraudster@example.com"
  }
}
```

***

# Block a Card BIN

## Endpoint

`POST /api/fraud/blocked-bins`

Block an entire card range by its BIN (Bank Identification Number). The BIN is the **first 6 digits** of a card number and identifies the issuing bank. This is useful when you notice a pattern of fraud from cards issued by the same bank.

For example, if you see multiple fraudulent orders from cards starting with `443047`, you can block that BIN to prevent all cards in that range from being used on your checkout.

### Request body

```json theme={null}
{
  "bin": "443047",
  "reason": "Fraud pattern detected from this card range"
}
```

| Field    | Type   | Required | Notes                               |
| -------- | ------ | -------- | ----------------------------------- |
| `bin`    | string | Yes      | Exactly 6 digits (e.g. `"443047"`). |
| `reason` | string | No       | Optional reason for blocking.       |

### Example request

```bash theme={null}
curl -X POST "https://www.niftipay.com/api/fraud/blocked-bins" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"bin": "443047", "reason": "Fraud pattern detected from this card range"}'
```

### Example response (201)

```json theme={null}
{
  "ok": true,
  "blockedBin": {
    "id": 5,
    "bin": "443047",
    "reason": "Fraud pattern detected from this card range",
    "createdAt": "2026-04-15T12:00:00.000Z"
  }
}
```

### Error: already blocked (409)

```json theme={null}
{
  "ok": false,
  "error": "BIN 443047 is already blocked"
}
```

### How to find a card's BIN

The BIN is extracted automatically from the card number when a payment is processed. You can see it in the [fraud signals API response](/api/chargebacks#fraud-signals-order-risk-check) in the `order.bin` field, or by looking at your order details — the first 6 digits of the truncated card number (e.g. `460332******1234` has BIN `460332`).

***

# List Blocked BINs

## Endpoint

`GET /api/fraud/blocked-bins`

Returns all blocked BINs for your account, including both merchant-specific and platform-wide blocks.

### Example request

```bash theme={null}
curl -X GET "https://www.niftipay.com/api/fraud/blocked-bins" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

### Example response

```json theme={null}
{
  "ok": true,
  "bins": [
    {
      "id": 5,
      "bin": "443047",
      "reason": "Fraud pattern detected from this card range",
      "scope": "merchant",
      "createdAt": "2026-04-15T12:00:00.000Z"
    },
    {
      "id": 1,
      "bin": "411111",
      "reason": "Known test card BIN",
      "scope": "platform",
      "createdAt": "2026-04-01T00:00:00.000Z"
    }
  ]
}
```

### Response fields

| Field       | Type           | Description                                                                            |
| ----------- | -------------- | -------------------------------------------------------------------------------------- |
| `id`        | number         | Blocked BIN ID (used for unblocking).                                                  |
| `bin`       | string         | The 6-digit BIN.                                                                       |
| `reason`    | string \| null | Reason for blocking.                                                                   |
| `scope`     | string         | `"merchant"` (you blocked it) or `"platform"` (blocked by Niftipay for all merchants). |
| `createdAt` | string         | ISO 8601 timestamp.                                                                    |

> **Note:** Platform-wide BIN blocks are managed by Niftipay and cannot be removed by merchants. Only merchant-specific BINs can be unblocked.

***

# Unblock a BIN

## Endpoint

`DELETE /api/fraud/blocked-bins/:id`

Removes a BIN from your blocklist. Only merchant-specific BINs can be removed — platform-wide blocks return a 403 error.

### Example request

```bash theme={null}
curl -X DELETE "https://www.niftipay.com/api/fraud/blocked-bins/5" \
  -H "x-api-key: YOUR_API_KEY"
```

### Example response

```json theme={null}
{
  "ok": true,
  "deleted": {
    "id": 5,
    "bin": "443047"
  }
}
```

### Error: platform block (403)

```json theme={null}
{
  "ok": false,
  "error": "Cannot delete a platform-wide BIN block"
}
```

***

# Unusual Amount Detection

Niftipay automatically monitors your order amounts to detect anomalies. This is a **passive detection** — it does not block orders, but flags them in the [fraud signals API](/api/chargebacks#fraud-signals-order-risk-check) and in fraud alert emails.

### How it works

1. When an order is **completed**, Niftipay computes the [z-score](https://en.wikipedia.org/wiki/Standard_score) of the order amount compared to your historical completed orders in the same currency.
2. The z-score measures how many standard deviations the amount is from your average.
3. Anomaly detection only activates after you have **at least 10 completed orders** in the given currency, to avoid false positives on new accounts.

### Thresholds

| Z-score   | Severity   | Meaning                                                            |
| --------- | ---------- | ------------------------------------------------------------------ |
| \< 3.0    | —          | Normal range. No flag.                                             |
| 3.0 - 4.9 | `warning`  | Unusually high amount. Included in fraud signals and alert emails. |
| >= 5.0    | `critical` | Extremely high amount. Elevated severity in fraud signals.         |

### Example

If your average order is **85.00 EUR** with a standard deviation of **40.00 EUR**, an order of **325.00 EUR** would have a z-score of (325 - 85) / 40 = **6.0**, triggering a critical amount anomaly signal.

An order of **210.00 EUR** would have a z-score of (210 - 85) / 40 = **3.1**, triggering a warning signal.

### What to do

When you see an amount anomaly signal:

* **Review the order** — is the amount consistent with what you sell?
* Check the customer's email and IP for other fraud signals
* If the order looks legitimate, no action is needed

***

# Velocity Auto-Blocking

When the same **IP address** or **email address** is involved in **2 or more** amount-anomaly orders within a **24-hour window**, Niftipay automatically blocks that identifier.

### How it works

1. An order completes and is flagged with an amount anomaly (z-score >= 3.0)
2. Niftipay checks if the same IP or email had other amount-anomaly orders in the last 24 hours
3. If 2 or more anomaly orders are found, the IP or email is **automatically blocked**
4. A chargeback case is created with kind `ip_amount_anomaly` or `email_amount_anomaly`
5. Future orders from the blocked IP or email are rejected with a block page

You can unblock these via the blocked IPs/emails endpoints above, or via the [chargeback cases API](/api/chargebacks#unblock-a-case).

***

# Fraud Alerts

## Endpoint

`GET /api/fraud/alerts`

> Requires API key or session authentication.

Returns a paginated list of orders that have at least one fraud indicator. This is the data source for the **Alerts** page in the dashboard, but you can also use it in your own integration to monitor suspicious orders.

Each alert includes the current block status for the order's IP and email, so you can decide whether to block them.

### What triggers an alert

An order appears in the alerts list if any of the following are true:

* **Amount anomaly** — the order's z-score is 3.0 or higher
* **Disposable email** — the email uses a known temporary domain
* **IP blocked** — the customer's IP is currently blocked
* **Email blocked** — the customer's email is currently blocked

### Query parameters

| Name       | Type   | Default | Notes                              |
| ---------- | ------ | ------- | ---------------------------------- |
| `page`     | number | `1`     | Page number (min 1).               |
| `pageSize` | number | `25`    | Results per page (min 1, max 200). |

### Example request

```bash theme={null}
curl -X GET "https://www.niftipay.com/api/fraud/alerts?page=1&pageSize=25" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

### Example response

```json theme={null}
{
  "ok": true,
  "alerts": [
    {
      "id": "ord_abc123",
      "orderKey": 10085,
      "merchantReference": "WC-789",
      "amountCents": 2500000,
      "currency": "EUR",
      "orderStatus": "completed",
      "email": "buyer@example.com",
      "ip": "203.0.113.42",
      "truncatedPan": "460332******1234",
      "bin": "460332",
      "cardholderName": "John Doe",
      "isDisposableEmail": false,
      "amountAnomalyZScore": 6.2,
      "createdAt": "2026-04-15T10:30:00.000Z",
      "completedAt": "2026-04-15T10:32:00.000Z",
      "severity": "critical",
      "reasons": ["critical_amount"],
      "ipBlock": null,
      "emailBlock": null
    },
    {
      "id": "ord_def456",
      "orderKey": 10086,
      "merchantReference": "WC-790",
      "amountCents": 5000,
      "currency": "EUR",
      "orderStatus": "completed",
      "email": "user@mailinator.com",
      "ip": "198.51.100.10",
      "truncatedPan": "411111******1111",
      "bin": "411111",
      "cardholderName": "Jane Smith",
      "isDisposableEmail": true,
      "amountAnomalyZScore": null,
      "createdAt": "2026-04-15T11:00:00.000Z",
      "completedAt": "2026-04-15T11:02:00.000Z",
      "severity": "medium",
      "reasons": ["disposable_email"],
      "ipBlock": {
        "caseId": 15,
        "caseNumber": "CB-00015",
        "status": "blocked"
      },
      "emailBlock": null
    }
  ],
  "pageInfo": {
    "page": 1,
    "pageSize": 25,
    "total": 2,
    "totalPages": 1,
    "hasMore": false
  }
}
```

### Response fields (alert object)

| Field                 | Type           | Description                                                          |
| --------------------- | -------------- | -------------------------------------------------------------------- |
| `id`                  | string         | Fiat order ID.                                                       |
| `orderKey`            | number         | Numeric order key.                                                   |
| `merchantReference`   | string \| null | Your merchant reference.                                             |
| `amountCents`         | number         | Order amount in minor units.                                         |
| `currency`            | string         | Currency code (e.g. `"EUR"`).                                        |
| `orderStatus`         | string         | Order status (e.g. `"completed"`).                                   |
| `email`               | string \| null | Customer email.                                                      |
| `ip`                  | string \| null | Customer IP address.                                                 |
| `truncatedPan`        | string \| null | Masked card number.                                                  |
| `bin`                 | string \| null | Card BIN (first 6 digits).                                           |
| `cardholderName`      | string \| null | Cardholder name.                                                     |
| `isDisposableEmail`   | boolean        | Whether the email is from a disposable domain.                       |
| `amountAnomalyZScore` | number \| null | Z-score of the order amount vs your average. `null` if not computed. |
| `createdAt`           | string         | ISO 8601 timestamp.                                                  |
| `completedAt`         | string \| null | ISO 8601 timestamp when payment completed.                           |
| `severity`            | string         | `"critical"`, `"high"`, or `"medium"`.                               |
| `reasons`             | string\[]      | Why this order was flagged (see below).                              |
| `ipBlock`             | object \| null | Current IP block status (see below). `null` if not blocked.          |
| `emailBlock`          | object \| null | Current email block status (see below). `null` if not blocked.       |

### `reasons` values

| Value              | Meaning                              |
| ------------------ | ------------------------------------ |
| `critical_amount`  | Amount anomaly with z-score >= 5.0.  |
| `high_amount`      | Amount anomaly with z-score >= 3.0.  |
| `disposable_email` | Disposable/temporary email detected. |
| `ip_blocked`       | The IP is currently blocked.         |
| `email_blocked`    | The email is currently blocked.      |

### `ipBlock` / `emailBlock` object

Present when the IP or email is currently blocked. Use the `caseId` to unblock via `DELETE /api/fraud/blocked-ips/:id` or `DELETE /api/fraud/blocked-emails/:id`.

| Field        | Type   | Description                                   |
| ------------ | ------ | --------------------------------------------- |
| `caseId`     | number | Case ID (use this to unblock).                |
| `caseNumber` | string | Human-readable case number (e.g. `CB-00015`). |
| `status`     | string | Always `"blocked"` in this response.          |

### Alert status

Each alert has a `status` field that you can update:

| Status      | Meaning                                           |
| ----------- | ------------------------------------------------- |
| `new`       | Not yet reviewed. Shown in red in the dashboard.  |
| `reviewed`  | You've looked at it. Shown in blue.               |
| `dismissed` | You've decided it's not a concern. Shown in gray. |

***

## Update Alert Status

### Endpoint

`PATCH /api/fraud/alerts/:id`

> Requires API key or session authentication.

Update the status of a fraud alert.

### Path parameters

| Name | Type   | Notes                |
| ---- | ------ | -------------------- |
| `id` | string | The alert ID (UUID). |

### Request body

```json theme={null}
{
  "status": "reviewed",
  "note": "Checked with customer, looks legitimate"
}
```

| Field    | Type   | Required | Notes                                         |
| -------- | ------ | -------- | --------------------------------------------- |
| `status` | string | Yes      | One of: `"new"`, `"reviewed"`, `"dismissed"`. |
| `note`   | string | No       | Optional review note (max 500 characters).    |

### Example request

```bash theme={null}
curl -X PATCH "https://www.niftipay.com/api/fraud/alerts/a1b2c3d4-5678-90ab-cdef-1234567890ab" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "reviewed", "note": "Verified with customer"}'
```

### Example response

```json theme={null}
{
  "ok": true,
  "alert": {
    "id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
    "status": "reviewed",
    "reviewedAt": "2026-04-15T14:00:00.000Z",
    "reviewNote": "Verified with customer"
  }
}
```

### Error: not found (404)

```json theme={null}
{
  "ok": false,
  "error": "Alert not found"
}
```

***

### Taking action on alerts

From the dashboard **Alerts** page, you can review, dismiss, block, or unblock directly. Via the API:

**Block an IP from an alert:**

```bash theme={null}
curl -X POST "https://www.niftipay.com/api/fraud/blocked-ips" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"ipAddress": "203.0.113.42", "reason": "Flagged in alert — order #10085"}'
```

**Block an email from an alert:**

```bash theme={null}
curl -X POST "https://www.niftipay.com/api/fraud/blocked-emails" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "buyer@example.com", "reason": "Flagged in alert — order #10085"}'
```

**Unblock an IP:**

```bash theme={null}
curl -X DELETE "https://www.niftipay.com/api/fraud/blocked-ips/15?reason=False+positive" \
  -H "x-api-key: YOUR_API_KEY"
```

***

# Updated Fraud Signals

The [fraud signals API](/api/chargebacks#fraud-signals-order-risk-check) now returns additional signal types for the new detection features.

### New signal types

| Type                    | Description                                                    | Extra fields                                        |
| ----------------------- | -------------------------------------------------------------- | --------------------------------------------------- |
| `bin_blocked`           | Card BIN is on the blocklist.                                  | `bin`, `reason`                                     |
| `amount_anomaly`        | Order amount is unusually high compared to merchant's average. | `zScore`, `severity`, `merchantMean`, `amountCents` |
| `ip_amount_velocity`    | IP auto-blocked due to repeated high-amount orders.            | `anomalyCount`, `caseNumber`                        |
| `email_amount_velocity` | Email auto-blocked due to repeated high-amount orders.         | `anomalyCount`, `caseNumber`                        |

### New fields in the `order` object

| Field | Type           | Description                                                                              |
| ----- | -------------- | ---------------------------------------------------------------------------------------- |
| `bin` | string \| null | Card BIN (first 6 digits). Extracted automatically from the card number at payment time. |

### Updated severity levels

| Level      | Triggers                                                                                            |
| ---------- | --------------------------------------------------------------------------------------------------- |
| `critical` | IP/email blocked, BIN blocked, velocity auto-block, or IP risk score >= 75.                         |
| `high`     | Card/email/IP matched your chargebacks, critical amount anomaly (z >= 5.0), or IP risk score >= 50. |
| `medium`   | Platform-wide matches, disposable email, or warning amount anomaly (z >= 3.0).                      |
| `low`      | No fraud signals detected.                                                                          |

### Example fraud signal: amount anomaly

```json theme={null}
{
  "type": "amount_anomaly",
  "label": "Order amount 250.00 EUR is unusually high (avg: 45.00 EUR, z-score: 5.1)",
  "zScore": 5.1,
  "severity": "critical",
  "merchantMean": 4500,
  "amountCents": 25000
}
```

### Example fraud signal: BIN blocked

```json theme={null}
{
  "type": "bin_blocked",
  "label": "Card BIN 443047 is blocked",
  "bin": "443047",
  "reason": "Fraud pattern detected from this card range"
}
```

***

# Error Responses

All endpoints return errors in this format:

### Invalid request (400)

```json theme={null}
{
  "ok": false,
  "error": "A valid ipAddress is required"
}
```

### Missing authentication (401)

```json theme={null}
{
  "ok": false,
  "error": "Unauthorized"
}
```

### Cannot delete platform block (403)

```json theme={null}
{
  "ok": false,
  "error": "Cannot delete a platform-wide BIN block"
}
```

### Not found (404)

```json theme={null}
{
  "ok": false,
  "error": "Blocked IP not found"
}
```

### Already blocked (409)

```json theme={null}
{
  "ok": false,
  "error": "IP 203.0.113.42 is already blocked (case CB-00015)"
}
```
