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
openwithactionable: true: review the current payment promptly. It may still be eligible for a refund.openwithactionable: 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
}
}
}
- Enable the endpoint in the correct mode (
testorlive) and select both event types, or*. - Verify
Southbill-Signatureon the raw request body before trusting the payload. It containst=<Unix seconds>,v1=<HMAC-SHA256>overt.rawBody. During secret rotation there can be multiplev1values; accept a valid matching signature and enforce a timestamp tolerance, such as 300 seconds. - Persist the event ID and queue work durably, then return a
2xxresponse promptly. The delivery timeout is 15 seconds. - 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.