Fraud warnings

Read issuer alerts, receive lifecycle webhooks and test your integration safely.

Fraud warnings

An early fraud warning is an issuer report that a card payment may be fraudulent. It is not a formal dispute and does not itself refund a payment. A full refund can reduce the risk of a later chargeback, but prevention is not guaranteed.

This reference describes the Merchant API and Merchant webhooks. For dashboard guidance, see Fraud warnings in the Help Center.

Authentication and environments

Base URL: https://api.southbill.com/v1.

Send a secret Southbill API key in Authorization: Bearer YOUR_SECRET_KEY. The key must include fraud_warnings:read. Never expose secret keys in browser code or mobile apps. Calls return only warnings belonging to the key's merchant and environment: test keys read test warnings; live keys read live warnings. Account restrictions and normal API rate limits apply.

See API keys & authentication. These routes do not accept a Stripe key or an App API OAuth token.

List warnings

GET /v1/fraud_warnings

curl 'https://api.southbill.com/v1/fraud_warnings?limit=25&status=open&actionable=true' \
  -H 'Authorization: Bearer YOUR_SECRET_KEY'
Parameter Meaning
limit Page size. Use an integer from 1 to 100; default 25.
starting_after Southbill warning UUID used as the cursor. Use an ID returned by this API, not an issuer warning ID or charge ID.
status Optional: open, refunded or disputed.
actionable Optional: literal true or false.
created_gte Inclusive lower bound for warning creation, in Unix seconds.
created_lte Inclusive upper bound for warning creation, in Unix seconds.

The response is { "object": "list", "has_more": false, "data": [...] }. Results are ordered newest first. When has_more is true, pass the last returned warning's id as starting_after, retaining your filters.

Pagination is keyset-based on creation time and ID, so no warning is skipped at a page boundary. An unknown or foreign starting_after returns 400.

Retrieve a warning

GET /v1/fraud_warnings/{id}

curl 'https://api.southbill.com/v1/fraud_warnings/WARNING_UUID' \
  -H 'Authorization: Bearer YOUR_SECRET_KEY'

Replace WARNING_UUID with the id returned by the list or webhook. The response is the warning object directly, not a list wrapper. An unknown ID, an ID belonging to another merchant, or an ID from the other environment returns 404 with error.code: "resource_missing".

Warning object

The following is an illustrative test object; IDs and timestamps are examples.

{
  "id": "7b69f46b-46ba-4c76-8ed8-b76204f1a837",
  "object": "fraud_warning",
  "livemode": false,
  "charge_id": "ch_test_example",
  "payment_intent_id": null,
  "fraud_type": "unauthorized_use_of_card",
  "amount": 2500,
  "currency": "usd",
  "status": "open",
  "actionable": true,
  "created": 1791878400,
  "updated": 1791878400,
  "resolved": null
}
Field Meaning
id Southbill warning UUID. Stable resource identifier, distinct from the webhook event ID.
object Always fraud_warning.
livemode true for live warnings, false for test warnings.
charge_id Linked charge ID, or null if unavailable.
payment_intent_id Linked PaymentIntent ID, or null if unavailable.
fraud_type Issuer-reported fraud category, or null if unavailable.
amount Original charge amount in currency minor units, or null if unavailable. It is not a fee, outstanding debt or remaining refundable amount.
currency Lowercase currency code, or null if unavailable. Use the currency's minor-unit convention.
status open, refunded or disputed.
actionable Issuer actionability flag. Evaluate it together with status.
created Warning creation time in Unix seconds.
updated Stored warning update time in Unix seconds. Not a guarantee that an update webhook was emitted.
resolved Recorded resolution time in Unix seconds, or null while unresolved.

For USD, 2500 means USD 25.00. See Currencies & amount format.

Reported fraud categories are card_never_received, fraudulent_card_application, made_with_counterfeit_card, made_with_lost_card, made_with_stolen_card, misc, and unauthorized_use_of_card. Handle unknown future values gracefully.

Status and safe handling

  • open with actionable: true: review the current payment promptly. It may still be eligible for a refund.
  • open with actionable: false: no currently actionable warning. This is not proof that the payment is legitimate.
  • refunded: a full charge refund has been recorded. A partial refund does not by itself set this status.
  • disputed: a dispute has been recorded; it takes precedence over refund status. Follow the dispute workflow and its deadline.

These are read-only endpoints. There is no update, delete or refund operation on a fraud-warning resource. Before taking a financial action, retrieve the warning and check the current payment, refund and dispute state. Do not automatically refund based solely on an old webhook snapshot. Use the separate Refunds API with its own permissions and idempotency requirements if your integration initiates refunds.

Southbill fees properly incurred remain non-refundable under Terms §11.6. A warning itself is not a chargeback fee; if a dispute follows, normal dispute rules apply. Do not infer or charge fees from the warning's amount.

Webhook events

Configure a Merchant webhook endpoint to receive:

Event When it is emitted
fraud_warning.created A warning is first stored for the merchant. It may already be refunded, disputed or non-actionable.
fraud_warning.updated The stored status or actionable value changes. A timestamp-only or other field change does not trigger this event.

The resource snapshot is under data.object. Merchant events use this envelope:

{
  "id": "evt_example",
  "object": "event",
  "type": "fraud_warning.created",
  "livemode": false,
  "created": 1791878400,
  "data": {
    "object": {
      "id": "7b69f46b-46ba-4c76-8ed8-b76204f1a837",
      "object": "fraud_warning",
      "livemode": false,
      "charge_id": "ch_test_example",
      "payment_intent_id": null,
      "fraud_type": "unauthorized_use_of_card",
      "amount": 2500,
      "currency": "usd",
      "status": "open",
      "actionable": true,
      "created": 1791878400,
      "updated": 1791878400,
      "resolved": null
    }
  }
}
  1. Enable the endpoint in the correct mode (test or live) and select both event types, or *.
  2. Verify Southbill-Signature on the raw request body before trusting the payload. It contains t=<Unix seconds>,v1=<HMAC-SHA256> over t.rawBody. During secret rotation there can be multiple v1 values; accept a valid matching signature and enforce a timestamp tolerance, such as 300 seconds.
  3. Persist the event ID and queue work durably, then return a 2xx response promptly. The delivery timeout is 15 seconds.
  4. Deduplicate by event.id, not warning ID: the same warning can legitimately produce multiple lifecycle events. Do not assume delivery order; retrieve current state before irreversible actions.

Failed deliveries are retried with backoff, up to seven attempts. Unchanged issuer replays normally do not create a lifecycle event, but this is not an exactly-once delivery guarantee. Build duplicate-safe handlers and reconcile periodically through the API.

See Webhook endpoints, Verify signatures, and Events & replay.

Test a warning

POST /v1/test_helpers/fraud_warnings requires a test secret key with fraud_warnings:read.

curl -X POST 'https://api.southbill.com/v1/test_helpers/fraud_warnings' \
  -H 'Authorization: Bearer YOUR_TEST_SECRET_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"amount":2500,"currency":"usd","fraud_type":"unauthorized_use_of_card"}'

Returns 201 with a synthetic warning (status: "open", actionable: true, livemode: false) and emits fraud_warning.created for matching test endpoints.

Body field Constraints / default
amount Optional integer, 1–100,000,000 minor units. Default 2500.
currency Optional three-letter code. Default usd.
fraud_type Optional category from the list above. Default unauthorized_use_of_card.
charge_id Optional test label; a synthetic charge ID is generated if omitted. Supplying an ID does not validate ownership or create a real charge.

Test warnings do not appear in the merchant's live Fraud warnings dashboard and do not represent real money. Every helper call creates a new warning; do not assume repeated calls are idempotent. The helper has no status-update simulation operation: it tests creation, retrieval and webhook delivery, not a real refund or a complete issuer lifecycle.

Errors

HTTP status Meaning
400 Invalid filter/body, or livemode_forbidden when a live key calls the test helper.
401 Missing or invalid secret API key.
403 Missing scope or an account restriction.
404 resource_missing: warning unavailable to this merchant and environment.
405 Unsupported method.
429 API rate limit exceeded.
500 API processing failure.
503 sandbox_unavailable: test mode is unavailable in the current environment.

See Error reference. Log event/resource IDs for troubleshooting, not secret keys or sensitive payment information.

Developer-app webhooks

Installed developer apps can receive fraud_warning.created and fraud_warning.updated only when the merchant has granted fraud_warnings:read and the app is subscribed to the events. App webhooks use the App webhook envelope, not the Merchant envelope shown above. This does not make the Merchant API routes accessible with an App OAuth token. See App webhook event catalog and App signatures & retries.