Only this pageAll pages
Powered by GitBook
1 of 43

ChargebackStop | DOCS

Loading...

Platform

Loading...

Loading...

Digital Receipts

Loading...

Loading...

Loading...

Systematic Dispute Deflection

Loading...

Loading...

Loading...

Chargeback Alerts

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Developer

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Integration

Loading...

Loading...

Loading...

Loading...

Merchants

Manage merchants under your partner account.

This endpoint set is partner-level only. Organisation API keys cannot access these endpoints.

Base URL: https://api.chargebackstop.com/v1/merchants/ Authentication: Bearer token via API key.

Required abilities:

  • merchants:read for GET endpoints

  • merchants:write for POST, PATCH, and DELETE endpoints

Access scope model:

  • Admin partner-group keys can access merchants across all organisations belonging to their partner.

  • Non-admin partner-group keys can access merchants only in organisations explicitly assigned to their group.

  • Organisation-level keys receive 401 Unauthorised on all endpoints in this API.


GET /v1/merchants - List merchants

Returns merchants accessible to the authenticated partner-group API key.

API level: Partner-level only Authentication: merchants:read

Query parameters

Parameter
Type
Description

organisation_id

string

Filter by organisation ID

type

string

Filter by merchant type

name

string

Case-insensitive partial match on merchant name

external_id

string

Filter by exact external merchant ID

sort

string

Sort field: name, type, created_at, updated_at; prefix with - for descending

limit

integer

Number of results per page

offset

integer

Number of results to skip

When sort is omitted, results are ordered by created_at descending.

Example request

Example response


POST /v1/merchants - Create merchant

Create a new merchant for an accessible organisation.

API level: Partner-level only Authentication: merchants:write

Request body

Field
Type
Required
Validation
Description

organisation_id

string

Yes

Must be accessible by API key

Organisation that owns the merchant

name

string

Yes

Min length 1

Merchant display name

type

string

Yes

Must be a supported merchant type

Merchant type

external_id

string

No

Max length 250

Optional external merchant ID

default_representment_service_type

string

No

PHYSICAL_GOODS, ONLINE_SERVICES, or OFFLINE_SERVICES

Default representment service type. If you do not use ChargebackStop representment/disputes workflows, omit this field.

If you do not use ChargebackStop representment/disputes workflows, skip default_representment_service_type.

Example request

Example response


GET /v1/merchants/{merchant_id} - Get merchant by ID

Retrieve one accessible merchant by ID.

API level: Partner-level only Authentication: merchants:read

URL parameters

Parameter
Type
Description

merchant_id

string

Merchant ID

Example request

Example response


PATCH /v1/merchants/{merchant_id} - Update merchant

Update one accessible merchant.

API level: Partner-level only Authentication: merchants:write

URL parameters

Parameter
Type
Description

merchant_id

string

Merchant ID to update

Request body

At least one field should be provided.

Field
Type
Required
Validation
Description

name

string

No

Min length 1

Updated merchant name

type

string

No

Must be a supported merchant type

Updated merchant type

external_id

string or null

No

Optional

Updated external ID (null clears value)

default_representment_service_type

string or null

No

PHYSICAL_GOODS, ONLINE_SERVICES, OFFLINE_SERVICES, or null

Updated default representment service type. If you do not use ChargebackStop representment/disputes workflows, omit this field.

  • Merchant type changes are blocked when related integrations, enrolments, or data providers exist.

  • Other fields can still be updated when type changes are blocked.

  • If you do not use ChargebackStop representment/disputes workflows, skip default_representment_service_type.

Example request

Example response


DELETE /v1/merchants/{merchant_id} - Delete merchant

Delete one accessible merchant.

API level: Partner-level only Authentication: merchants:write

URL parameters

Parameter
Type
Description

merchant_id

string

Merchant ID to delete

Deletion is blocked when the merchant has related enrolments or alerts.

Example request

Example response

204 No Content


Common error responses

401 Unauthorised

Returned for invalid or expired API keys, and for organisation-level keys calling this partner-only API.

403 Forbidden (missing ability)

Returned when the API key is valid but missing required ability (merchants:read or merchants:write).

404 Not found

Returned when the merchant is not found.

422 Unprocessable Entity (merchant type change restricted)

422 Unprocessable Entity (merchant deletion restricted)

Other business validation codes you may receive:

Code
Meaning

INVALID_MERCHANT_TYPE

type is not a valid merchant type

INVALID_REPRESENTMENT_SERVICE_TYPE

default_representment_service_type is not valid

MERCHANT_TYPE_CHANGE_RESTRICTED

Requested type change is blocked by related records

MERCHANT_DELETION_RESTRICTED

Merchant cannot be deleted due to related records

curl -X GET "https://api.chargebackstop.com/v1/merchants/?limit=20&offset=0&sort=-created_at" \
  -H "Authorization: Bearer <api_key>"
{
  "items": [
    {
      "id": "mrch_abc123",
      "organisation_id": "org_xyz456",
      "name": "Acme Stripe EU",
      "type": "STRIPE",
      "external_id": "acct_eu_001",
      "default_representment_service_type": "PHYSICAL_GOODS",
      "created_at": "2026-02-10T09:30:00Z",
      "updated_at": "2026-02-10T09:30:00Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/merchants/mrch_abc123"
        }
      ]
    },
    {
      "id": "mrch_def789",
      "organisation_id": "org_xyz456",
      "name": "Acme Adyen UK",
      "type": "ADYEN",
      "external_id": null,
      "default_representment_service_type": null,
      "created_at": "2026-02-08T15:12:44Z",
      "updated_at": "2026-02-08T15:12:44Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/merchants/mrch_def789"
        }
      ]
    }
  ],
  "count": 2
}
curl -X POST "https://api.chargebackstop.com/v1/merchants/" \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "organisation_id": "org_xyz456",
    "name": "Acme Stripe US",
    "type": "STRIPE",
    "external_id": "acct_us_002",
    "default_representment_service_type": "PHYSICAL_GOODS"
  }'
{
  "id": "mrch_new123",
  "organisation_id": "org_xyz456",
  "name": "Acme Stripe US",
  "type": "STRIPE",
  "external_id": "acct_us_002",
  "default_representment_service_type": "PHYSICAL_GOODS",
  "created_at": "2026-02-16T12:00:00Z",
  "updated_at": "2026-02-16T12:00:00Z",
  "links": [
    {
      "rel": "self",
      "uri": "/v1/merchants/mrch_new123"
    }
  ]
}
curl -X GET "https://api.chargebackstop.com/v1/merchants/mrch_abc123" \
  -H "Authorization: Bearer <api_key>"
{
  "id": "mrch_abc123",
  "organisation_id": "org_xyz456",
  "name": "Acme Stripe EU",
  "type": "STRIPE",
  "external_id": "acct_eu_001",
  "default_representment_service_type": "PHYSICAL_GOODS",
  "created_at": "2026-02-10T09:30:00Z",
  "updated_at": "2026-02-16T09:05:00Z",
  "links": [
    {
      "rel": "self",
      "uri": "/v1/merchants/mrch_abc123"
    }
  ]
}
curl -X PATCH "https://api.chargebackstop.com/v1/merchants/mrch_abc123" \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Stripe Europe",
    "external_id": "acct_eu_010",
    "default_representment_service_type": "ONLINE_SERVICES"
  }'
{
  "id": "mrch_abc123",
  "organisation_id": "org_xyz456",
  "name": "Acme Stripe Europe",
  "type": "STRIPE",
  "external_id": "acct_eu_010",
  "default_representment_service_type": "ONLINE_SERVICES",
  "created_at": "2026-02-10T09:30:00Z",
  "updated_at": "2026-02-16T12:10:00Z",
  "links": [
    {
      "rel": "self",
      "uri": "/v1/merchants/mrch_abc123"
    }
  ]
}
curl -X DELETE "https://api.chargebackstop.com/v1/merchants/mrch_abc123" \
  -H "Authorization: Bearer <api_key>"
{
  "errors": [
    {
      "code": "UNAUTHORISED",
      "message": "Unauthorised"
    }
  ]
}
{
  "errors": [
    {
      "code": "FORBIDDEN",
      "message": "Forbidden"
    }
  ]
}
{
  "errors": [
    {
      "code": "NOT_FOUND",
      "message": "Not found"
    }
  ]
}
{
  "errors": [
    {
      "code": "MERCHANT_TYPE_CHANGE_RESTRICTED",
      "message": "Cannot change merchant type when integrations are associated with this merchant."
    }
  ]
}
{
  "errors": [
    {
      "code": "MERCHANT_DELETION_RESTRICTED",
      "message": "Merchant cannot be deleted because it has active enrollments. Please contact support if you need to delete this merchant."
    }
  ]
}

Use cases

B2C subscription products

  • Display subscription billing cycles to cardholders

  • Embed deep-links for managing subscriptions or requesting refunds

Merchant of Record PSPs

  • Surface the details of the sub-merchant that delivered the goods or services

eCommerce brands

  • Show itemised breakdowns of items ordered, including delivery and tracking status

Integrating

Systematic Dispute Deflection builds on top of the same data set used for Digital Receipts, in addition to the qualifying data.

  • Customer's IP address or device fingerprint

  • Customer's email address

The qualifying data identifiers listed above are mandatory for deflection. If you're setting up Digital Receipts alongside this product, pay close attention to the required fields for Consumer Clarity, First Party Trust, Order Insights, and Compelling Evidence 3.0 during your integration.

Both products share the same underlying data pipeline. Getting your Digital Receipts integration right means Systematic Dispute Deflection works out of the box.

Alert Providers

Chargeback alerts are powered by Visa and Mastercard. ChargebackStop is an authorized, direct reseller of alert data from both card networks. We handle onboarding, management, and automation so you get full value from alerts without extra overhead.

Ethoca Alerts (Mastercard) covers roughly 95% of Mastercard-related chargebacks and about 40% of Visa-related chargebacks. Learn more here.

Verifi RDR (Visa) covers roughly 95% of Visa-related chargebacks. Learn more here.

When both programs are enabled together, merchants typically see up to 95%* dispute prevention coverage across all Visa and Mastercard transactions.

A note on coverage estimates: The 95% figure reflects what we typically see across our customer portfolio. Your actual coverage depends on issuer spread and cardholder regions. Contact our sales or support team with details about your setup and volume, we can give you a specific estimate before you onboard.

What about Amex & Discover?

Both alert providers offer some coverage for Amex and Discover disputes, but availability depends on your payment processor setup. Reach out to sales or support to confirm what's possible for your configuration.

Introduction

Digital Receipts let you send additional order information to cardholders and their banks, including subscription details, itemised breakdowns, in-flight refunds, and more. When implemented, they reduce cardholder confusion, help banks better understand charges before raising a dispute, and ultimately lower your chargeback rate.

1

Cardholder views a transaction

A cardholder opens a transaction in their banking app.

2

Intergrating

You may need to perform additional integration work to support Digital Receipts. Depending on your payment processor or CRM, we may need extra information to return data to cardholders and their banks.

During your initial conversations with our team, we'll evaluate which of three paths applies to your setup:

  1. No additional work needed: We can gather enough data from your payment processor, CRM, or eCommerce platform. No work required from your technical team.

  2. Partial order enrichment: We can pull most of the data from your existing integrations, but some additional enrichment is needed from your side.

Introduction

Chargeback prevention alerts warn you of a dispute before it becomes an official chargeback with your payment service provider. When you receive an alert, you can refund the transaction and avoid the chargeback entirely.

1

A cardholder contacts their bank to dispute a transaction they made with your business.

2

As the issuer begins filing the dispute, they check whether you're enrolled to receive alerts (this depends on the card network and issuer).

3

Enrolments

An enrollment registers your merchant setup with ChargebackStop and the card networks (Visa and Mastercard). You'll likely have more than one enrollment, each merchant account and product requires its own.

Our onboarding and support teams handle all enrollment work and communicate with the card networks on your behalf. No action needed from you.

View your enrollments in your dashboard under Settings > Enrollments.

Ethoca enrollment is descriptor-based. If your descriptor is too generic or already enrolled by another merchant globally across Ethoca's network, the enrollment may need attention. When this happens, our support team will reach out to discuss alternatives — for example, using a more specific descriptor or a different match type. This typically takes 1–2 business days to resolve, after which we resubmit the enrollment.

ChargebackStop manages your enrollments, but if you need to pause, extend, or reduce coverage, contact our support team. They'll gather the required information and make the changes. Depending on what you're changing, there may be a delay while we coordinate with the card networks.

Resolution Rules

Resolution rules tell the system how to handle incoming alerts, whether to refund, dismiss, or escalate for manual review. You can filter by transaction amount, date, reason code, reason category, and more.

Go to Settings > Resolution Rules to create, edit, or delete rules.

Each resolution rule applies to exactly one enrollment. If you have multiple enrollments or merchant accounts, you'll need separate rules for each. This gives you precise control over behavior per merchant account.

Changes to a resolution rule apply only to alerts received after you save. Already-received alerts aren't affected. If you have unresolved alerts that should match a new rule, contact support, we can re-queue them for processing.

If an incoming alert doesn't match any rule, it goes to manual review in the Action Required tab. You'll have up to 48 hours to make a refund decision (timeframe varies by network). After that, the alert is automatically declined.

Alert received from the card networks

We receive the alert in real time and locate the order in your payment processor or connected gateway.

4

Dispute deflected based on setup

Based on rules you configure during onboarding or later in your dashboard, the system takes one of these actions:

  • Refund and resolve: We refund the transaction and mark the alert as resolved.

  • Decline the alert: The alert is declined and the dispute proceeds normally.

  • Manual decision: The alert appears in your dashboard and triggers an email, giving you 24–48 hours to decide whether to refund.

How does it works?

Cardholder starts chargeback

Card issuer checks runs check

If you're already enrolled with another provider and want to move to ChargebackStop, you can transfer your enrollments to avoid any gap in coverage.

Transfers require:

  • Approval from your current provider

  • Authorization from ChargebackStop to receive the transfer

  • All fees paid and notice given to your current provider

Once your provider initiates the transfer, we work directly with the card networks to ensure coverage continues without interruption.

To start a transfer, contact our sales or support team. They'll provide an email template you can send to your current provider and walk you through the process.

Enrolling for the first time

Enrollment timelines vary by product and provider. When we begin an enrollment, we'll tell you the expected timeframe, typically 2–10 working days to be fully enrolled across all programs. See individual product pages on this site for specifics.

Ethoca descriptor conflicts

Changing enrollment settings

Transferring enrollments from another provider

Creating a new rule

Modifying existing rules

Deleting or disabling rules

Deleting or disabling a rule stops it from applying to new alerts immediately. It won't change your enrollment settings or affect previously resolved or declined alerts.

Real-time lookup

The app performs a real-time lookup to check whether additional order data is available.

3

Data displayed

If data is available, it's shown directly in the cardholder's banking app alongside the transaction.

1

Cardholder contacts their bank

A cardholder queries a transaction with their bank.

2

Agent opens the dispute portal

The banking agent opens the Mastercard or Visa dispute portal.

3

Real-time lookup

A real-time lookup checks whether additional order data is available.

4

Data displayed

If data is available, the agent sees it in the portal before proceeding with the dispute.

Depending on what's available at the time of the query, the platform automatically shapes the response to provide maximum context. This can include:

  • Subscription details

  • Transaction details

  • Merchant details

  • Refund details

  • Digital deliveries

  • Physical deliveries

  • Hospitality booking details

Digital Receipts are powered by two card network solutions. We harmonise both systems into a single unified interface built to scale and support both programs as they evolve. You never need to integrate directly or manage those connections.

  • Order Insights (Visa)

  • Consumer Clarity (Mastercard)

How it works for cardholders

How it works for banking agents

What data can be returned?

See the full options for enrichment using our

Card network integration

Complete order data: Most of the data we need lives outside of our reach. Your systems need to pass complete order data to ours.

1

We connect to your systems

We integrate with your payment processor, CRM, or eCommerce platform.

2

Order data is imported

As much order data as possible is pulled into our systems automatically.

3

You enrich remaining data

You make an API request to enrich existing order IDs with any data we couldn't pull ourselves.

Both partial enrichment and complete order data flows are powered by our . Depending on your use case, integration method, and available data, we'll tell you exactly what fields you need to provide.

How partial order enrichment works

Authorize.net

You don't need Authorize.net account in order to use ChargebackStop. We work with all processors and an Authorize.net integration is not required.

Integrating Authorize.net

ChargebackStop ↔ Authorize.net integration is straightforward.

  1. Log in to your Authorize.net account.

  2. From the top navigation bar, select "Account".

  3. In "Security Settings" section, select "API Credentials & Keys"

  1. In the page that opens, take note of the "API Login ID" value.

  1. If you already use Authorize.net API in other integrations, you'll need to find your Transaction Key in order to integrate with ChargebackStop. If you are confident that you don't use Authorize.net API anywhere you can select "New Transaction Key" at the bottom page, and click "Submit".

  2. Open , and select "Authorize.net" from the "Add provider" dropdown.

  1. In the pop up window that opens, enter:

    1. Integration name - this is for your reference purposes only

    2. Login ID - API Login ID from step 4.

  1. ChargebackStop will validate your API details, and activate the integration if they are correct.

Introduction

Systematic Dispute Deflection prevents friendly fraud by proving historic cardholder purchase activity with qualifying data. When a deflection is successful, the dispute is blocked by the card networks before it's raised. You retain the funds, prevent fraud claims (TC40s) from being filed, and reduce your dispute rate.

How it works

1

Cardholder attempts a dispute

A cardholder contacts their bank to dispute a transaction.

2

Real-time lookup

The card network performs a real-time lookup against your historical transaction data.

3

Dispute blocked

If the criteria for deflection are met, the dispute is instantly blocked and never reaches you.

A dispute becomes eligible for deflection when the cardholder has completed at least two previous transactions within 120 to 365 days before the disputed charge. These earlier transactions form the purchase history used to verify legitimacy.

For a deflection to succeed, identifiers unique to the cardholder must match across the disputed transaction and the historic purchase history. Qualifying identifiers include:

  • IP address

  • Email address

  • Device fingerprint

  • Billing address

At least two identifiers must match, and one of them must be either an IP address or an email address.

Currently, deflection is attempted for the following dispute conditions:

  • Visa 10.4 — Card Not Present

  • Mastercard 4814 — Card Not Present

Other conditions may become eligible as the card networks expand their programs.

Systematic Dispute Deflection is powered by two card network solutions. We harmonise both systems into a single unified interface built to scale and support both programs as they evolve. You never need to integrate directly or manage those connections.

  • Compelling Evidence 3.0 (Visa)

  • First Party Trust (Mastercard)

VAMP Ratio Reduction

The is Visa's unified framework for monitoring fraud and dispute levels across merchants. If your VAMP ratio exceeds Visa's thresholds, you risk fines, restrictions, or removal from the network.

is the only tool available that can prevent first-party misuse disputes and remove the associated fraud notices (TC40s) from your VAMP ratio. Chargeback alerts and other prevention tools resolve disputes reactively, but the TC40 has already been filed and still counts against you. Systematic Dispute Deflection blocks the dispute before it's created, and the TC40 is excluded from your VAMP calculation entirely.

Visa introduced VAMP in 2024/25 to replace its previous fragmented monitoring programs with a single framework. It monitors your fraud and dispute activity relative to your transaction volume. If your ratio crosses Visa's thresholds, your acquirer is notified and you may face escalating consequences.

Visa updated the VAMP formula to include all disputes, both fraudulent and non-fraud, rather than fraud-only. This makes first-party misuse (friendly fraud, subscription confusion, unrecognised charges) significantly more important to your ratio than before, and harder to address without the right tooling.

When a cardholder attempts to dispute a transaction, our system checks their purchase history against qualifying identifiers you've provided through Digital Receipts, IP address, email, device fingerprint, and billing address. If the evidence proves prior legitimate activity, the dispute is blocked at the network level.

Integrating with ChargebackStop

ChargebackStop for Partners has extensive API and webhook capabilities.

To understand how our API and platform work, it helps to learn these terms and their relationships.

Your partner account.

  • In production, you’ll typically only have one.

An organisation within your partner account.

Ethoca Alerts

Ethoca Alerts cover roughly 95% of Mastercard disputes and 40% of Visa disputes. Alerts can be fully automated or managed individually.

When you receive an alert, you have two options:

  1. Refund the transaction and resolve the alert

  2. Dismiss the alert, skip the refund, and let the chargeback proceed

If you've set up a resolution rule, this happens automatically. Otherwise, the alert appears in your dashboard. You have 48 hours from receipt to provide an outcome. If you don't respond in time, the alert is automatically declined and the chargeback comes through.

Transaction Matching

Our system locates transactions in your account using data received from the card networks. This is the foundation for automation and resolution rules.

Depending on your account agreement, available integrations, and connector quality, we offer either strict matching or soft matching.

With strict matching enabled, every alert from the card network is matched to a transaction in your payment processor, and the refund is confirmed as executed.

If the system can't find a match, someone on our team manually investigates using the alert data and transaction records. If we still can't locate it, you're automatically credited for that alert.

If connector data quality or account configuration prevents strict matching, we fall back to soft matching. The system attempts a best-case match, but if it fails, the alert lands in your dashboard as "Action Required" for manual review.

We try to offer strict matching to as many customers as possible at no extra cost. But some setups make it technically impossible, missing data fields, limited query options, or specific configurations. Examples:

NMI

ChargebackStop ↔ NMI integration is straightforward.

  1. Log in to your NMI account

  2. Click "My Settings" in the top right corner

  3. Scroll down to "Private Security Keys"

Orders API
Orders API
Transaction Key - API key from step 5.
  • Confirm with "Add integration"

  • Authorize.net only allows one API key to exist at the time.

    If you already use Authorize.net API, creating a new key will invalidate it and cause your other integrations to fail.

    Proceed with caution!

    ChargebackStop Integrations settings

    Historic purchase history

    Qualifying data

    Eligible dispute conditions

    Card network integration

    When a dispute is successfully deflected:

    • The dispute never reaches you

    • The TC40 is excluded from your VAMP ratio

    • You retain the funds from the original transaction

    The richer your Digital Receipts integration, the more transaction data and qualifying identifiers are available, and the more disputes become eligible for deflection. This is why we recommend implementing Digital Receipts and Systematic Dispute Deflection together, the same data powers both products.

    Chargeback Alerts let you refund a transaction and prevent the chargeback from landing, but by the time an alert is raised, the TC40 has already been filed with Visa. The dispute is resolved, but your VAMP ratio still takes the hit.

    Systematic Dispute Deflection intervenes earlier. It blocks the dispute before it's created, which is the only way to prevent the TC40 from being filed in the first place. This makes it the only product in the ecosystem that both prevents first-party misuse disputes and reduces your VAMP exposure.

    If you're already using Systematic Dispute Deflection, your deflections are automatically benefiting your VAMP ratio, no additional setup is required.

    If you're not yet enrolled, see the introduction for how it works, or the integration guide to begin.

    The short version: Systematic Dispute Deflection is the single most effective way to reduce your VAMP ratio from first-party misuse. No other tool prevents the dispute and removes the TC40 at the same time.

    What is VAMP?

    What changed

    See here for a full breakdown of the ratios and threadholds for merchants and acquirers

    How Systematic Dispute Deflection reduces your ratio

    Visa Acquirer Monitoring Program (VAMP)
    Systematic Dispute Deflection

    Why other tools can't do this

    What you should do

    Want to understand your current VAMP exposure? Contact our support team. We can help you assess your ratio and estimate the impact of Systematic Dispute Deflection on your standing.

    We recommend setting separate organisations for all your customers.

    A membership of a user within an organisation.

    • This enables your customers to log in to their organisation.

    • If your integration does not include your customers logging into ChargebackStop platform in any form (including whitelabel solutions), you will not need to create any memberships.

    A merchant account within an organisation.

    • If your customer has multiple merchant accounts with payment processors, create a separate merchant account for each one.

    • When creating a new merchant, we strongly recommend passing external_id as their MID, CAID, or provider account ID. It helps you differentiate merchant accounts later on.

    A connection with a data source (e.g. payment processor such as Stripe, Adyen, Shopify, etc.), or a custom orders integration if you decide to push orders to ChargebackStop using the Orders API.

    • Integrations allow ChargebackStop to match incoming alerts to transactions, and (for payment-processor-based integrations) to automatically refund or cancel payments associated with alerts.

    An enrolment with a dispute prevention service (Ethoca or Verifi RDR).

    • Creating an enrolment in the ChargebackStop platform starts the process of enrolling the merchant account with the selected service.

    • Enrolment can span across multiple merchant accounts, e.g. when a single descriptor enrolled with Ethoca is used across multiple accounts.

    An individual pre-dispute alert.

    • An alert is always tied to an enrolment, as it’s the enrolment that’s the source of the alert.

    A dispute case ingested via your payment processor.

    • Only available if you choose to work with ChargebackStop for representment.

    The ChargebackStop platform has an API that supports creating and managing all of the entities above.

    You can read more about how to consume the API and onboard customers in our API integration guide page.

    The ChargebackStop platform supports webhooks for the following events:

    • alert.created

    • alert.updated

    • enrolment.created

    • enrolment.updated

    • representment.created

    • representment.updated

    • scheme_notice.created

    • scheme_notice.updated

    Full webhook documentation is available here: Webhooks

    Webhooks can be tested using our Postman collection: https://www.postman.com/chargebackstop/chargebackstop/collection/2yu40q8/chargebackstop-webhooks. You can read more on the page linked above.

    Terminology

    Partner

    Organisation

    Membership

    Merchant

    Integration

    Enrolment

    Alert

    Representment

    API

    Webhooks

    Important: Ethoca Alerts must be refunded at the gateway level to prevent a chargeback. Marking an alert as resolved in the portal or API alone won't stop the dispute, the transaction must also be refunded through your gateway.

    Ethoca enrollment is descriptor-based. During onboarding, we'll ask for all billing descriptors used by your merchant account(s). Provide every variation: soft, hard, static, dynamic. Missing a descriptor reduces your coverage.

    We evaluate each descriptor to confirm:

    1. It's unique enough to enroll

    2. It isn't already enrolled elsewhere

    If a descriptor is too generic (e.g., "Pet Store"), another merchant may already be enrolled with the same name, blocking your enrollment or causing you to receive their alerts. Using your site name or legal company name typically works better.

    Ethoca Alerts are billed at a fixed per-alert fee, whether you refund or not.

    Around 5–10% of Ethoca alerts each month are invalid. Examples:

    • The transaction was already refunded

    • The transaction was already disputed

    • The alert is clearly for another merchant

    • You can't find the transaction

    • It's a duplicate of a previous alert

    Our system detects invalid alerts automatically, filters them out, and credits your invoice. You never pay for an alert that provided no value. If you spot an invalid alert that wasn't auto-detected, submit it for manual credit review in your dashboard. If the card networks approve, the credit appears on your next invoice.

    Although rare, cross network alerts are still valid, if we see alerts raised by both networks these are counted:

    Scenario 1

    An Ethoca alert is raised, you accept the chargeback and allow it to flow. Verifi then also raise an alert for this transaction which, is not automatically refunded (as you accepted Ethoca). In this case, both alerts are valid with the Verifi not being a duplicate as the chargeback alert is still correct.

    Scenario 2

    An Ethoca alert is raised, you refund, but Verifi still triggers. This may happen if both alerts within 24 hour window from each other.

    If you want to filter alerts by amount, date, reason code, or another criterion, contact sales or support. We work with the card networks case by case to add filter capabilities to your descriptor.

    For example: if you'd refund low-value chargebacks but prefer to accept high-value ones, a filter lets you avoid paying alert fees on alerts you don't plan to act on.

    If multiple merchant accounts share the same descriptor, our system attempts to locate the transaction across all connected payment providers.

    When possible, we recommend adding a unique character to each merchant account's descriptor. This helps us match orders more efficiently during alert processing, especially at higher volumes.

    Enrollment

    Billing

    Invalid alerts

    Valid duplicate alerts

    Reducing coverage

    Multiple merchant accounts

  • Digital wallet providers like Stripe Link that mask card data

  • Network tokens that scramble card data, increasing the risk of invalid matches

  • Sometimes the data from the card network isn't enough to produce a definitive match, or any results at all.

    If you're on strict matching, these cases are fully creditable. You won't pay for them.

    However, if matching issues stem from your specific setup (e.g., using Stripe Link in wallet mode), Mastercard may consider it a problem on your end rather than theirs. In those cases, we likely can't credit every instance.

    Strict matching

    Soft matching

    Unmatchable transactions

    Create a new key with API permissions

  • Open ChargebackStop Integrations settings, and select "NMI" from the "Add provider" dropdown.

  • Give your new integration a display name (used only internally by ChargebackStop) and paste the security key you just created.

  • Save the new integration with "Add integration".

  • You don't need NMI account in order to use ChargebackStop. We work with all processors and an NMI integration is not required.

    Integrating NMI

    API documentation

    All API endpoints authenticate using bearer tokens (Authorization: Bearer cbs_<token>). There are two types of API key:

    • Partner key — tied to a partner group; can access resources across all organisations within that group.

    • Organisation key — tied to a single organisation; can only access resources belonging to that organisation.

    The sections below describe which APIs are available to each key type.

    These APIs are restricted to partner keys. Requests made with an organisation key will be rejected.

    They cover tenant provisioning — creating and managing organisations, merchants, memberships, and enrolments.

    API
    Methods
    Docs

    Organisations

    POST GET PATCH DELETE

    Merchants

    POST GET PATCH DELETE

    These APIs accept both key types. Data is automatically scoped to the organisations the key has access to.

    API
    Methods
    Docs

    Alerts

    GET PATCH

    Orders

    GET POST PATCH

    Partner-level only

    Note: Enrolments V1 is deprecated. Use the V2 enrolments API for all new integrations. V2 adds support for enrolling a descriptor with multiple merchants in a single request.

    Note: Access to the Merchants and Enrolments V2 APIs with an organisation key can be enabled for select organisations on request. Contact support if you need this.

    Organisation and partner level

    Stripe

    Do I need to have a Stripe account?

    No, we work with all processors and a Stripe integration is not required. Do note, some of our functionality is only available with Stripe currently (billing descriptors etc.)

    You can skip manual API key setup by using this magic link that pre-fills all required permissions.

    Stripe Integration Instructions

    1. Create a new restricted API key in Stripe (https://dashboard.stripe.com/apikeys) ensuring that all the required permissions (see the full list below) are selected.

      1. Follow this link to open the API keys page in Stripe with all of our required permissions pre-filled: Create ChargebackStop key in Stripe

    2. Grab your Stripe account ID from your profile page ().

    3. Login to ChargebackStop and under > Integrations add your Stripe account ID and restricted key.

    In order to match network alerts to your Stripe transactions and automate refunds, we need to sync the following data into our system:

    → Payment intents / charges

    → Customers

    → Refunds

    → Subscriptions

    → Payment methods (without card numbers)

    → Last 4 digits of card number

    → BIN

    → Disputes

    → Early fraud notification

    Stripe made the decision to not disclose card brand, card last 4, authorisation code, BIN, or ARN for transactions paid for with Link in their API. As a result, If you use Stripe Link as a payment method in your Stripe integration, we won't be able to automatically match alerts to Stripe transactions.

    If we cannot match an alert due to multiple matching Link transactions existing, you might still be charged for the alert. This is not a valid creditable scenario recognised by Verifi nor Ethoca.

    There are a few suggested options to try and prevent unmatched alerts and potentially being charged for them:

    1. Use Link in wallet mode.

    2. If Stripe Checkout is not used, alternative approaches are available, although these may require some additional configuration. Please reach out to discuss.

    3. Don’t offer Link

    If these options don’t work for your specific case, then we can provide you with the opportunity to manually match these. Instead of us automatically resolving as “Not Refunded” we can add these to your “Action Required” queue. This gives you the opportunity to manually action this alert. Reach out to us, should you wish to activate this.

    Memberships

    POST GET PATCH DELETE

    Memberships

    Enrolments V1 (deprecated)

    POST GET DELETE

    —

    Enrolments V2

    POST GET DELETE

    Enrolments

    Integrations

    GET POST PATCH

    Integrations

    Lookups

    GET

    Lookups

    Representments

    GET POST PATCH

    —

    Scheme Notices

    GET

    Scheme Notices

    Simulations

    POST PATCH

    Simulations

    Organisations
    Merchants
    Alerts
    Orders

    Used for correlating network alerts with charges and initiating refund processes.

    ⁠PaymentMethods (Read)

    Helps match network alerts by analysing the BIN on card objects.

    Products (Read):

    Provides necessary information related to payment intents and subscriptions.

    Prices (Read)

    Displays information pertinent to subscriptions.

    Subscriptions (Read and Write)

    Facilitates the linking of payment intents to invoices, supporting refund and cancellation workflows.

    Credit notes (Read and Write)

    Enables viewing and managing invoice refunds when using Stripe Billing.

    ⁠Invoices (Write)

    Allows for linking payment intents to their respective subscriptions and updating statement descriptors for Link payments.

    Webhooks (Write)

    Allows for ChargebackStop to setup webhooks for the platform to automate certain tasks in real time.

    Disputes (Read and Write)

    Allows the platform to sync the disputes to detect if the incoming alert is not disputed yet. Write permission allows us to submit representment for the disputes you decide to accept.

    Permission

    Description

    Charges (Read and Write)

    Required for matching network alerts to charges and processing refunds.

    Customers (Read)

    Essential for linking alerts to customers and accessing payment methods.

    Events (Read and Write)

    Ensures real-time updates on account changes without the need for frequent resource refetching.

    Stripe Integration Permissions

    What is synced?

    Matching Stripe Link payments

    If you offer Link to your customers you may not be able to prevent as many chargebacks unless you implement some changes to the default Link settings with Stripe. Without these changes, you may be charged for unactionable alerts.

    Please read this section carefully to fully understand the required changes

    https://dashboard.stripe.com/settings/user
    Settings
    Read more details in Stripe documentation
    Create ChargebackStop key in Stripe

    PaymentIntents (Read and Write)

    Adyen

    We are aware of the fact that this integration guide is quite long. We are happy to run this integration for you in your Adyen account.

    To have ChargebackStop team perform the integration process for you, please add our Client Services account ([email protected]) as a user to your Adyen account.

    Make sure to include the following permissions.

    Accounts

    • Company account and all associated merchant accounts

    Roles

    Welcome

    ChargebackStop gives you a single platform to prevent chargebacks before they happen. We sit between you and the card networks, handling the integration, automation, and resolution logic so you can focus on your business.

    This documentation covers everything you need to get set up, configure your products, and start preventing disputes.

    Every chargeback has a lifecycle. We intervene at three different stages, each with its own protection layer. Use one, two, or all three depending on your risk profile and goals.

    1

    Digital Receipts push rich order data to cardholders and their banks in real time. When a cardholder views a transaction in their banking app or a bank agent opens a dispute portal, they see subscription details, itemised breakdowns, delivery tracking, and more, before a dispute is ever raised.

    This reduces cardholder confusion and gives banks the context they need to resolve queries without filing a chargeback.

    Powered by: Order Insights (Visa) · Consumer Clarity (Mastercard)

    Get started with Digital Receipts →

    2

    Systematic Dispute Deflection

    Systematic Dispute Deflection blocks friendly fraud disputes at the card network level. When a cardholder attempts to dispute a transaction, the network checks their purchase history and qualifying identifiers. If there's a match, the dispute is instantly blocked, you retain the funds and it never hits your dispute rate.

    Powered by: Compelling Evidence 3.0 (Visa) · First Party Trust (Mastercard)

    Get started with Systematic Dispute Deflection →

    3

    Chargeback Alerts

    Chargeback Alerts notify you of a dispute before it becomes an official chargeback. When an alert comes in, you can refund the transaction and prevent the chargeback entirely, or decline the alert and let the dispute proceed. Alerts can be fully automated with resolution rules or handled case by case in your dashboard.

    When both alert programs are active, merchants typically see up to 95% dispute prevention coverage across Visa and Mastercard.

    Powered by: Ethoca Alerts (Mastercard) · Verifi RDR (Visa)

    Get started with Chargeback Alerts →

    ChargebackStop integrates directly with your payment processor to locate transactions, issue refunds, and pull order data. We currently support:

    • Stripe

    • Adyen

    • Authorize.net

    • NMI

    • ACI Worldwide (OPPWA)

    If your processor isn't listed, reach out to our team, we're adding new integrations regularly.

    If you're integrating via API or building on top of ChargebackStop as a partner, head to the API documentation or the Partner integration guide.

    ChargebackStop is built for both merchants and PSPs. If you're a payment service provider looking to white-label our platform, offer chargeback prevention to your merchants, or manage risk at portfolio level, contact our sales team to discuss partner options.

    How ChargebackStop works

    New here? Start with Chargeback Alerts if you want the fastest path to reducing disputes. Most merchants are protected within a few working days.

    Digital Receipts

    Connecting your payment processor

    For developers

    For payment service providers

    Make sure the following roles are selected:
    • General

      • Merchant report

      • Merchant view PII

      • Download reports

      • Generate reports

      • Merchant report

    • Developer

      • Manage API credentials

      • Merchant technical integrator

    • Transactions

    • Merchant manage payments

    • View payments

    Once that's done please let us know, and we'll pick it up from there! That's all you need to do.

    In order to integrate ChargebackStop and Adyen, you'll need to perform a few actions in your Adyen account.

    If you want to keep track of your progress as you work through all these steps, you can use the checklist at the bottom of this page.

    If you encounter any issues at any point of the process, please contact our support at [email protected].

    If you prefer to perform the integration steps manually, please follow this guide.

    ChargebackStop integration with Adyen relies on two types of reports being automatically generated by Adyen every day:

    • Payment accounting

    • Received payment details

    Before you begin, please open your Adyen dashboard.

    1. Click "Reports" in left-hand menu.

    2. Select "All" tab underneath the search input.

    3. Type "Payment accounting" in the search input.

    4. Click "Payment accounting" report title in the list.

    Here's where you need to click in each of the steps above:

    Once you are inside of the "Payment accounting" report, please do the following:

    1. Click "Manage report".

    2. In the dropdown menu, click "Automatic (generate on a schedule)".

    In the pop-up window that opens, switch the "Automatic generation" toggle to "On".

    Once that's done, repeat the same steps for the "Received payment details" report.

    Before you begin, please open your Adyen dashboard.

    1. Click "Reports" in left-hand menu.

    2. Select "All" tab underneath the search input.

    3. Type "Payment accounting" in the search input.

    4. Click "Payment accounting" report title in the list.

    Here's where you need to click in each of the steps above:

    Once the report page opens, click on the "Column configuration" tab underneath the main headline.

    In the list, please make sure that the following columns are enabled:

    • Company Account

    • Merchant Account

    • Psp Reference

    • Record Type

    • Main Amount

    • Main Currency

    • ARN

    • Creation Date (AMS)

    In most cases, only the last two columns will need to be enabled. You can add more columns to your reports if you need them for other purposes, ChargebackStop will ignore any data that is not required by us. Ordering of the column does not matter for ChargebackStop.

    Once you made sure all the columns from the list above are enabled, please save the changes by clicking the "Save configuration" button at the bottom of the page.

    Make sure to familiarise yourself with the contents of the popup window displayed, and confirm it with "OK" button once you've made sure the change won't break any workflows in your organisation.

    Next step is to create an API credential web service user that will be used by ChargebackStop to perform operations in your account.

    Firstly, make sure you are in your Adyen company account context, not merchant account context.

    Once you're confident you're within company account context, you can proceed to create web service user API credential by following these steps:

    1. Click "Developers" in the left-hand menu.

    2. In the list that opens, select "API credentials".

    3. Click the blue button in the top right that says "Create new credential".

    In the pop-up window that opens, select the following:

    1. Make sure that "Web service user" credential type is selected.

    2. You can optionally add a description to make it easier to identify the API credential later on, e.g. "ChargebackStop integration".

    3. Click the blue "Create credential" button in the bottom right corner of the window.

    In the next screen, you will see your new key details. Firstly, please copy the API key and store it in a secure spot. You will use it later on when creating your ChargebackStop integration.

    Next, please scroll down to the "Permissions" section below. In the "Roles" block, please make sure that the following checkboxes are selected:

    • Account

      • Management API - Accounts read and write

      • Management API - API credentials read and write

      • Management API - Webhooks read and write

    • Uncategorized

      • Checkout webservice role

    Once that's verified, you can finalise API credential creation using the blue "Save changes" button in the bottom right corner of the page.

    The process for creating reports service user is similar.

    Firstly, make sure you are in your Adyen company account context, not merchant account context.

    Once you're confident you're within company account context, you can proceed to create web service user API credential by following these steps:

    1. Click "Developers" in the left-hand menu

    2. In the list that opens, select "API credentials"

    3. Click the blue button in the top right that says "Create new credential"

    In the pop-up window that opens, select the following:

    1. Make sure that "Report service user" credential type is selected.

      1. This is the first step that's different from the web service user API credential creation.

    2. You can optionally add a description to make it easier to identify the API credential later on, e.g. "ChargebackStop integration".

    3. Click the blue "Create credential" button in the bottom right corner of the window.

    In the next screen, you will see your new key details.

    1. Please copy the API key and store it in a secure spot. You will use it later on when creating your ChargebackStop integration.

    2. Finalise API credential creation using the blue "Save changes" button in the bottom right corner of the page.

    You are now ready to create the integration in ChargebackStop dashboard!

    The first step is to open integration settings page in ChargebackStop.

    Next, click on the black "Add provider" button. In the dropdown list, select "Adyen".

    If this is the first integration in your ChargebackStop organisation, you'll need to click "Add your first integration" button in the middle of the page instead.

    Once the pop-up window opens, enter the required data into respective fields.

    Company and merchant account names can be found in dropdown menu in the top left corner of Adyen dashboard. Web service user API key and report service user API key are the keys we generated in previous part of this tutorial.

    In order to save and enable the integration, press the black "Add integration" button at the bottom of the pop-up window.

    ChargebackStop platform will now do the following:

    1. Verify your web service user API key.

    2. Verify your reports service user API key.

    3. Set up required webhooks in your Adyen account.

    If all of the above succeed, you'll see a "Successfully connected to Adyen" message above the integrations list and a green "Enabled" badge next to the integration.

    In order to keep track of your ChargebackStop - Adyen integration progress, you can use this handy checklist.

    You don't need an Adyen account in order to use ChargebackStop. We work with all processors and an Adyen integration is not required.

    Before you begin…

    The ChargebackStop team can perform this integration process for you. See details below.

    Integrating Adyen Manually

    ChargebackStop team can perform this integration for you. Please see the section above.

    Automatic reports generation

    Additional fields in "Payment accounting" report

    Create web service user API credential

    You won't be able to see this key again. Make sure you store it somewhere safe temporarily as you'll need it in the next steps!

    Create reports service user API credential

    You won't be able to see this key again. Make sure you store it somewhere safe temporarily as you'll need it in the next steps!

    Connecting ChargebackStop to your Adyen account

    Final checklist

    Migration Guide: fraud_notification.created -> scheme_notice.created

    This guide explains how to migrate webhook consumers from the deprecated fraud_notification.created event to scheme_notice.created.

    What is changing

    • fraud_notification.created is deprecated and will be removed on March 31.

    • scheme_notice.created is the replacement event for new scheme notice records.

    • Event envelope stays the same: id, type, created_at, data.object, api_version.

    • Do not listen to fraud_notification.created and scheme_notice.created at the same time in production.

    • A dual subscription can create duplicate processing for the same business signal.

    • fraud_notification.created events are not remapped onto existing

    The new event payload is based on SchemeNotice.

    Timestamps are RFC 3339 UTC. In production payloads, envelope created_at is emitted as an offset timestamp (for example +00:00), while data.object datetime fields are emitted with a Z suffix. Fractional seconds may appear when present.

    1
    1. Prepare your consumer code to support scheme_notice.created before changing subscriptions.

    2

    Use a single-event-family cutover to avoid duplicates:

    1

    Deploy consumer changes that can parse scheme_notice.created.

    2

    In production webhook configuration, switch subscription from fraud_notification.created to scheme_notice.created in one cutover window.

    3

    Scheme notices

    List and retrieve scheme notices for accessible organisations.

    Base URL: https://api.chargebackstop.com/v1/scheme-notices/

    Authentication: Bearer token via API key.

    Required abilities:

    • scheme_notices:read for GET endpoints

    Access scope model:

    • Organisation-level keys can access scheme notices for their own organisation only.

    • Admin partner-group keys can access scheme notices across all organisations for their partner.

    • Non-admin partner-group keys can access scheme notices only for organisations assigned to their group.


    Returns a paginated list of scheme notices accessible to the authenticated key.

    API level: Organisation-level and partner-level Authentication: scheme_notices:read

    Parameter
    Type
    Description
    • If both reported_at_gte and reported_at_lte are sent, reported_at_gte must be less than or equal to reported_at_lte.

    • Default sort order is newest reported notice first (-reported_at).


    Returns one scheme notice if it is visible to the authenticated key.

    API level: Organisation-level and partner-level Authentication: scheme_notices:read

    Parameter
    Type
    Description
    • The same access rules as list scheme notices apply.

    • List items and individual scheme notice responses use the same item schema.

    • Connector raw_data is not returned by this API.


    Error responses use this shape:

    Lookups

    List and retrieve digital receipt lookups for accessible organisations.

    Base URL: https://api.chargebackstop.com/v1/lookups/

    Authentication: Bearer token via API key.

    Required abilities:

    • lookups:read for GET endpoints

    Access scope model:

    • Organisation-level keys can access lookups for their own organisation only.

    • Admin partner-group keys can access lookups across all organisations for their partner.

    • Non-admin partner-group keys can access lookups only for organisations assigned to their group.

    Returns a paginated list of lookup records accessible to the authenticated key.

    API level: Organisation-level and partner-level Authentication: lookups:read

    Parameter
    Type
    Description
    • If both created_at_gte and created_at_lte are sent, created_at_gte must be less than or equal to created_at_lte.

    • Default sort order is newest lookup first (-created_at).


    Returns one lookup if it is visible to the authenticated key.

    API level: Organisation-level and partner-level Authentication: lookups:read

    Parameter
    Type
    Description
    • The same access rules as list lookups apply.

    • Non-existent or inaccessible lookups return 404 Not found.


    I successfully connected ChargebackStop platform to my Adyen account
    SchemeNotice
    rows.
  • Historical backfill/migration does not emit webhook side effects (no replay).

  • Use a strict cutover plan: stop legacy consumption, then start new event consumption.

  • scheme_notice_type

    Renamed; allowed values: TC15, TC40, SAFE (fraud_notification.created used TC40/SAFE)

    fraud_reported_at

    fraud_reported_at

    Same semantic meaning

    fraud_type

    fraud_type

    Same

    transaction_amount_in_cents

    transaction_amount_in_cents

    Same

    transaction_currency_code

    transaction_currency_code

    Same

    transaction_card_bin

    transaction_card_bin

    Same

    transaction_card_last4

    transaction_card_last4

    Same

    transaction_merchant_name

    transaction_merchant_name

    Same

    transaction_merchant_id

    transaction_merchant_id

    Same

    transaction_acquirer_reference_number

    transaction_acquirer_reference_number

    Same

    transaction_authorisation_code

    transaction_authorisation_code

    Same

    transaction_original_date

    transaction_original_date

    Same

    (not available)

    merchant_id

    New, nullable

    (not available)

    notice_type

    New (FRAUD_NOTICE or DISPUTE_NOTICE)

    (not available)

    scheme

    New (VISA, MASTERCARD, OTHER)

    (not available)

    is_revoked

    New lifecycle field

    (not available)

    notice_revoked_at

    New lifecycle timestamp

    (not available)

    fraud_dispute_eligible

    New optional boolean

    (not available)

    transaction_purchase_date

    New optional timestamp

    (not available)

    created_at, updated_at

    Object-level timestamps

    replace fraud_notification_type with scheme_notice_type
  • expect object id to use schntc_* prefix

  • 3

    Keep existing logic for common fields

    Keep existing logic for common fields (fraud_reported_at, transaction_*, fraud_type).

    4

    Add null-safe handling for new optional fields

    Add null-safe handling for new optional fields (merchant_id, transaction_purchase_date, fraud_dispute_eligible, notice_revoked_at).

    5

    Execute strict cutover in webhook settings

    • disable/unsubscribe fraud_notification.created

    • enable/subscribe scheme_notice.created

    • do not run both subscriptions concurrently in production

    6

    Keep handler focused on create semantics

    Keep your handler focused on create semantics for scheme_notice.created.

    Verify delivery and downstream processing

    Verify successful delivery and downstream processing.

    4

    Keep legacy handler for rollback only

    Keep legacy handler code temporarily for rollback, but keep legacy subscription disabled unless rolling back.

    5

    Remove legacy handler after cutover is stable

    Remove legacy handler after cutover is stable.

    Deprecated event (fraud_notification.created)

    Replacement (scheme_notice.created)

    Notes

    id (frdnt_*)

    id (schntc_*)

    Object id prefix changes

    organisation_id

    organisation_id

    Same

    Compatibility and rollout notes

    Payload changes (data.object)

    Field mapping

    Example: new event format

    Consumer migration checklist

    Prepare your consumer code to support scheme_notice.created

    Update parser mappings

    Recommended strict cutover strategy

    Deploy consumer changes that can parse scheme_notice.created

    Switch subscription in one cutover window

    fraud_notification_type

    string

    Filter by merchant ID

    reported_at_gte

    datetime

    Include scheme notices reported at or after this timestamp (ISO 8601, inclusive)

    reported_at_lte

    datetime

    Include scheme notices reported at or before this timestamp (ISO 8601, inclusive)

    sort

    string

    Sort field: -reported_at (default), reported_at

    limit

    integer

    Number of results per page

    offset

    integer

    Number of results to skip

    Non-existent scheme notices return 404 Not found.

    scheme_notice_type

    string

    Filter by notice type: TC15, TC40, SAFE

    organisation_id

    string

    Filter by organisation ID

    scheme_notice_id

    string

    Scheme notice ID

    GET /v1/scheme-notices - list scheme notices

    Query parameters

    Important behaviour

    Example 1 request

    Example 1 response

    GET /v1/scheme-notices/{scheme_notice_id} - get scheme notice by ID

    URL parameters

    Important behaviour

    Example 2 request

    Example 2 response

    Common error responses

    Example 3 response - 401 unauthorised

    Example 4 response - 403 forbidden

    Example 5 response - 404 not found

    Example 6 response - 422 invalid date range

    merchant_id

    string

    Filter by lookup type

    parent_lookup_id

    string

    Filter by parent lookup ID

    lookup_status

    string

    Filter by lookup status: PENDING, SUCCEEDED, FAILED, TIMEOUT

    deflection_status

    string

    Filter by deflection status: NOT_ATTEMPTED, PENDING, SUCCEEDED, FAILED

    created_at_gte

    datetime

    Include lookups created at or after this timestamp (ISO 8601, inclusive)

    created_at_lte

    datetime

    Include lookups created at or before this timestamp (ISO 8601, inclusive)

    sort

    string

    Sort field: -created_at (default) or created_at

    limit

    integer

    Number of results per page

    offset

    integer

    Number of results to skip

    Responses use the same lookup object shape as lookup webhooks.

    organisation_id

    string

    Filter by organisation ID

    enrollment_id

    string

    Filter by enrollment ID

    lookup_id

    string

    Lookup ID

    GET /v1/lookups - list lookups

    Query parameters

    Important behaviour

    Example request

    Example response

    GET /v1/lookups/{lookup_id} - get lookup by ID

    URL parameters

    Important behaviour

    Example request

    Example response

    Error examples

    Example: unauthorised
    Example: forbidden
    Example: not found
    Example: invalid date range

    type

    {
      "id": "evt_9UYR3Q8xP4aX4Z4uL2YfN",
      "type": "scheme_notice.created",
      "created_at": "2026-02-13T12:17:42+00:00",
      "data": {
        "object": {
          "id": "schntc_8W2tVb13qfHkK3gQ9n7Yp",
          "organisation_id": "org_WVJ7aJzpT32FED9BqKPpM",
          "merchant_id": "mrch_bQXg83B18qgACnp5Y4qU8",
          "scheme_notice_type": "SAFE",
          "notice_type": "FRAUD_NOTICE",
          "scheme": "MASTERCARD",
          "is_revoked": false,
          "notice_revoked_at": null,
          "fraud_reported_at": "2026-02-13T12:15:00Z",
          "transaction_amount_in_cents": 14760,
          "transaction_currency_code": "USD",
          "transaction_card_bin": "411798",
          "transaction_card_last4": "3508",
          "transaction_merchant_name": "ECOM-STUFF OUTLET",
          "transaction_merchant_id": "274953873887879",
          "transaction_acquirer_reference_number": "77198913101798678449413",
          "transaction_authorisation_code": "96JNEP",
          "transaction_original_date": "2026-02-01T08:13:50Z",
          "transaction_purchase_date": null,
          "fraud_type": "CARD_NOT_PRESENT",
          "fraud_dispute_eligible": true,
          "created_at": "2026-02-13T12:16:10Z",
          "updated_at": "2026-02-13T12:16:10Z"
        }
      },
      "api_version": "v1"
    }
    curl -X GET "https://api.chargebackstop.com/v1/scheme-notices/?scheme_notice_type=TC40&sort=-reported_at&limit=20&offset=0" \
      -H "Authorization: Bearer <api_key>"
    {
      "items": [
        {
          "id": "schntc_abc123",
          "organisation_id": "org_xyz456",
          "merchant_id": "mrch_abc123",
          "scheme_notice_type": "TC40",
          "notice_type": "FRAUD_NOTICE",
          "scheme": "VISA",
          "is_revoked": false,
          "notice_revoked_at": null,
          "fraud_reported_at": "2026-02-11T10:30:00Z",
          "transaction_amount_in_cents": 4999,
          "transaction_currency_code": "USD",
          "transaction_card_bin": "424242",
          "transaction_card_last4": "4242",
          "transaction_merchant_name": "EXAMPLE STORE",
          "transaction_merchant_id": "merchant-123",
          "transaction_acquirer_reference_number": "74027012345678901234567",
          "transaction_authorisation_code": "ABC123",
          "transaction_original_date": "2026-02-01T10:30:00Z",
          "transaction_purchase_date": "2026-02-01T10:30:00Z",
          "fraud_type": "CARD_NOT_PRESENT",
          "fraud_dispute_eligible": true,
          "created_at": "2026-02-11T10:31:00Z",
          "updated_at": "2026-02-11T10:31:00Z",
          "parent_notice_id": null,
          "enrolment_id": "enrl_abc123",
          "matched_transaction_entity_id": "dpe_abc123",
          "links": [
            {
              "rel": "self",
              "uri": "/v1/scheme-notices/schntc_abc123"
            }
          ]
        }
      ],
      "count": 1
    }
    curl -X GET "https://api.chargebackstop.com/v1/scheme-notices/schntc_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "schntc_abc123",
      "organisation_id": "org_xyz456",
      "merchant_id": "mrch_abc123",
      "scheme_notice_type": "TC40",
      "notice_type": "FRAUD_NOTICE",
      "scheme": "VISA",
      "is_revoked": false,
      "notice_revoked_at": null,
      "fraud_reported_at": "2026-02-11T10:30:00Z",
      "transaction_amount_in_cents": 4999,
      "transaction_currency_code": "USD",
      "transaction_card_bin": "424242",
      "transaction_card_last4": "4242",
      "transaction_merchant_name": "EXAMPLE STORE",
      "transaction_merchant_id": "merchant-123",
      "transaction_acquirer_reference_number": "74027012345678901234567",
      "transaction_authorisation_code": "ABC123",
      "transaction_original_date": "2026-02-01T10:30:00Z",
      "transaction_purchase_date": "2026-02-01T10:30:00Z",
      "fraud_type": "CARD_NOT_PRESENT",
      "fraud_dispute_eligible": true,
      "created_at": "2026-02-11T10:31:00Z",
      "updated_at": "2026-02-11T10:31:00Z",
      "parent_notice_id": null,
      "enrolment_id": "enrl_abc123",
      "matched_transaction_entity_id": "dpe_abc123",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/scheme-notices/schntc_abc123"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "ERROR_CODE",
          "message": "Human readable message"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "UNAUTHORISED",
          "message": "Unauthorised"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "INVALID_DATE_RANGE",
          "message": "reported_at_gte cannot be greater than reported_at_lte"
        }
      ]
    }
    curl -X GET "https://api.chargebackstop.com/v1/lookups/?organisation_id=org_xyz456&lookup_status=SUCCEEDED&sort=-created_at&limit=20&offset=0" \
      -H "Authorization: Bearer <api_key>"
    {
      "items": [
        {
          "id": "lkup_abc123",
          "organisation_id": "org_xyz456",
          "enrollment_id": "enrl_def456",
          "type": "ETHOCA_CONSUMER_CLARITY",
          "parent_lookup_id": null,
          "lookup_status": "SUCCEEDED",
          "deflection_status": "NOT_ATTEMPTED",
          "transaction_card_bin": "424242",
          "transaction_card_last4": "4242",
          "transaction_arn": "74027012345678901234567",
          "transaction_auth_code": "AUTH123",
          "transaction_amount": 4999,
          "transaction_currency": "USD",
          "transaction_date": "2026-02-10T10:30:00Z",
          "transaction_statement_descriptor": "EXAMPLE STORE",
          "transaction_network_id": "network_123",
          "integration_id": "int_abc123",
          "integration_transaction_id": "txn_123",
          "created_at": "2026-02-11T10:30:00Z",
          "updated_at": "2026-02-11T10:30:00Z",
          "links": [
            {
              "rel": "self",
              "uri": "/v1/lookups/lkup_abc123"
            }
          ]
        }
      ],
      "count": 1
    }
    curl -X GET "https://api.chargebackstop.com/v1/lookups/lkup_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "lkup_abc123",
      "organisation_id": "org_xyz456",
      "enrollment_id": "enrl_def456",
      "type": "ETHOCA_CONSUMER_CLARITY",
      "parent_lookup_id": null,
      "lookup_status": "SUCCEEDED",
      "deflection_status": "NOT_ATTEMPTED",
      "transaction_card_bin": "424242",
      "transaction_card_last4": "4242",
      "transaction_arn": "74027012345678901234567",
      "transaction_auth_code": "AUTH123",
      "transaction_amount": 4999,
      "transaction_currency": "USD",
      "transaction_date": "2026-02-10T10:30:00Z",
      "transaction_statement_descriptor": "EXAMPLE STORE",
      "transaction_network_id": "network_123",
      "integration_id": "int_abc123",
      "integration_transaction_id": "txn_123",
      "created_at": "2026-02-11T10:30:00Z",
      "updated_at": "2026-02-11T10:30:00Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/lookups/lkup_abc123"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "UNAUTHORISED",
          "message": "Unauthorised"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "INVALID_DATE_RANGE",
          "message": "created_at_gte cannot be greater than created_at_lte"
        }
      ]
    }

    Organisations

    Manage organisations under your partner account.

    This endpoint set is partner-level only. Organisation API keys cannot access these endpoints.

    Base URL: https://api.chargebackstop.com/v1/organisations/ Authentication: Bearer token via API key.

    Required abilities:

    • organisations:read for GET endpoints

    • organisations:write for POST, PATCH, and DELETE endpoints

    Access scope model:

    • Admin partner-group keys can access all organisations belonging to their partner.

    • Non-admin partner-group keys can access only organisations explicitly assigned to their group.

    • Organisation-level keys receive 401 Unauthorised on all endpoints in this API.


    Returns organisations accessible to the authenticated partner-group API key.

    Because organisation mode must match partner mode on create, results for a given partner key are expected to be single-mode (LIVE or TEST).

    API level: Partner-level only Authentication: organisations:read

    Parameter
    Type
    Description

    Create a new organisation for the authenticated partner.

    API level: Partner-level only Authentication: organisations:write

    Field
    Type
    Required
    Validation
    Description

    Retrieve one accessible organisation by ID.

    API level: Partner-level only Authentication: organisations:read

    Parameter
    Type
    Description

    Update organisation details.

    API level: Partner-level only Authentication: organisations:write

    Parameter
    Type
    Description
    Field
    Type
    Required
    Validation
    Description

    Delete an organisation if it has no related dependent records.

    API level: Partner-level only Authentication: organisations:write

    Parameter
    Type
    Description

    204 No Content


    Returned for invalid/expired API keys, and for organisation-level keys calling this partner-only API.

    Returned when the API key is valid but missing required ability (organisations:read or organisations:write).

    Returned when the organisation does not exist or is outside the key's accessible scope.

    Used for business-rule and schema validation errors.

    Example: business validation (delete blocked):

    Other business validation codes you may receive:

    Code
    Meaning

    Schema validation errors are also returned as 422 with VALIDATION_* codes (for example, invalid field values or empty name).

    HAS_ALERTS

    Organisation has alerts and cannot be deleted

    limit

    integer

    Number of results per page

    offset

    integer

    Number of results to skip

    curl -X GET "https://api.chargebackstop.com/v1/organisations/?limit=20&offset=0" \
      -H "Authorization: Bearer <api_key>"
    {
      "items": [
        {
          "id": "org_abc123",
          "name": "Acme Payments",
          "mode": "LIVE",
          "created_at": "2026-01-10T10:45:12Z",
          "updated_at": "2026-01-10T10:45:12Z",
          "links": [
            {
              "rel": "self",
              "uri": "/v1/organisations/org_abc123"
            }
          ]
        },
        {
          "id": "org_def456",
          "name": "Acme Payments EU",
          "mode": "LIVE",
          "created_at": "2026-01-11T09:12:00Z",
          "updated_at": "2026-01-11T09:12:00Z",
          "links": [
            {
              "rel": "self",
              "uri": "/v1/organisations/org_def456"
            }
          ]
        }
      ],
      "count": 2
    }

    name

    string

    Yes

    Min length 1

    Public organisation name

    curl -X POST "https://api.chargebackstop.com/v1/organisations/" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "New Organisation"
      }'
    {
      "id": "org_new123",
      "name": "New Organisation",
      "mode": "LIVE",
      "created_at": "2026-02-16T12:00:00Z",
      "updated_at": "2026-02-16T12:00:00Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/organisations/org_new123"
        }
      ]
    }

    organisation_id

    string

    Organisation ID

    curl -X GET "https://api.chargebackstop.com/v1/organisations/org_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "org_abc123",
      "name": "Acme Payments",
      "mode": "LIVE",
      "created_at": "2026-01-10T10:45:12Z",
      "updated_at": "2026-01-15T08:00:00Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/organisations/org_abc123"
        }
      ]
    }

    organisation_id

    string

    Organisation ID to update

    name

    string

    Yes

    Min length 1

    Updated public organisation name

    curl -X PATCH "https://api.chargebackstop.com/v1/organisations/org_abc123" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Acme Payments UK"
      }'
    {
      "id": "org_abc123",
      "name": "Acme Payments UK",
      "mode": "LIVE",
      "created_at": "2026-01-10T10:45:12Z",
      "updated_at": "2026-02-16T12:10:00Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/organisations/org_abc123"
        }
      ]
    }

    organisation_id

    string

    Organisation ID to delete

    curl -X DELETE "https://api.chargebackstop.com/v1/organisations/org_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "errors": [
        {
          "code": "INVALID_REQUEST",
          "message": "Invalid request"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "UNAUTHORISED",
          "message": "Unauthorised"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "HAS_MERCHANTS",
          "message": "The organisation has merchants. Please contact customer support to delete this organisation."
        }
      ]
    }

    HAS_MERCHANTS

    Organisation has merchants and cannot be deleted

    HAS_ENROLMENTS

    Organisation has active enrolments and cannot be deleted

    HAS_INTEGRATIONS

    Organisation has integrations and cannot be deleted

    HAS_DATA_PROVIDERS

    GET /v1/organisations - List organisations

    Query parameters

    Example request

    Example response

    POST /v1/organisations - Create organisation

    Request body

    Important behavior:

    • Organisation mode always follows the partner's mode.

    • If resulting mode is TEST and name does not already start with [TEST], the API prefixes the name with [TEST] automatically.

    • If name already starts with [TEST], no duplicate prefix is added.

    Example request

    Example response

    GET /v1/organisations/{organisation_id} - Get organisation by ID

    URL parameters

    Example request

    Example response

    Error responses

    404 Not Found - Organisation does not exist or is not accessible to this key:

    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }

    PATCH /v1/organisations/{organisation_id} - Update organisation

    URL parameters

    Request body

    Important behavior:

    • Only name is updatable via this endpoint.

    • mode is not updatable here.

    • Attempting to update an inaccessible organisation returns 404.

    Example request

    Example response

    DELETE /v1/organisations/{organisation_id} - Delete organisation

    URL parameters

    Important behavior:

    • Deletion is blocked if the organisation still has related data. In those cases, API returns 422.

    Blocking checks include:

    • Merchants

    • Network alert enrolments

    • Integrations

    • Data providers

    Example request

    Example response

    Common error responses

    400 Invalid request

    401 Unauthorised

    403 Forbidden (missing ability)

    404 Not found

    422 Unprocessable Entity

    Organisation has data providers and cannot be deleted

    Integrations

    Manage integrations used by ChargebackStop APIs.

    This endpoint set currently supports creating and managing CUSTOM_ORDERS integrations, and listing all integrations your API key can access.

    Base URL: https://api.chargebackstop.com/v1/integrations/ Authentication: Bearer token via API key.

    This endpoint set supports both organisation-level and partner-level keys.

    integrations:read and integrations:write are enabled automatically for every API key.

    • integrations:read for GET endpoints

    • integrations:write for POST and PATCH endpoints

    Access scope model:

    • Organisation-level keys can access integrations for their own organisation only.

    • Admin partner-group keys can access integrations across all organisations for their partner.

    • Non-admin partner-group keys can access integrations only for organisations assigned to their group.


    Returns integrations from organisations accessible to the API key.

    API level: Organisation-level and Partner-level Authentication: integrations:read

    No custom filters are currently supported.

    Pagination parameters are supported:

    Parameter
    Type
    Description

    Create a new integration.

    API level: Organisation-level and Partner-level Authentication: integrations:write

    Field
    Type
    Required
    Validation
    Description

    Status behavior on create:

    • If status is omitted, integrations are created with status: ENABLED.


    Retrieve a single integration by ID.

    API level: Organisation-level and Partner-level Authentication: integrations:read

    Parameter
    Type
    Description

    Update an existing integration.

    API level: Organisation-level and Partner-level Authentication: integrations:write

    • status updates are only allowed for CUSTOM_ORDERS integrations.

    • The only allowed status value in PATCH is DISABLED.

    • name

    Parameter
    Type
    Description
    Field
    Type
    Required
    Validation
    Description

    Other business validation codes you may receive:

    Code
    Meaning

    Verifi RDR

    Verifi RDR (Rapid Dispute Resolution) covers roughly 95% of Visa transactions. Unlike Ethoca Alerts, RDR cases are fully automated at the Visa network level, you can't manage them individually.

    During onboarding, you'll define which transactions should be automatically refunded and which should proceed as disputes. These rules apply to all cases unless you request changes.

    Available RDR rules

    Work with our support team during onboarding to set your strategy. You can filter by:

    • Purchase amount

    • Date

    • Currency

    • Reason code

    • Reason category

    • Transaction identifier

    • BIN range

    These rules are defined upfront and apply automatically. Changes can take anywhere from a few minutes to a few days depending on your setup.

    Verifi RDR enrollment requires your Visa BIN and CAID. These identifiers are set by your payment processor for each merchant account.

    • BIN: A six-digit number identifying your acquiring bank

    • CAID: A 16-character alphanumeric identifier unique to your merchant account with your acquirer

    Together, these form your unique Visa enrollment.

    Most processors don't display this information by default, but their support team or your relationship manager can provide it. Our team will collect and validate your BINs and CAIDs before submitting them. Visa's enrollment SLA is 10 working days, though it sometimes completes sooner.

    Verifi RDR cases are billed per case, regardless of refund outcome. We also offer a model where you're only billed for refunded cases. Contact us for details.

    Multiple merchant accounts typically means multiple BINs and/or CAIDs. Make sure you provide all of them. If using ARN lookup instead, provide at least one or two ARNs per merchant account.

    Alerts

    Enrollment

    Can't get your BIN and CAID? Provide one or two ARNs (acquirer reference numbers) from recent Visa transactions, completed, refunded, or disputed, within the last 120 days. An ARN is a 23-digit transaction identifier. We can use it to query your BIN and CAID directly with Visa.

    Billing

    Multiple merchant accounts

    Organizations

    An organization is the top-level entity in ChargebackStop. It groups your merchant accounts, team members, email preferences, APIs, webhooks, and integrations under one roof.

    We recommend one organization per brand or website. If that brand has multiple merchant accounts, keep them in the same organization, they'll share dispute logic, resolution rules, APIs, and integrations.

    You can belong to multiple organizations and switch between them with a single login.

    Permissions to note

    Anyone invited to an organization can see and read everything in that account. If different teams need restricted access to certain data, use separate organizations.

    The same applies to API keys and webhooks, any credentials created within an organization have full account access.

    Billing

    A billing account determines how you're charged and which organizations are covered under it.

    If you have multiple organizations, they can share a single billing account, useful for keeping invoices in one place. If you'd prefer separate billing for different organizations, let us know during onboarding and we'll set that up.

    To change your payment method, billing frequency, or other billing settings, contact support.

    string

    Yes

    1-255 chars

    Integration display name

    type

    string

    Yes

    Must be CUSTOM_ORDERS

    Integration type

    status

    string

    No

    ENABLED or DISABLED

    Initial integration status

    merchant_ids

    array[string]

    Yes

    Non-empty, unique, all merchants must belong to organisation_id and be accessible

    Merchants linked to this integration

    can be updated.
  • You must provide at least one of status or name.

  • string

    No

    1-255 chars

    New integration name

    limit

    integer

    Number of results per page

    offset

    integer

    Number of results to skip

    organisation_id

    string

    Yes

    Must be accessible by API key

    Organisation that owns the integration

    integration_id

    string

    Integration ID

    integration_id

    string

    Integration ID to update

    status

    string

    No

    DISABLED only; only for CUSTOM_ORDERS integrations

    New integration status

    DUPLICATE_MERCHANT_IDS

    merchant_ids contains duplicate values

    INVALID_MERCHANT_IDS

    One or more merchants do not exist, are inaccessible, or do not belong to the provided organisation

    INVALID_INTEGRATION_TYPE

    PATCH attempted on a non-CUSTOM_ORDERS integration

    MISSING_UPDATE_FIELDS

    API-level summary:

    • Organisation-level and Partner-level keys are supported.

    • Use integrations:read for GET endpoints and integrations:write for POST/PATCH endpoints.

    GET /v1/integrations - List integrations

    Query parameters

    Example 1 request (partner-level key)

    Example 1 response (partner-level key)

    Example 2 request (organisation-level key)

    Example 2 response (organisation-level key)

    POST /v1/integrations - Create integration

    Request body

    Example 3 request

    Example 3 response

    GET /v1/integrations/{integration_id} - Get integration by ID

    URL parameters

    Example 4 request

    Example 4 response

    404 Not Found — Integration does not exist (example)

    PATCH /v1/integrations/{integration_id} - Update integration

    Important behavior

    URL parameters

    Request body

    Example 5 request

    Example 5 response

    Common error responses

    401 Unauthorised (example)
    403 Forbidden (missing ability) (example)
    404 Not found (example)

    Returned when the target organisation or integration is not found.

    422 Unprocessable Entity (business validation) (example)

    name

    name

    PATCH request did not include either status or name

    curl -X GET "https://api.chargebackstop.com/v1/integrations/?limit=20&offset=0" \
      -H "Authorization: Bearer <api_key>"
    {
      "items": [
        {
          "id": "int_abc123",
          "organisation_id": "org_xyz456",
          "name": "Orders API Integration",
          "type": "CUSTOM_ORDERS",
          "status": "ENABLED",
          "merchant_ids": ["mrch_111", "mrch_222"],
          "links": [
            {
              "rel": "self",
              "uri": "/v1/integrations/int_abc123"
            }
          ]
        },
        {
          "id": "int_def789",
          "organisation_id": "org_xyz456",
          "name": "Stripe Main",
          "type": "STRIPE",
          "status": "ENABLED",
          "merchant_ids": ["mrch_111"],
          "links": [
            {
              "rel": "self",
              "uri": "/v1/integrations/int_def789"
            }
          ]
        }
      ],
      "count": 2
    }
    curl -X GET "https://api.chargebackstop.com/v1/integrations/?limit=20&offset=0" \
      -H "Authorization: Bearer <org_api_key>"
    {
      "items": [
        {
          "id": "int_abc123",
          "organisation_id": "org_xyz456",
          "name": "Orders API Integration",
          "type": "CUSTOM_ORDERS",
          "status": "ENABLED",
          "merchant_ids": ["mrch_111", "mrch_222"],
          "links": [
            {
              "rel": "self",
              "uri": "/v1/integrations/int_abc123"
            }
          ]
        }
      ],
      "count": 1
    }
    curl -X POST "https://api.chargebackstop.com/v1/integrations/" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_xyz456",
        "name": "Orders API Integration",
        "type": "CUSTOM_ORDERS",
        "status": "DISABLED",
        "merchant_ids": ["mrch_111", "mrch_222"]
      }'
    {
      "id": "int_abc123",
      "organisation_id": "org_xyz456",
      "name": "Orders API Integration",
      "type": "CUSTOM_ORDERS",
      "status": "DISABLED",
      "merchant_ids": ["mrch_111", "mrch_222"],
      "links": [
        {
          "rel": "self",
          "uri": "/v1/integrations/int_abc123"
        }
      ]
    }
    curl -X GET "https://api.chargebackstop.com/v1/integrations/int_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "int_abc123",
      "organisation_id": "org_xyz456",
      "name": "Orders API Integration",
      "type": "CUSTOM_ORDERS",
      "status": "ENABLED",
      "merchant_ids": ["mrch_111", "mrch_222"],
      "links": [
        {
          "rel": "self",
          "uri": "/v1/integrations/int_abc123"
        }
      ]
    }
    curl -X PATCH "https://api.chargebackstop.com/v1/integrations/int_abc123" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Orders API Integration - EU"
      }'
    {
      "id": "int_abc123",
      "organisation_id": "org_xyz456",
      "name": "Orders API Integration - EU",
      "type": "CUSTOM_ORDERS",
      "status": "DISABLED",
      "merchant_ids": ["mrch_111", "mrch_222"],
      "links": [
        {
          "rel": "self",
          "uri": "/v1/integrations/int_abc123"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "UNAUTHORISED",
          "message": "Unauthorised"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "INVALID_MERCHANT_IDS",
          "message": "One or more merchant_ids are invalid or inaccessible for this organisation"
        }
      ]
    }

    Partner integration guide

    Welcome to the ChargebackStop for Partners platform.

    We suggest starting with the “Integrating with ChargebackStop” page below, which guides you through the API and webhook documentation, as well as the terminology we use at ChargebackStop.

    Title
    Target
    Title
    Target
    Title
    Target

    Integrating with ChargebackStop

    API

    Webhooks

    Alerts

    List, retrieve, and action network alerts for accessible organisations.

    Verifi RDR alerts are resolved automatically. Verifi RDR alerts arrive with status RESOLVED or INVALID and do not require actioning. The ACTION_REQUIRED status and the PATCH endpoint for actioning alerts apply to Ethoca alerts only.

    Ethoca alerts in ACTION_REQUIRED status must be actioned. Refunding the transaction alone is not enough to prevent a chargeback. You must also action the alert using the PATCH endpoint so that Ethoca is notified and can stop the dispute. Unactioned alerts provide no value — the chargeback will proceed regardless of whether you refunded the customer. If you have resolution rules configured, matching alerts are resolved automatically. In rare cases, an alert may still appear as ACTION_REQUIRED if the system cannot match the alert to a transaction or cannot process the refund.

    Base URL: https://api.chargebackstop.com/v1/alerts/

    Authentication: Bearer token via API key.

    Required abilities:

    • alerts:read for GET endpoints

    • alerts:write for PATCH endpoints

    Access scope model:

    • Organisation-level keys can access alerts for their own organisation only.

    • Admin partner-group keys can access alerts across all organisations for their partner.

    • Non-admin partner-group keys can access alerts only for organisations assigned to their group.


    Returns a paginated list of alerts accessible to the authenticated key.

    API level: Organisation-level and partner-level Authentication: alerts:read

    Parameter
    Type
    Description
    Code
    Description
    • If both alert_received_at_gte and alert_received_at_lte are sent, alert_received_at_gte must be less than or equal to alert_received_at_lte.

    • Default sort order is newest alert received first (-alert_received_at).


    Returns one alert if it is visible to the authenticated key.

    API level: Organisation-level and partner-level Authentication: alerts:read

    Parameter
    Type
    Description
    Code
    Description
    • The same eligibility rules as list alerts apply.

    • Non-existent alerts return 404 Not found.


    Updates the alert note and/or actions the alert.

    API level: Organisation-level and partner-level Authentication: alerts:write

    Parameter
    Type
    Description

    All fields are optional.

    Field
    Type
    Required
    Description
    Code
    Description
    • This endpoint applies to Ethoca alerts only. Verifi RDR alerts are resolved automatically and cannot be actioned.

    • If note is provided, it is saved on the alert.

    • If action is omitted, only the note is updated.


    Error responses use this shape:

    Memberships

    Manage organisation memberships under your partner account.

    This endpoint set is partner-level only. Organisation API keys cannot access these endpoints.

    Base URL: https://api.chargebackstop.com/v1/memberships/ Authentication: Bearer token via API key.

    Required abilities:

    • memberships:read for GET endpoints

    • memberships:write for POST, PATCH, and DELETE endpoints

    Access scope model:

    • Admin partner-group keys can access memberships across all organisations belonging to their partner.

    • Non-admin partner-group keys can access memberships only in organisations explicitly assigned to their group.

    • Organisation-level keys receive 401 Unauthorised on all endpoints in this API.


    Returns memberships accessible to the authenticated partner-group API key.

    API level: Partner-level only Authentication: memberships:read

    Parameter
    Type
    Description

    Create a new membership for an accessible organisation.

    API level: Partner-level only Authentication: memberships:write

    Field
    Type
    Required
    Validation
    Description

    Retrieve one accessible membership by ID.

    API level: Partner-level only Authentication: memberships:read

    Parameter
    Type
    Description

    Update one accessible membership.

    API level: Partner-level only Authentication: memberships:write

    Parameter
    Type
    Description

    All fields are optional.

    Field
    Type
    Required
    Validation
    Description

    Delete one accessible membership.

    API level: Partner-level only Authentication: memberships:write

    Parameter
    Type
    Description

    204 No Content


    Other business validation codes you may receive:

    Code
    Meaning

    Schema validation errors are also returned as 422 with VALIDATION_* codes.

    Rulesets - developer preview

    Create and manage resolution rulesets and their child rules.

    Base URL: https://api.chargebackstop.com/v1/rulesets/

    Authentication: Bearer token via API key.

    Required abilities:

    • rulesets:read for GET endpoints

    • rulesets:write for POST, PATCH, and DELETE endpoints

    Access scope model:

    • Organisation-level keys can access rulesets for their own organisation only.

    • Admin partner-group keys can access rulesets across all organisations for their partner.

    • Non-admin partner-group keys can access rulesets only for organisations assigned to their group.


    A rule is defined by its type and a parameters object whose shape depends on the type. Each ruleset can contain at most one rule of each type. The same rule types apply to embedded rules on POST /v1/rulesets and to the nested POST / PATCH rule endpoints.

    Matches the transaction amount against a threshold.

    Field
    Type
    Description

    Example parameters:

    Matches the transaction's statement descriptor against one or more entries.

    Field
    Type
    Description

    Each descriptor entry:

    Field
    Type
    Description

    Example parameters:


    Creates one ruleset and optionally creates child rules within the same request.

    API level: Organisation-level and partner-level Authentication: rulesets:write

    Field
    Type
    Description

    Returns a paginated list of accessible rulesets.

    API level: Organisation-level and partner-level Authentication: rulesets:read

    Parameter
    Type
    Description

    Returns one accessible ruleset.

    API level: Organisation-level and partner-level Authentication: rulesets:read


    Updates one accessible ruleset.

    API level: Organisation-level and partner-level Authentication: rulesets:write

    Field
    Type
    Description

    Deletes one accessible ruleset and its child rules.

    API level: Organisation-level and partner-level Authentication: rulesets:write


    Adds one rule to an existing accessible ruleset.

    API level: Organisation-level and partner-level Authentication: rulesets:write

    Field
    Type
    Description

    Returns one accessible rule from an accessible ruleset.

    API level: Organisation-level and partner-level Authentication: rulesets:read


    Updates one accessible rule within an accessible ruleset.

    API level: Organisation-level and partner-level Authentication: rulesets:write

    Field
    Type
    Description

    Deletes one accessible rule from an accessible ruleset.

    API level: Organisation-level and partner-level Authentication: rulesets:write


    string

    Filter by merchant ID

    alert_received_at_gte

    datetime

    Include alerts received at or after this timestamp (ISO 8601, inclusive)

    alert_received_at_lte

    datetime

    Include alerts received at or before this timestamp (ISO 8601, inclusive)

    sort

    string

    Sort field: -alert_received_at (default), alert_received_at, -action_required_deadline, action_required_deadline

    limit

    integer

    Number of results per page

    offset

    integer

    Number of results to skip

    Forbidden — API key lacks alerts:read ability

    422

    Validation error (e.g. invalid date range)

    Forbidden — API key lacks alerts:read ability

    404

    Alert not found

    Customer-facing note saved on the alert

    Forbidden — API key lacks alerts:write ability

    404

    Alert not found

    422

    Validation error (e.g. invalid action, alert already resolved)

    Once an alert is in RESOLVED, it cannot be actioned again.

  • Action values map to available underlying actions at runtime. For detailed behaviour, see Actioning alerts:

    • REFUND prioritises refund actions.

    • CANCEL prioritises cancel/dismiss actions.

    • REFUND_AND_CANCEL prioritises combined refund-and-cancel, then refund-only if combined action is unavailable.

    • ACCEPT_DISPUTE maps to dismissing the alert.

  • status

    string

    Filter by alert status: ACTION_REQUIRED (Ethoca only), RESOLVED, INVALID

    organisation_id

    string

    Filter by organisation ID

    200

    Success

    400

    Invalid request

    401

    Unauthorised

    alert_id

    string

    Alert ID

    200

    Success

    400

    Invalid request

    401

    Unauthorised

    alert_id

    string

    Alert ID to update

    action

    string

    No

    Action to apply: REFUND, CANCEL, REFUND_AND_CANCEL, ACCEPT_DISPUTE

    note

    string

    200

    Success

    400

    Invalid request

    401

    Unauthorised

    GET /v1/alerts - list alerts

    Query parameters

    Response codes

    Important behaviour

    Example 1 request
    Example 1 response

    GET /v1/alerts/{alert_id} - get alert by ID

    URL parameters

    Response codes

    Important behaviour

    Example 2 request
    Example 2 response

    PATCH /v1/alerts/{alert_id} - update alert

    URL parameters

    Request body

    Response codes

    Important behaviour

    Example 3 request
    Example 3 response

    Common error responses

    Example 4: 401 Unauthorised

    Returned for invalid, expired, or missing API keys.

    Example 5: 403 Forbidden

    Returned when the API key is valid but missing required ability.

    Example 6: 404 Not found

    Returned when the alert is not found or not accessible.

    Example 7: 422 Unprocessable Entity (invalid date range)

    Returned when alert_received_at_gte is greater than alert_received_at_lte.

    Example 8: 422 Unprocessable Entity (invalid enum value)

    Returned when action is not one of the supported values.

    Example 9: 422 Unprocessable Entity (resolved alert cannot be actioned)
    Example 10: 422 Unprocessable Entity (no available action)

    Returned when the requested action cannot be mapped to any available action for the alert.

    Example 11: 422 Unprocessable Entity (action execution failed)

    Returned when the underlying action execution is rejected.

    Additional reference: 500 Server error

    Unexpected server-side failures return:

    merchant_id

    403

    403

    No

    403

    integer

    Number of results to skip

    string

    Yes

    Min length 1

    User first name

    last_name

    string

    Yes

    Min length 1

    User last name

    email

    string

    Yes

    Valid email format

    User email

    role

    string

    Yes

    ADMIN or STANDARD

    Membership role

    is_alert_action_required_email_enabled

    boolean

    No

    Defaults to true

    Alert action-required email setting

    is_alert_resolved_email_enabled

    boolean

    No

    Defaults to true

    Alert resolved email setting

    is_alert_dismissed_email_enabled

    boolean

    No

    Defaults to true

    Alert dismissed email setting

    is_evidence_requested_email_enabled

    boolean

    No

    Defaults to true

    Evidence requested email setting

    boolean

    No

    Optional

    Updated alert action-required email setting

    is_alert_resolved_email_enabled

    boolean

    No

    Optional

    Updated alert resolved email setting

    is_alert_dismissed_email_enabled

    boolean

    No

    Optional

    Updated alert dismissed email setting

    is_evidence_requested_email_enabled

    boolean

    No

    Optional

    Updated evidence requested email setting

    organisation_id

    string

    Filter by exact organisation ID

    limit

    integer

    Number of results per page

    organisation_id

    string

    Yes

    Must be accessible by API key

    Organisation that owns the membership

    membership_id

    string

    Membership ID

    membership_id

    string

    Membership ID to update

    role

    string

    No

    ADMIN or STANDARD

    Updated membership role

    membership_id

    string

    Membership ID to delete

    MEMBERSHIP_ALREADY_EXISTS

    A membership for this user and organisation already exists

    MEMBERSHIP_DELETION_FORBIDDEN

    Membership cannot be deleted due to business rules

    GET /v1/memberships - List memberships

    Query parameters

    Results are ordered by created_at descending.

    Example request

    Example response

    POST /v1/memberships - Create membership

    Request body

    • If the user is already a member of the organisation, the API returns 422 with MEMBERSHIP_ALREADY_EXISTS.

    • Notification setting values provided in the request are applied as sent.

    Example request

    Example response

    GET /v1/memberships/{membership_id} - Get membership by ID

    URL parameters

    Example request

    Example response

    PATCH /v1/memberships/{membership_id} - Update membership

    URL parameters

    Request body

    • Only fields included in the request are updated.

    • If no fields are provided, the API returns the existing membership unchanged.

    Example request

    Example response

    DELETE /v1/memberships/{membership_id} - Delete membership

    URL parameters

    Example request

    Example response

    Common error responses

    400 Invalid request

    Returned when a membership cannot be created for the target user (for example, a staff user).

    401 Unauthorised

    Returned for invalid or expired API keys, and for organisation-level keys calling this partner-only API.

    403 Forbidden (missing ability)

    Returned when the API key is valid but missing required ability (memberships:read or memberships:write).

    404 Not found

    Returned when the membership is not found or outside the key's accessible scope.

    422 Unprocessable Entity (membership already exists)
    422 Unprocessable Entity (membership deletion forbidden)

    offset

    first_name

    is_alert_action_required_email_enabled

    {
      "errors": [
        {
          "code": "ERROR_CODE",
          "message": "Human-readable message"
        }
      ]
    }
    curl -X GET "https://api.chargebackstop.com/v1/alerts/?status=ACTION_REQUIRED&sort=-alert_received_at&limit=20&offset=0" \
      -H "Authorization: Bearer <api_key>"
    {
      "items": [
        {
          "id": "netalrt_abc123",
          "alert_network_id": "1234567890",
          "organisation_id": "org_xyz456",
          "merchant_id": "mrch_abc123",
          "enrolment_id": "enrl_def456",
          "enrolment_type": "ETHOCA_ALERT",
          "status": "ACTION_REQUIRED",
          "chargeback_reason_code": "10.4",
          "transaction_amount_in_cents": 4999,
          "transaction_currency_code": "USD",
          "transaction_authorised_at": "2026-02-10T10:30:00Z",
          "action_required_deadline": "2026-02-17T10:30:00Z",
          "transaction_authorisation_code": "ABC123",
          "transaction_acquirer_reference_number": "74027012345678901234567",
          "transaction_statement_descriptor": "EXAMPLE STORE",
          "transaction_card_bin": "424242",
          "transaction_card_last4": "4242",
          "transaction_card_scheme": "VISA",
          "transaction_card_issuer": "Example Bank",
          "transaction_refund_outcome": null,
          "transaction_network_id": null,
          "subscription_cancel_outcome": null,
          "note": "Customer requested immediate review",
          "created_at": "2026-02-11T10:30:00Z",
          "updated_at": "2026-02-11T10:30:00Z",
          "integration_id": null,
          "integration_transaction_id": null,
          "links": [
            {
              "rel": "self",
              "uri": "/v1/alerts/netalrt_abc123"
            }
          ]
        }
      ],
      "count": 1
    }
    curl -X GET "https://api.chargebackstop.com/v1/alerts/netalrt_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "netalrt_abc123",
      "alert_network_id": "1234567890",
      "organisation_id": "org_xyz456",
      "merchant_id": "mrch_abc123",
      "enrolment_id": "enrl_def456",
      "enrolment_type": "ETHOCA_ALERT",
      "status": "ACTION_REQUIRED",
      "chargeback_reason_code": "10.4",
      "transaction_amount_in_cents": 4999,
      "transaction_currency_code": "USD",
      "transaction_authorised_at": "2026-02-10T10:30:00Z",
      "action_required_deadline": "2026-02-17T10:30:00Z",
      "transaction_authorisation_code": "ABC123",
      "transaction_acquirer_reference_number": "74027012345678901234567",
      "transaction_statement_descriptor": "EXAMPLE STORE",
      "transaction_card_bin": "424242",
      "transaction_card_last4": "4242",
      "transaction_card_scheme": "VISA",
      "transaction_card_issuer": "Example Bank",
      "transaction_refund_outcome": null,
      "transaction_network_id": null,
      "subscription_cancel_outcome": null,
      "note": "Customer requested immediate review",
      "created_at": "2026-02-11T10:30:00Z",
      "updated_at": "2026-02-11T10:30:00Z",
      "integration_id": null,
      "integration_transaction_id": null,
      "links": [
        {
          "rel": "self",
          "uri": "/v1/alerts/netalrt_abc123"
        }
      ]
    }
    curl -X PATCH "https://api.chargebackstop.com/v1/alerts/netalrt_abc123" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "action": "ACCEPT_DISPUTE",
        "note": "We decided to accept this dispute"
      }'
    {
      "id": "netalrt_abc123",
      "alert_network_id": "1234567890",
      "organisation_id": "org_xyz456",
      "merchant_id": "mrch_abc123",
      "enrolment_id": "enrl_def456",
      "enrolment_type": "ETHOCA_ALERT",
      "status": "RESOLVED",
      "chargeback_reason_code": "10.4",
      "transaction_amount_in_cents": 4999,
      "transaction_currency_code": "USD",
      "transaction_authorised_at": "2026-02-10T10:30:00Z",
      "action_required_deadline": "2026-02-17T10:30:00Z",
      "transaction_authorisation_code": "ABC123",
      "transaction_acquirer_reference_number": "74027012345678901234567",
      "transaction_statement_descriptor": "EXAMPLE STORE",
      "transaction_card_bin": "424242",
      "transaction_card_last4": "4242",
      "transaction_card_scheme": "VISA",
      "transaction_card_issuer": "Example Bank",
      "transaction_refund_outcome": "NOT_REFUNDED",
      "transaction_network_id": null,
      "subscription_cancel_outcome": null,
      "note": "We decided to accept this dispute",
      "created_at": "2026-02-11T10:30:00Z",
      "updated_at": "2026-02-11T10:32:00Z",
      "integration_id": null,
      "integration_transaction_id": null,
      "links": [
        {
          "rel": "self",
          "uri": "/v1/alerts/netalrt_abc123"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "UNAUTHORISED",
          "message": "Unauthorised"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "INVALID_DATE_RANGE",
          "message": "alert_received_at_gte cannot be greater than alert_received_at_lte"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "VALIDATION_ENUM",
          "message": "Validation error at ('body', 'update', 'action'). Input should be 'REFUND', 'CANCEL', 'REFUND_AND_CANCEL' or 'ACCEPT_DISPUTE'."
        }
      ]
    }
    {
      "errors": [
        {
          "code": "INVALID_ACTION",
          "message": "Failed to update netalrt_abc123 alert. This alert is in RESOLVED status and cannot be actioned."
        }
      ]
    }
    {
      "errors": [
        {
          "code": "INVALID_ACTION",
          "message": "Failed to update netalrt_abc123 alert. No available action found."
        }
      ]
    }
    {
      "errors": [
        {
          "code": "ACTION_FAILED",
          "message": "Failed to update netalrt_abc123 alert. The requested action is not allowed."
        }
      ]
    }
    {
      "errors": [
        {
          "code": "SERVER_ERROR",
          "message": "Server error"
        }
      ]
    }
    curl -X GET "https://api.chargebackstop.com/v1/memberships/?organisation_id=org_xyz456&limit=20&offset=0" \
      -H "Authorization: Bearer <api_key>"
    {
      "items": [
        {
          "id": "mem_abc123",
          "organisation_id": "org_xyz456",
          "user_id": "usr_aaa111",
          "first_name": "John",
          "last_name": "Doe",
          "email": "[email protected]",
          "role": "ADMIN",
          "is_alert_action_required_email_enabled": true,
          "is_alert_resolved_email_enabled": true,
          "is_alert_dismissed_email_enabled": true,
          "is_evidence_requested_email_enabled": true,
          "created_at": "2026-02-10T09:30:00Z",
          "updated_at": "2026-02-10T09:30:00Z",
          "links": [
            {
              "rel": "self",
              "uri": "/v1/memberships/mem_abc123"
            }
          ]
        },
        {
          "id": "mem_def456",
          "organisation_id": "org_xyz456",
          "user_id": "usr_bbb222",
          "first_name": "Jane",
          "last_name": "Smith",
          "email": "[email protected]",
          "role": "STANDARD",
          "is_alert_action_required_email_enabled": true,
          "is_alert_resolved_email_enabled": false,
          "is_alert_dismissed_email_enabled": false,
          "is_evidence_requested_email_enabled": true,
          "created_at": "2026-02-08T15:12:44Z",
          "updated_at": "2026-02-08T15:12:44Z",
          "links": [
            {
              "rel": "self",
              "uri": "/v1/memberships/mem_def456"
            }
          ]
        }
      ],
      "count": 2
    }
    curl -X POST "https://api.chargebackstop.com/v1/memberships/" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_xyz456",
        "first_name": "Alice",
        "last_name": "Johnson",
        "email": "[email protected]",
        "role": "ADMIN",
        "is_alert_action_required_email_enabled": true,
        "is_alert_resolved_email_enabled": false,
        "is_alert_dismissed_email_enabled": true,
        "is_evidence_requested_email_enabled": true
      }'
    {
      "id": "mem_new123",
      "organisation_id": "org_xyz456",
      "user_id": "usr_new123",
      "first_name": "Alice",
      "last_name": "Johnson",
      "email": "[email protected]",
      "role": "ADMIN",
      "is_alert_action_required_email_enabled": true,
      "is_alert_resolved_email_enabled": false,
      "is_alert_dismissed_email_enabled": true,
      "is_evidence_requested_email_enabled": true,
      "created_at": "2026-02-16T12:00:00Z",
      "updated_at": "2026-02-16T12:00:00Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/memberships/mem_new123"
        }
      ]
    }
    curl -X GET "https://api.chargebackstop.com/v1/memberships/mem_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "mem_abc123",
      "organisation_id": "org_xyz456",
      "user_id": "usr_aaa111",
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "role": "ADMIN",
      "is_alert_action_required_email_enabled": true,
      "is_alert_resolved_email_enabled": true,
      "is_alert_dismissed_email_enabled": true,
      "is_evidence_requested_email_enabled": true,
      "created_at": "2026-02-10T09:30:00Z",
      "updated_at": "2026-02-16T09:05:00Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/memberships/mem_abc123"
        }
      ]
    }
    curl -X PATCH "https://api.chargebackstop.com/v1/memberships/mem_abc123" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "role": "STANDARD",
        "is_alert_resolved_email_enabled": false,
        "is_alert_dismissed_email_enabled": false
      }'
    {
      "id": "mem_abc123",
      "organisation_id": "org_xyz456",
      "user_id": "usr_aaa111",
      "first_name": "John",
      "last_name": "Doe",
      "email": "[email protected]",
      "role": "STANDARD",
      "is_alert_action_required_email_enabled": true,
      "is_alert_resolved_email_enabled": false,
      "is_alert_dismissed_email_enabled": false,
      "is_evidence_requested_email_enabled": true,
      "created_at": "2026-02-10T09:30:00Z",
      "updated_at": "2026-02-16T12:10:00Z",
      "links": [
        {
          "rel": "self",
          "uri": "/v1/memberships/mem_abc123"
        }
      ]
    }
    curl -X DELETE "https://api.chargebackstop.com/v1/memberships/mem_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "errors": [
        {
          "code": "INVALID_REQUEST",
          "message": "Invalid request"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "UNAUTHORISED",
          "message": "Unauthorised"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "MEMBERSHIP_ALREADY_EXISTS",
          "message": "A user with this email is already a member of this organisation"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "MEMBERSHIP_DELETION_FORBIDDEN",
          "message": "This membership cannot be deleted"
        }
      ]
    }

    integer

    Non-negative amount in cents.

    string

    REFUND, CANCEL, REFUND_AND_CANCEL, or ACCEPT_DISPUTE

    join_operator

    string

    AND or OR

    rules

    array[object]

    Optional initial rules. Each entry has type and parameters — see .

    integer

    Number of results per page

    offset

    integer

    Number of results to skip

    string

    Optional. AND or OR

    operator

    string

    GREATER_THAN, GREATER_THAN_OR_EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, EQUAL, or NOT_EQUAL

    currency_code

    string

    Three-letter currency code. Must be USD.

    {
      "operator": "GREATER_THAN",
      "currency_code": "USD",
      "amount_in_cents": 5000
    }

    descriptors

    array[object]

    One or more descriptor entries

    value

    string

    Descriptor string to match against.

    match_type

    string

    STARTS_WITH or EXACT_MATCH

    {
      "descriptors": [
        {"value": "NETFLIX", "match_type": "STARTS_WITH"},
        {"value": "SPOTIFY", "match_type": "EXACT_MATCH"}
      ]
    }

    organisation_id

    string

    Organisation ID

    enrolment_ids

    array[string]

    One or more enrolment IDs

    curl -X POST "https://api.chargebackstop.com/v1/rulesets/" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_xyz456",
        "enrolment_ids": ["enrl_abc123", "enrl_def456"],
        "outcome": "REFUND",
        "join_operator": "AND",
        "rules": [
          {
            "type": "DESCRIPTOR",
            "parameters": {
              "descriptors": [
                {"value": "NETFLIX", "match_type": "STARTS_WITH"},
                {"value": "SPOTIFY", "match_type": "STARTS_WITH"}
              ]
            }
          },
          {
            "type": "AMOUNT",
            "parameters": {
              "operator": "GREATER_THAN",
              "currency_code": "USD",
              "amount_in_cents": 5000
            }
          }
        ]
      }'
    {
      "id": "rset_abc123",
      "organisation_id": "org_xyz456",
      "enrolment_ids": ["enrl_abc123", "enrl_def456"],
      "outcome": "REFUND",
      "join_operator": "AND",
      "rules": [
        {
          "id": "resrule_desc123",
          "type": "DESCRIPTOR",
          "parameters": {
            "descriptors": [
              {"value": "NETFLIX", "match_type": "STARTS_WITH"},
              {"value": "SPOTIFY", "match_type": "STARTS_WITH"}
            ]
          },
          "created_at": "2026-05-05T10:00:00Z",
          "updated_at": "2026-05-05T10:00:00Z"
        },
        {
          "id": "resrule_amt123",
          "type": "AMOUNT",
          "parameters": {
            "operator": "GREATER_THAN",
            "currency_code": "USD",
            "amount_in_cents": 5000
          },
          "created_at": "2026-05-05T10:00:00Z",
          "updated_at": "2026-05-05T10:00:00Z"
        }
      ],
      "created_at": "2026-05-05T10:00:00Z",
      "updated_at": "2026-05-05T10:00:00Z"
    }

    organisation_id

    string

    Filter by organisation ID

    sort

    string

    -created_at (default), created_at, -updated_at, or updated_at

    curl -X GET "https://api.chargebackstop.com/v1/rulesets/?organisation_id=org_xyz456&sort=-created_at&limit=20&offset=0" \
      -H "Authorization: Bearer <api_key>"
    {
      "items": [
        {
          "id": "rset_def456",
          "organisation_id": "org_xyz456",
          "enrolment_ids": ["enrl_abc123", "enrl_def456"],
          "outcome": "REFUND",
          "join_operator": "AND",
          "rules": [],
          "created_at": "2026-05-05T10:00:00Z",
          "updated_at": "2026-05-05T10:00:00Z"
        }
      ],
      "count": 1
    }
    curl -X GET "https://api.chargebackstop.com/v1/rulesets/rset_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "rset_abc123",
      "organisation_id": "org_xyz456",
      "enrolment_ids": ["enrl_abc123"],
      "outcome": "ACCEPT_DISPUTE",
      "join_operator": "AND",
      "rules": [
        {
          "id": "resrule_amt123",
          "type": "AMOUNT",
          "parameters": {
            "operator": "GREATER_THAN",
            "currency_code": "USD",
            "amount_in_cents": 5000
          },
          "created_at": "2026-05-05T10:00:00Z",
          "updated_at": "2026-05-05T10:00:00Z"
        }
      ],
      "created_at": "2026-05-05T10:00:00Z",
      "updated_at": "2026-05-05T10:00:00Z"
    }

    enrolment_ids

    array[string]

    Optional. One or more enrolment IDs

    outcome

    string

    Optional. REFUND, CANCEL, REFUND_AND_CANCEL, or ACCEPT_DISPUTE

    curl -X PATCH "https://api.chargebackstop.com/v1/rulesets/rset_abc123" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "enrolment_ids": ["enrl_abc123", "enrl_def456"],
        "outcome": "CANCEL",
        "join_operator": "OR"
      }'
    {
      "id": "rset_abc123",
      "organisation_id": "org_xyz456",
      "enrolment_ids": ["enrl_abc123", "enrl_def456"],
      "outcome": "CANCEL",
      "join_operator": "OR",
      "rules": [],
      "created_at": "2026-05-05T10:00:00Z",
      "updated_at": "2026-05-05T10:00:00Z"
    }
    curl -X DELETE "https://api.chargebackstop.com/v1/rulesets/rset_abc123" \
      -H "Authorization: Bearer <api_key>"
    204 No Content

    type

    string

    AMOUNT or DESCRIPTOR. See Rule types.

    parameters

    object

    Parameters for the selected rule type. See Rule types.

    curl -X POST "https://api.chargebackstop.com/v1/rulesets/rset_abc123/rules" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "type": "AMOUNT",
        "parameters": {
          "operator": "GREATER_THAN",
          "currency_code": "USD",
          "amount_in_cents": 5000
        }
      }'
    {
      "id": "resrule_amt123",
      "type": "AMOUNT",
      "parameters": {
        "operator": "GREATER_THAN",
        "currency_code": "USD",
        "amount_in_cents": 5000
      },
      "created_at": "2026-05-05T10:00:00Z",
      "updated_at": "2026-05-05T10:00:00Z"
    }
    curl -X GET "https://api.chargebackstop.com/v1/rulesets/rset_abc123/rules/resrule_amt123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "resrule_amt123",
      "type": "AMOUNT",
      "parameters": {
        "operator": "GREATER_THAN",
        "currency_code": "USD",
        "amount_in_cents": 5000
      },
      "created_at": "2026-05-05T10:00:00Z",
      "updated_at": "2026-05-05T10:00:00Z"
    }

    type

    string

    Must match the existing rule type. See Rule types.

    parameters

    object

    Parameters for the selected rule type. See Rule types.

    curl -X PATCH "https://api.chargebackstop.com/v1/rulesets/rset_abc123/rules/resrule_amt123" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "type": "AMOUNT",
        "parameters": {
          "operator": "GREATER_THAN",
          "currency_code": "USD",
          "amount_in_cents": 7500
        }
      }'
    {
      "id": "resrule_amt123",
      "type": "AMOUNT",
      "parameters": {
        "operator": "GREATER_THAN",
        "currency_code": "USD",
        "amount_in_cents": 7500
      },
      "created_at": "2026-05-05T10:00:00Z",
      "updated_at": "2026-05-05T10:00:00Z"
    }
    curl -X DELETE "https://api.chargebackstop.com/v1/rulesets/rset_abc123/rules/resrule_amt123" \
      -H "Authorization: Bearer <api_key>"
    204 No Content
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "INVALID_CURRENCY_CODE",
          "message": "Only USD is allowed.",
          "field": "currency_code"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "RULES_NOT_ALLOWED_ON_RULESET_UPDATE",
          "message": "Rules cannot be updated via this endpoint. Use PATCH /v1/rulesets/{ruleset_id}/rules/{rule_id} instead.",
          "field": "rules"
        }
      ]
    }

    Rule types

    AMOUNT

    Only USD is accepted as the rule currency. If a transaction is in a different currency, its amount is automatically converted to USD before the rule is evaluated, so the rule still applies to non-USD transactions.

    DESCRIPTOR

    POST /v1/rulesets - create ruleset

    Request body

    All selected enrolments must be accessible and must share the same enrolment type. For example, you cannot combine Ethoca and Verifi RDR enrolments in the same ruleset. If you need the same rules to apply to both, create one ruleset per enrolment type.

    Only one rule of each type is allowed per ruleset.

    Amount rules must use USD.

    If any embedded rule fails validation, the entire ruleset creation is rolled back.

    Example 1 request

    Example 1 response

    GET /v1/rulesets - list rulesets

    Query parameters

    Example 2 request

    Example 2 response

    GET /v1/rulesets/{ruleset_id} - get ruleset by ID

    Example 3 request

    Example 3 response

    PATCH /v1/rulesets/{ruleset_id} - update ruleset

    Request body

    Send only the mutable fields you want to change. Omitted fields keep their existing values.

    rules is not accepted on this endpoint. Update child rules through the nested rule endpoints instead.

    All selected enrolments must be accessible and must share the same enrolment type. For example, you cannot combine Ethoca and Verifi RDR enrolments in the same ruleset.

    Example 4 request

    Example 4 response

    DELETE /v1/rulesets/{ruleset_id} - delete ruleset

    The response body is empty on success.

    Example 5 request

    Example 5 response

    POST /v1/rulesets/{ruleset_id}/rules - add rule

    Request body

    Only one rule of each type is allowed per ruleset.

    Amount rules must use USD.

    Example 6 request

    Example 6 response

    GET /v1/rulesets/{ruleset_id}/rules/{rule_id} - get rule by ID

    Example 7 request

    Example 7 response

    PATCH /v1/rulesets/{ruleset_id}/rules/{rule_id} - update rule

    Request body

    Rule type cannot be changed.

    Amount rules must use USD.

    Example 8 request

    Example 8 response

    DELETE /v1/rulesets/{ruleset_id}/rules/{rule_id} - delete rule

    The response body is empty on success.

    Example 9 request

    Example 9 response

    Error examples

    Example 10: forbidden

    Example 11: not found

    Example 12: invalid currency

    Example 13: rules not allowed on ruleset update

    amount_in_cents

    outcome

    limit

    join_operator

    Simulations

    Generate test enrolment states, test alerts, and test scheme notices for TEST mode organisations.

    Base URL: https://api.chargebackstop.com/v1/simulate/

    Authentication: Bearer token via API key.

    Required abilities:

    • simulations:enrollments for PATCH /v1/simulate/enrolments/{enrolment_id}

    Rule types
  • simulations:alerts for POST /v1/simulate/alerts

  • simulations:lookups for POST /v1/simulate/lookups

  • simulations:scheme_notices for POST /v1/simulate/scheme-notices

  • Access scope model:

    • Organisation-level keys can simulate data for their own organisation only.

    • Admin partner-group keys can simulate data across all organisations for their partner.

    • Non-admin partner-group keys can simulate data only for organisations assigned to their group.

    Typical simulation flow:

    1

    Create an enrolment

    Create an enrolment with /v2/enrolments.

    2

    Enable the enrolment for simulation

    Set that enrolment to ENABLED with:

    PATCH /v1/simulate/enrolments/{enrolment_id}

    3

    Generate a simulated alert

    Generate a simulated alert with POST /v1/simulate/alerts.

    4

    Generate a simulated lookup

    Generate a simulated lookup with POST /v1/simulate/lookups.

    5

    Generate a simulated scheme notice

    Generate a simulated scheme notice with POST /v1/simulate/scheme-notices.


    Updates an enrolment status for simulation use.

    API level: Organisation-level and partner-level Authentication: simulations:enrollments

    Parameter
    Type
    Description

    enrolment_id

    string

    Enrolment ID to update

    Field
    Type
    Required
    Description

    status

    string

    Yes

    New enrolment status: ENABLED or UNENROLLED

    • This endpoint is only available for TEST mode organisations.

    • The enrolment must be accessible to the authenticated API key.

    • For ETHOCA_ALERT enrolments, setting status to ENABLED activates configured descriptors for simulation matching.


    Creates a simulated network alert.

    API level: Organisation-level and partner-level Authentication: simulations:alerts

    Field
    Type
    Required
    Description

    organisation_id

    string

    Yes

    Organisation ID. Must be in TEST mode and accessible to the key

    enrolment_id

    string

    • This endpoint is only available for TEST mode organisations.

    • The enrolment must be an alert enrolment: ETHOCA_ALERT or VERIFI_RDR.

    • If status is omitted, the simulator chooses a valid status.

    • If transaction_refund_outcome is provided without status, the created alert is set to RESOLVED.

    • Simulated alerts trigger the same alert.created event flow as non-simulated alerts.


    Creates a simulated lookup.

    API level: Organisation-level and partner-level Authentication: simulations:lookups

    Field
    Type
    Required
    Description

    organisation_id

    string

    Yes

    Organisation ID. Must be in TEST mode and accessible to the key

    enrollment_id

    string

    • This endpoint is only available for TEST mode organisations.

    • The enrollment must be a lookup enrolment: ETHOCA_CONSUMER_CLARITY or VERIFI_ORDER_INSIGHT.

    • If lookup_status is omitted, the simulator uses SUCCEEDED.

    • If deflection_status is omitted, the simulator uses NOT_ATTEMPTED.

    • The simulator also stores a standard response summary on the lookup record for downstream UI and internal testing use.

    • Simulated lookups trigger the same lookup.created event flow as non-simulated lookups.

    • Simulated lookups do not create billing events or request-response records.


    Creates a simulated scheme notice.

    API level: Organisation-level and partner-level Authentication: simulations:scheme_notices

    Field
    Type
    Required
    Description

    organisation_id

    string

    Yes

    Organisation ID. Must be in TEST mode and accessible to the key

    scheme_notice_type

    string

    • This endpoint is only available for TEST mode organisations.

    • If scheme_notice_type is omitted, the simulator chooses a valid notice type.

    • TC15 simulations use Verifi dispute-notice semantics: notice_type=DISPUTE_NOTICE, scheme=VISA.

    • Simulated scheme notices trigger the same scheme_notice.created event flow as non-simulated scheme notices.

    • The response uses the standard public scheme-notice payload, including fraud_reported_at.


    Error responses use this shape:

    curl -X PATCH "https://api.chargebackstop.com/v1/simulate/enrolments/enrl_abc456" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "status": "ENABLED"
      }'
    {
      "id": "enrl_abc456",
      "organisation_id": "org_test123",
      "merchant_ids": ["mrch_abc123"],
      "type": "ETHOCA_ALERT",
      "status": "ENABLED",
      "ethoca_alert": {
        "descriptors": [
          {
            "descriptor": "TESTMERCHANT.COM",
            "match_type": "EXACT_MATCH"
          }
        ]
      },
      "verifi_rdr": null,
      "created_at": "2026-02-10T12:00:00Z",
      "updated_at": "2026-02-16T08:15:00Z",
      "note": null,
      "links": [
        {
          "rel": "self",
          "uri": "/v2/enrolments/enrl_abc456"
        }
      ]
    }
    curl -X POST "https://api.chargebackstop.com/v1/simulate/alerts" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_test123",
        "enrolment_id": "enrl_abc456",
        "status": "RESOLVED",
        "transaction_refund_outcome": "REFUNDED",
        "card_scheme": "VISA",
        "amount_in_cents": 5000,
        "currency_code": "USD"
      }'
    {
      "id": "netalrt_xyz789",
      "alert_network_id": "SIM123456",
      "organisation_id": "org_test123",
      "merchant_id": "mrch_abc123",
      "enrolment_id": "enrl_abc456",
      "enrolment_type": "ETHOCA_ALERT",
      "status": "RESOLVED",
      "chargeback_reason_code": null,
      "transaction_amount_in_cents": 5000,
      "transaction_currency_code": "USD",
      "transaction_authorised_at": "2026-02-10T10:30:00Z",
      "action_required_deadline": null,
      "transaction_authorisation_code": "ABC123",
      "transaction_acquirer_reference_number": "12345678901234567890123",
      "transaction_statement_descriptor": "TESTMERCHANT.COM",
      "transaction_card_bin": "400000",
      "transaction_card_last4": "1234",
      "transaction_card_scheme": "VISA",
      "transaction_card_issuer": "Bank of America",
      "transaction_refund_outcome": "REFUNDED",
      "transaction_network_id": null,
      "subscription_cancel_outcome": null,
      "note": null,
      "created_at": "2026-02-16T08:20:00Z",
      "updated_at": "2026-02-16T08:20:00Z",
      "integration_id": null,
      "integration_transaction_id": null
    }
    curl -X POST "https://api.chargebackstop.com/v1/simulate/lookups" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_test123",
        "enrollment_id": "enrl_abc456",
        "type": "ETHOCA_CONSUMER_CLARITY",
        "lookup_status": "SUCCEEDED",
        "deflection_status": "NOT_ATTEMPTED",
        "card_scheme": "VISA",
        "amount_in_cents": 5000,
        "currency_code": "USD",
        "transaction_acquirer_reference_number": "12345678901234567890123",
        "transaction_authorisation_code": "ABC123"
      }'
    {
      "id": "lkup_xyz789",
      "organisation_id": "org_test123",
      "enrollment_id": "enrl_abc456",
      "type": "ETHOCA_CONSUMER_CLARITY",
      "parent_lookup_id": null,
      "lookup_status": "SUCCEEDED",
      "deflection_status": "NOT_ATTEMPTED",
      "transaction_card_bin": "411111",
      "transaction_card_last4": "1234",
      "transaction_arn": "12345678901234567890123",
      "transaction_auth_code": "ABC123",
      "transaction_amount": 5000,
      "transaction_currency": "USD",
      "transaction_date": "2026-02-16T08:20:00Z",
      "transaction_statement_descriptor": "ETHOCA TEST LOOKUP",
      "transaction_network_id": null,
      "integration_id": null,
      "integration_transaction_id": null,
      "created_at": "2026-02-16T08:20:00Z",
      "updated_at": "2026-02-16T08:20:00Z"
    }
    curl -X POST "https://api.chargebackstop.com/v1/simulate/scheme-notices" \
      -H "Authorization: Bearer <api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_test123",
        "scheme_notice_type": "TC15",
        "transaction_amount_in_cents": 5000,
        "transaction_currency_code": "USD",
        "reported_at": "2026-02-16T08:20:00Z"
      }'
    {
      "id": "schntc_xyz789",
      "organisation_id": "org_test123",
      "merchant_id": null,
      "scheme_notice_type": "TC15",
      "notice_type": "DISPUTE_NOTICE",
      "scheme": "VISA",
      "is_revoked": false,
      "notice_revoked_at": null,
      "fraud_reported_at": "2026-02-16T08:20:00Z",
      "transaction_amount_in_cents": 5000,
      "transaction_currency_code": "USD",
      "transaction_card_bin": "411111",
      "transaction_card_last4": "1111",
      "transaction_merchant_name": "ECOM-STUFF.COM",
      "transaction_merchant_id": "003500935000093",
      "transaction_acquirer_reference_number": "12345678901234567890123",
      "transaction_authorisation_code": "ABC123",
      "transaction_original_date": "2026-02-01T08:20:00Z",
      "transaction_purchase_date": null,
      "fraud_type": null,
      "fraud_dispute_eligible": null,
      "created_at": "2026-02-16T08:20:00Z",
      "updated_at": "2026-02-16T08:20:00Z"
    }
    {
      "errors": [
        {
          "code": "ERROR_CODE",
          "message": "Human-readable message"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "UNAUTHORISED",
          "message": "Unauthorised"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "SIMULATION_NOT_ALLOWED",
          "message": "Alert simulation is only allowed for TEST mode organisations. Production Org is in LIVE mode."
        }
      ]
    }
    {
      "errors": [
        {
          "code": "SIMULATION_VALIDATION_ERROR",
          "message": "Invalid currency_code 'INVALID'. Must be a valid ISO 4217 code."
        }
      ]
    }
    {
      "errors": [
        {
          "code": "SIMULATION_VALIDATION_ERROR",
          "message": "Invalid scheme_notice_type 'INVALID'. Must be TC15, TC40, or SAFE."
        }
      ]
    }
    {
      "errors": [
        {
          "code": "VALIDATION_ENUM",
          "message": "Validation error at ('body', 'data', 'status'). Input should be 'ENABLED' or 'UNENROLLED'."
        }
      ]
    }
    {
      "errors": [
        {
          "code": "SERVER_ERROR",
          "message": "Server error"
        }
      ]
    }

    PATCH /v1/simulate/enrolments/{enrolment_id} - update enrolment simulation status

    URL parameters

    Request body

    Important behaviour

    Example 1 request

    Example 1 response

    POST /v1/simulate/alerts - create simulated alert

    Request body

    Important behaviour

    Example 2 request

    Example 2 response

    POST /v1/simulate/lookups - create simulated lookup

    Request body

    Important behaviour

    Example 4 request

    Example 4 response

    POST /v1/simulate/scheme-notices - create simulated scheme notice

    Request body

    Important behaviour

    Example 3 request

    Example 3 response

    Common error responses

    Example 4: 401 Unauthorised

    Example 5: 403 Forbidden

    Example 6: 404 Not found

    Example 7: 422 Unprocessable Entity (simulation not allowed)

    Example 8: 422 Unprocessable Entity (simulation validation error)

    Example 9: 422 Unprocessable Entity (scheme notice validation error)

    Example 10: 422 Unprocessable Entity (invalid enum value)

    Additional reference: 500 Server error

    Partner SSO

    If you're a ChargebackStop Partner you're able to integrate custom SSO for your users to easily authenticate into their organisations from your application, no re-authentication required.

    Note that this is not for integrating enterprise SSO providers such as Okta or Azure AD for partner or merchant accounts, if you want to enable enterprise SSO login options please contact support.

    These are instructions on how to generate Single Sign-On tokens on your server. These token can be used to authenticate your users into our merchant dashboard for your organisations.

    1. Generate your Partner SSO Key

    You can do this by logging into your partner dashboard and under Settings > Single Sign-On (SSO) for Organisations and generate a key. Store this key in a secure environment variable on your server. Do not expose this key in any frontend interface.

    2. Get your Partner ID

    From your partner dashboard grab the first ID in the URL. For example:

    https://dashboard.chargebackstop.com/partners/ptnr_T1Ng7EgYrY7uaKMgPsASE/settings

    In this case ptnr_T1Ng7EgYrY7uaKMgPsASE would be your Partner ID.

    3. Generate your SSO Token

    You can do this using all major programming languages, see below for common examples:

    1

    We use JSON Web Tokens to securely authenticate your users. First, install the appropriate JWT library for your server.

    2

    These tokens must be used within 15 minutes of issuance (UTC timezone)

    Your user must already be a member of an organisation with your partner account. If the user is not a member the SSO will fail, and due to security implications you cannot SSO a user that is a member of an organisation outside of your partner account.

    Your Base URL will be either https://dashboard.chargebackstop.com, or your own white label instance such https://chargebacks.example.com, make sure to redirect your customer to the right one.

    Your Partner ID will be the ID we retrieved earlier such as ptnr_T1Ng7EgYrY7uaKMgPsASE

    Your SSO Token will be the token we generated above. You need to generate this token each time.

    Putting it all together

    For example

    https://dashboard.chargebackstop.com/auth/partner-organisation-sso?partner_id=ptnr_T1Ng7xxxxx&token=eyJhbGciOiJIUzI1NiIsInR5cCIyyyyy

    If you have any questions, please let our customer success team know and we'll do our best to help you.

    Yes

    Enrolment ID that belongs to organisation_id and is an alert enrolment (ETHOCA_ALERT or VERIFI_RDR)

    status

    string

    No

    Alert status: ACTION_REQUIRED, RESOLVED, INVALID. Verifi RDR only supports RESOLVED or INVALID

    transaction_refund_outcome

    string

    No

    Refund outcome: REFUNDED or NOT_REFUNDED. Only valid with status=RESOLVED

    card_scheme

    string

    No

    Card scheme. Use any supported scheme value, for example VISA, MASTERCARD, AMEX

    amount_in_cents

    integer

    No

    Transaction amount in cents. Must be a positive integer

    currency_code

    string

    No

    ISO 4217 currency code, for example USD, EUR, GBP

    transaction_acquirer_reference_number

    string

    No

    ARN. Must be exactly 23 characters

    transaction_authorisation_code

    string

    No

    Authorisation code. Must be exactly 6 characters

    Yes

    Enrollment ID that belongs to organisation_id and is a lookup enrolment (ETHOCA_CONSUMER_CLARITY or VERIFI_ORDER_INSIGHT)

    type

    string

    Yes

    Lookup type: ETHOCA_CONSUMER_CLARITY, ETHOCA_FIRST_PARTY_TRUST, VERIFI_ORDER_INSIGHT, VERIFI_COMPELLING_EVIDENCE_3

    parent_lookup_id

    string

    No

    Existing lookup ID in the same organisation

    lookup_status

    string

    No

    Lookup status: PENDING, SUCCEEDED, FAILED, TIMEOUT

    deflection_status

    string

    No

    Deflection status: NOT_ATTEMPTED, PENDING, SUCCEEDED, FAILED

    card_scheme

    string

    No

    Card scheme. Use any supported scheme value, for example VISA, MASTERCARD, AMEX

    amount_in_cents

    integer

    No

    Transaction amount in cents. Must be a positive integer

    currency_code

    string

    No

    ISO 4217 currency code, for example USD, EUR, GBP

    transaction_acquirer_reference_number

    string

    No

    ARN. Must be exactly 23 characters

    transaction_authorisation_code

    string

    No

    Authorisation code. Must be exactly 6 characters

    No

    Scheme notice type: TC15, TC40, or SAFE

    transaction_amount_in_cents

    integer

    No

    Transaction amount in cents. Must be a positive integer

    transaction_currency_code

    string

    No

    ISO 4217 currency code, for example USD, EUR, GBP

    reported_at

    datetime

    No

    Reported timestamp in ISO 8601 format

    using System;
    using System.IdentityModel.Tokens.Jwt;
    using System.Text;
    using Microsoft.IdentityModel.Tokens;
    using System.Security.Claims;
    
    public class JwtTokenGenerator
    {
        private const string PrivateKey = "YOUR_PRIVATE_PARTNER_SSO_KEY";
    
        public static string CreateChargebackstopSsoToken(string email)
        {
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(PrivateKey));
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
    
            var claims = new[]
            {
                new Claim("user_email", email),
                new Claim(JwtRegisteredClaimNames.Iat, 
                    new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
            };
    
            var token = new JwtSecurityToken(
                claims: claims,
                signingCredentials: credentials);
    
            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
    
    package main
    
    import (
    	"fmt"
    	"time"
    
    	"github.com/golang-jwt/jwt"
    )
    
    var privateKey = []byte("YOUR_PRIVATE_PARTNER_SSO_KEY")
    
    func createChargebackstopSsoToken(email string) (string, error) {
    	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
    		"iat":        time.Now().Unix(),
    		"user_email": email,
    	})
    
    	tokenString, err := token.SignedString(privateKey)
    	if err != nil {
    		return "", err
    	}
    
    	return tokenString, nil
    }
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.algorithms.Algorithm;
    
    import java.time.Instant;
    import java.util.Date;
    
    public class JwtGenerator {
        private static final String PRIVATE_KEY = "YOUR_PRIVATE_PARTNER_SSO_KEY";
    
        public static String createChargebackstopSsoToken(String email) {
            Algorithm algorithm = Algorithm.HMAC256(PRIVATE_KEY);
    
            return JWT.create()
                    .withClaim("user_email", email)
                    .withIssuedAt(Date.from(Instant.now()))
                    .sign(algorithm);
        }
    }
    require 'jwt'
    
    PRIVATE_KEY = 'YOUR_PRIVATE_PARTNER_SSO_KEY'
    
    def create_chargebackstop_sso_token(email)
      payload = {
        iat: Time.now.to_i,
        user_email: email
      }
    
      JWT.encode(payload, PRIVATE_KEY, 'HS256')
    end
    
    {Base URL}/auth/partner-organisation-sso?partner_id={Partner ID}&token={SSO Token}

    Install a JWT Library

    pip install PyJWT
    npm install --save jsonwebtoken
    dotnet add package System.IdentityModel.Tokens.Jwt
    go get github.com/golang-jwt/jwt
    implementation 'com.auth0:java-jwt:4.4.0'
    sudo gem install jwt

    Generate Tokens on your Server

    Make sure to thoroughly read through the appropriate documentation for your library and ensure the right security methods are used such as setting appropriate expiries on JWT tokens.

    4. Redirect your user

    The token you generate must be used within 15 minutes of creation, so we recommend only creating these tokens when the user wants to be redirected rather than ahead of time

    import jwt
    from datetime import datetime, timezone
    
    private_key = 'YOUR_PRIVATE_PARTNER_SSO_KEY'
    
    def create_chargebackstop_sso_token(email):
      user_data = {
          "iat": datetime.now(tz=timezone.utc),
          "user_email": email,
      }
      return jwt.encode(user_data, private_key, algorithm='HS256')
    const jwt = require('jsonwebtoken');
    
    const privateKey = 'YOUR_PRIVATE_PARTNER_SSO_KEY';
    
    function createChargebackstopSsoToken(email) {
      const userData = {
        iat: Math.floor(Date.now() / 1000),
        user_email: email,
      };
    
      return jwt.sign(userData, privateKey, { algorithm: 'HS256' }
    }

    Enrolments

    Create, list, retrieve, and cancel network alert enrolments for one or more merchants.

    Versioning notice (important):

    • This is the first v2 API documentation for enrolments.

    • /v1/enrolments is deprecated and should not be used for new integrations.

    • Use /v2/enrolments with enrolments_v2:* abilities.

    • New API keys are provisioned with enrolments_v2:* abilities for enrolments access.

    • Some legacy keys created before /v1/enrolments was deprecated may include both enrolments:* and enrolments_v2:* abilities.

    Base URL: https://api.chargebackstop.com/v2/enrolments/

    Authentication: Bearer token via API key.

    Required abilities:

    • enrolments_v2:read for GET endpoints

    • enrolments_v2:write for POST and DELETE endpoints

    Access scope model:

    • This API is partner-level only.

    • Admin partner-group keys can access enrolments across organisations available to their partner.

    • Non-admin partner-group keys can access enrolments only for organisations assigned to their group.


    Use this section to migrate existing enrolments integrations from v1 to v2.

    Area
    v1
    v2
    Action

    All operations map 1:1 to v2 routes:

    • POST /v1/enrolments -> POST /v2/enrolments

    • GET /v1/enrolments -> GET /v2/enrolments

    • v2 is still partner-level only.

    • Organisation-level keys are still not allowed.

    • v2 endpoints require enrolments_v2:read and enrolments_v2:write.

    v1 create body (single merchant):

    v2 create body (one or more merchants):

    v1 response field:

    v2 response field:

    Other core fields (id, organisation_id, type, status, ethoca_alert, verifi_rdr, timestamps, note) stay the same contract shape.

    • merchant_ids must not contain duplicates.

    • All merchants in one create request must be accessible to the key.

    • All merchants in one create request must belong to the same organisation.

    • type values used by this API remain ETHOCA_ALERT and VERIFI_RDR.

    • GET /v2/enrolments still supports merchant_id, organisation_id, type

    1

    Switch all enrolments routes from /v1/enrolments to /v2/enrolments.

    2

    Ensure API keys include enrolments_v2:read and enrolments_v2:write.

    3

    Create a new enrolment for one or more merchants.

    API level: Partner-level only Authentication: enrolments_v2:write

    Field
    Type
    Required
    Validation
    Description
    Field
    Type
    Required
    Validation
    Description
    Field
    Type
    Required
    Validation
    Description
    • The API rejects mixed-organisation merchant lists with MERCHANTS_DIFFERENT_ORGANISATIONS.

    • The enrolment is created in PENDING status.

    • Responses return merchant_ids (plural), not merchant_id

    Ethoca validates descriptors asynchronously after the enrolment is created. This can take a few days. If the descriptor is too generic or already enrolled by another merchant globally across Ethoca's network, the enrolment moves to ACTION_REQUIRED. When this happens, our support team reaches out to the merchant to agree on an alternative descriptor. This typically takes 1–2 business days. Once resolved, the enrolment is resubmitted. To track enrolment status, poll the GET endpoint every 2–3 hours or subscribe to a webhook to watch for status changes.


    Return enrolments accessible to the authenticated partner-group key.

    API level: Partner-level only Authentication: enrolments_v2:read

    Parameter
    Type
    Description
    • Filtering by a non-existent organisation returns 404 Not found.

    • Filtering by a non-existent merchant returns 404 Not found.


    Retrieve one accessible enrolment by ID.

    API level: Partner-level only Authentication: enrolments_v2:read

    Parameter
    Type
    Description

    Cancel one accessible enrolment.

    API level: Partner-level only Authentication: enrolments_v2:write

    Parameter
    Type
    Description
    • Only enrolments in PENDING status can be cancelled.

    • Cancellation sets status to CANCELLED and sets note to Enrolment cancelled via API request.


    All error responses use this shape:

    Other business validation codes you may receive:

    Code
    Meaning

    API integration guide

    Full API documentation is available here: https://api.chargebackstop.com/v1/docs.

    V2 API documentation (enrolments endpoint only for now): https://api.chargebackstop.com/v2/docs.

    Onboarding a new customer into your partner account

    1

    Create an organisation

    Use the /v1/organisations endpoint. Save the organisation ID for later use in the memberships and merchants APIs.

    Sample request:

    curl -X POST "https://api.chargebackstop.com/v1/organisations/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Acme Fitness"
      }'

    Sample response:

    {
      "id": "org_abc123",
      "name": "Acme Fitness",
      "mode": "LIVE",
      "created_at": "2026-02-17T10:00:00Z",
      "updated_at": "2026-02-17T10:00:00Z"
    }

    Save organisation_id = org_abc123. You will use this in memberships, merchants, and integrations requests.

    2

    Use the /v1/memberships endpoint.

    You can skip this step if you do not intend for your users to log in to ChargebackStop.

    Sample request:

    Sample response:

    This creates the customer user and links them to the organisation.

    3

    Use the /v1/merchants endpoint. Save the merchant account IDs for later use in the integrations and enrolments APIs.

    Sample request:

    Sample response:

    Save merchant_id = mrch_abc123. You will use this in integrations and enrolments requests.

    4

    Use the /v1/integrations endpoint. Save the integration ID for later use in the orders API.

    Sample request:

    Sample response:

    Save integration_id = int_abc123. You will use this for orders submissions.

    5

    Use the /v2/enrolments endpoint. Verifi RDR and Ethoca enrolments are separate; create both if the customer wants both services.

    See .

    Create Ethoca enrolment

    Sample request:

    Sample response:

    Save ethoca_enrolment_id = enrl_ethoca123 if you need to track this enrolment status.

    6

    Use the /v1/rulesets endpoint to control what happens when a pre-dispute alert matches a transaction. A ruleset is scoped to one or more enrolments of the same type — you cannot combine Ethoca and Verifi RDR enrolments in the same ruleset. If you need the same logic for both, create one ruleset per enrolment type.

    See .

    Verifi RDR

    By default, every Verifi RDR alert results in a refund of the matching transaction. Verifi RDR alerts are resolved at the network level, so they arrive already resolved and have no ACTION_REQUIRED state — they are not actionable after the fact.

    7

    Use the /v1/orders endpoint.

    Send a COMPLETE order that satisfies alert matching requirements. COMPLETE orders can be sent directly to your CUSTOM_ORDERS integration.

    Sample request:

    Sample response:

    This creates a COMPLETE order with the core card transaction fields required for alert matching.

    8

    If you want to run the same onboarding flow end-to-end and print all created IDs automatically, use:

    Before running it, save the script below as onboarding-flow.js and set API_KEY.

    Full onboarding flow script (Node.js):

    Every Ethoca alert with ACTION_REQUIRED status is expected to be actioned by the user. The deadline is represented by the action_required_deadline field in the alert object. However, we recommend sending your chosen action as soon as possible. After actioning, the alert status moves to RESOLVED and can no longer be changed. Verifi RDR alerts arrive already resolved and are not actionable.

    Behind the scenes, actioning an alert updates Ethoca with the outcome. This allows them to stop the dispute if the user proactively refunded the transaction, or let the dispute proceed if you chose to fight it.

    For actions that refund the transaction, if the merchant account is integrated with a payment provider (e.g. Stripe), we automatically refund the payment. You can also choose to cancel the subscription associated with the payment.

    The update alert endpoint (PATCH /v1/alerts/{alert_id}) takes the following parameters:

    • action - the action to perform on the alert (see below)

    • note - an optional customer-facing comment/note about the alert

    The action parameter can be one of four values:

    • REFUND

    • CANCEL

    • REFUND_AND_CANCEL

    Let's explore how each of these values works.

    • We let the alert provider know that you refunded the alert.

    • If your merchant account is integrated with a payment provider, we automatically refund the payment.

    • We let the alert provider know that you did not refund the alert.

    • If your merchant account is integrated with a payment provider and there is a subscription associated with the alert, we automatically cancel it.

    • We let the alert provider know that you refunded the alert.

    • If your merchant account is integrated with a payment provider, we automatically refund the payment.

    • If your merchant account is integrated with a payment provider and there is a subscription associated with the alert, we automatically cancel it.

    • We let the alert provider know that you did not refund the alert.

    If you have not integrated ChargebackStop with any payment processing services, you will most likely use only REFUND and ACCEPT_DISPUTE.

    This API is also available to your customers. They can generate API keys for their own organisations in the organisation dashboard and action alerts via API.

    If you enabled payment processor integrations in your organisations and enabled automatic matching, GET /v1/alerts responses include two additional fields:

    • integration_id - ChargebackStop integration ID that contains the transaction matched to this alert

    • integration_transaction_id - transaction ID matched to this alert in your payment processor. For Stripe, this looks like pi_3SPJO4KRFSLReU4y04XJUvLN. For other processors it varies.

    Ethoca and Verifi RDR resolve alerts through fundamentally different mechanisms. Both flows are documented in detail in the sections above — use this contrast as a quick reference.

    • Ethoca (ETHOCA_ALERT) — Alerts enter an ACTION_REQUIRED state with a deadline (action_required_deadline). You (or your customer) must call PATCH /v1/alerts/{alert_id} with one of REFUND, CANCEL, REFUND_AND_CANCEL, or ACCEPT_DISPUTE before the deadline. If no action is taken, the dispute proceeds. Resolution rulesets can auto-action matched alerts when a payment processor integration is in place, but the underlying mechanism is still the same

    In TEST mode, you can use simulation endpoints to test webhooks and actioning alerts.

    .

    )
    ;
    Organisation-level keys receive
    401 Unauthorised
    on all endpoints.

    Update payload shape

    Create response merchant field

    merchant_id

    merchant_ids

    Update response parsing

    List/get/delete response merchant field

    merchant_id

    merchant_ids

    Update response parsing

    New create validation

    Not applicable

    Rejects duplicate merchant IDs and mixed-organisation merchant sets

    Handle new 422 codes

    Merchant reference

    merchant_id identifies one merchant

    merchant_ids supports one or more merchants; missing merchant references return 404 Not found; mixed-organisation merchant sets return 422 MERCHANTS_DIFFERENT_ORGANISATIONS

    Update merchant error handling

    GET /v1/enrolments/{enrolment_id}
    ->
    GET /v2/enrolments/{enrolment_id}
  • DELETE /v1/enrolments/{enrolment_id} -> DELETE /v2/enrolments/{enrolment_id}

  • New API keys are provisioned with v2 enrolments abilities.

  • Some legacy keys created before v1 deprecation may include both enrolments:* and enrolments_v2:*.

  • Out-of-scope organisation and merchant references are returned as 404 Not found.
  • Handle additional 422 business codes: DUPLICATE_MERCHANT_IDS and MERCHANTS_DIFFERENT_ORGANISATIONS.

  • , and
    status
    filters.
  • Deleting an enrolment still cancels it, and only PENDING enrolments can be cancelled.

  • Update payloads

    Update create payload builders from merchant_id to merchant_ids.

    4

    Update response parsing

    Update response parsing from merchant_id to merchant_ids across create/list/get/delete flows.

    5

    Handle new 422 codes

    Add handling for new 422 codes: DUPLICATE_MERCHANT_IDS and MERCHANTS_DIFFERENT_ORGANISATIONS.

    6

    Re-run tests

    Re-run integration tests for enrolment create, list filters, detail, and cancel flows.

    string

    Yes

    ETHOCA_ALERT or VERIFI_RDR

    Enrolment type

    ethoca_alert

    object

    Conditionally

    Required when type is ETHOCA_ALERT

    Ethoca Alert configuration

    verifi_rdr

    object

    Conditionally

    Required when type is VERIFI_RDR

    Verifi RDR configuration

    string

    Yes

    Minimum length 1

    Descriptor text

    descriptors[].match_type

    string

    Yes

    STARTS_WITH or EXACT_MATCH

    Descriptor matching mode

    string

    Conditionally

    Provide together with bin, or omit both and provide arns

    Visa CAID

    arns

    array[string]

    Conditionally

    At least one item when used

    Visa ARNs

    .

    string

    Filter by enrolment type

    status

    string

    Filter by enrolment status

    limit

    integer

    Number of results per page

    offset

    integer

    Number of results to skip

    INVALID_VERIFI_RDR_CONFIG

    Verifi payload does not provide valid BIN/CAID or ARNs

    ETHOCA_ALERT_ENROLLMENT_ERROR

    Upstream Ethoca enrolment validation failed

    VERIFI_RDR_ENROLLMENT_ERROR

    Upstream Verifi enrolment validation failed

    Base path

    /v1/enrolments

    /v2/enrolments

    Update request URLs

    Create request merchant field

    merchant_id (string)

    merchant_ids

    array[string]

    Yes

    At least one ID; duplicates are rejected; all merchants must be accessible and belong to the same organisation

    Merchants to associate with the enrolment

    descriptors

    array[object]

    Yes

    At least one descriptor

    Descriptor rules for Ethoca matching

    bin

    string

    Conditionally

    Provide together with caid, or omit both and provide arns

    Visa BIN

    merchant_id

    string

    Filter by one accessible merchant ID

    organisation_id

    string

    Filter by one accessible organisation ID

    enrolment_id

    string

    Enrolment ID

    enrolment_id

    string

    Enrolment ID to cancel

    DUPLICATE_MERCHANT_IDS

    merchant_ids contains duplicate values

    MISSING_ETHOCA_ALERT_CONFIG

    ethoca_alert is required for ETHOCA_ALERT enrolments

    MISSING_VERIFI_RDR_CONFIG

    verifi_rdr is required for VERIFI_RDR enrolments

    INVALID_MATCH_TYPE

    Migration from /v1/enrolments to /v2/enrolments

    At a glance

    Endpoint mapping

    Authentication and abilities changes

    Request and response schema differences

    Behaviour differences to handle

    What does not change

    Migration checklist

    Switch routes

    Update API key abilities

    POST /v2/enrolments - Create enrolment

    Request body

    Ethoca Alert configuration

    Verifi RDR configuration

    Important behaviour

    Ethoca descriptor validation

    Example 1 request

    Example 1 response

    Example 2 request

    Example 2 response

    GET /v2/enrolments - List enrolments

    Query parameters

    Important behaviour

    Example 3 request

    Example 3 response

    GET /v2/enrolments/{enrolment_id} - Get enrolment by ID

    URL parameters

    Example 4 request

    Example 4 response

    DELETE /v2/enrolments/{enrolment_id} - Cancel enrolment

    URL parameters

    Important behaviour

    Example 5 request

    Example 5 response

    Common error responses

    401 Unauthorised

    Returned for invalid or expired API keys, and for organisation-level keys calling this partner-only API.

    403 Forbidden (missing v2 ability)

    Returned when the key is valid but does not have the required v2 ability.

    404 Not found

    Returned when the requested resource does not exist. This includes non-existent enrolments and non-existent organisation_id or merchant_id filters.

    422 Unprocessable Entity (mixed organisation merchants)
    422 Unprocessable Entity (enrolment not pending)

    merchant_ids (array of strings)

    type

    descriptors[].descriptor

    caid

    type

    Ethoca descriptor match_type is invalid

    Create Verifi RDR enrolment

    Sample request:

    You must provide either both bin and caid, or at least one ARN in the arns array. For example, to enrol using ARNs instead:

    Sample response:

    Save verifi_enrolment_id = enrl_verifi123 if you need to track this enrolment status.

    Note: Once the enrolment is enabled (2-3 business days for Ethoca, and up to 5-14 business days for Verifi RDR), your customer will start receiving pre-dispute alerts in their organisation.

    If you want to limit which transactions are refunded — for example, never auto-refund transactions above a certain amount — create a ruleset with an ACCEPT_DISPUTE outcome and add rules describing the transactions that should bypass the default refund.

    Sample request — accept dispute (skip auto-refund) for any Verifi RDR transaction above $50:

    Ethoca

    Resolution rules for Ethoca alerts only make sense if you have a payment processor integration in place (e.g. Stripe, Adyen) and ChargebackStop is matching incoming alerts to transactions. Ethoca alerts are actioned by issuing a refund through the original payment processor, so without a matched transaction there is nothing for a rule to act on.

    Once matching is in place, a ruleset can auto-action matched Ethoca alerts that meet your criteria, so the user does not have to handle them manually.

    Sample request — automatically refund and cancel matched Ethoca alerts whose descriptor starts with ACMEFIT:

    ACCEPT_DISPUTE

    PATCH
    call applied on the customer's behalf.
  • Verifi RDR (VERIFI_RDR) — Alerts are resolved synchronously at the network level. Each incoming alert is evaluated against the enrolment's resolution ruleset and the chosen outcome is applied automatically. There is no ACTION_REQUIRED state, no deadline, and no PATCH /v1/alerts/{alert_id} call to make — the action API is Ethoca-only. With no ruleset configured, every RDR alert is refunded by default (see step 6 of the onboarding flow).

  • Add your customer users to their organisation

    Add their merchant accounts into the newly created organisation

    If you intend to use the Orders API, create an integration

    If you wish to enrol the customer with Ethoca or Verifi RDR, create enrolments

    Optional: Configure resolution rules for the new enrolments

    Start pushing orders to us using the Orders API

    Optional: Run this flow with a Node.js script

    Actioning alerts

    Ethoca alerts in ACTION_REQUIRED status must be actioned. Refunding the transaction alone is not enough — you must also action the alert so that Ethoca is notified and can stop the dispute. Unactioned alerts provide no value and the chargeback will proceed regardless of whether you refunded the customer. If you have resolution rules configured, matching alerts are resolved automatically. In rare cases, an alert may still appear as ACTION_REQUIRED if the system cannot match the alert to a transaction or cannot process the refund. Verifi RDR alerts are resolved automatically and do not need to be actioned.

    REFUND

    CANCEL

    REFUND_AND_CANCEL

    ACCEPT_DISPUTE

    Matching an alert to a transaction

    Resolution models: Ethoca vs Verifi RDR

    Test organisation simulations

    Enrolments API docs
    Rulesets API docs
    Simulations API docs
    {
      "merchant_id": "mrch_abc123",
      "type": "ETHOCA_ALERT",
      "ethoca_alert": {
        "descriptors": [
          {
            "descriptor": "ECOMM.COM",
            "match_type": "STARTS_WITH"
          }
        ]
      }
    }
    {
      "merchant_ids": ["mrch_abc123", "mrch_def456"],
      "type": "ETHOCA_ALERT",
      "ethoca_alert": {
        "descriptors": [
          {
            "descriptor": "ECOMM.COM",
            "match_type": "STARTS_WITH"
          }
        ]
      }
    }
    {
      "merchant_id": "mrch_abc123"
    }
    {
      "merchant_ids": ["mrch_abc123", "mrch_def456"]
    }
    curl -X POST "https://api.chargebackstop.com/v2/enrolments/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "merchant_ids": ["mrch_abc123", "mrch_def456"],
        "type": "ETHOCA_ALERT",
        "ethoca_alert": {
          "descriptors": [
            {
              "descriptor": "ECOMM.COM",
              "match_type": "STARTS_WITH"
            }
          ]
        }
      }'
    {
      "id": "enrl_abc123",
      "organisation_id": "org_xyz456",
      "merchant_ids": ["mrch_abc123", "mrch_def456"],
      "type": "ETHOCA_ALERT",
      "status": "PENDING",
      "ethoca_alert": {
        "descriptors": [
          {
            "descriptor": "ECOMM.COM",
            "match_type": "STARTS_WITH",
            "status": "PENDING"
          }
        ]
      },
      "created_at": "2026-02-16T12:00:00Z",
      "updated_at": "2026-02-16T12:00:00Z",
      "note": null,
      "links": [
        {
          "rel": "self",
          "uri": "/v2/enrolments/enrl_abc123"
        }
      ]
    }
    curl -X POST "https://api.chargebackstop.com/v2/enrolments/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "merchant_ids": ["mrch_abc123"],
        "type": "VERIFI_RDR",
        "verifi_rdr": {
          "bin": "424242",
          "caid": "ABC1234567"
        }
      }'
    {
      "id": "enrl_def456",
      "organisation_id": "org_xyz456",
      "merchant_ids": ["mrch_abc123"],
      "type": "VERIFI_RDR",
      "status": "PENDING",
      "verifi_rdr": {
        "bin": "424242",
        "caid": "ABC1234567",
        "arns": null
      },
      "created_at": "2026-02-16T12:05:00Z",
      "updated_at": "2026-02-16T12:05:00Z",
      "note": null,
      "links": [
        {
          "rel": "self",
          "uri": "/v2/enrolments/enrl_def456"
        }
      ]
    }
    curl -X GET "https://api.chargebackstop.com/v2/enrolments/?merchant_id=mrch_abc123&type=ETHOCA_ALERT&status=PENDING&limit=20&offset=0" \
      -H "Authorization: Bearer <partner_api_key>"
    {
      "items": [
        {
          "id": "enrl_abc123",
          "organisation_id": "org_xyz456",
          "merchant_ids": ["mrch_abc123", "mrch_def456"],
          "type": "ETHOCA_ALERT",
          "status": "PENDING",
          "ethoca_alert": {
            "descriptors": [
              {
                "descriptor": "ECOMM.COM",
                "match_type": "STARTS_WITH",
                "status": "PENDING"
              }
            ]
          },
          "created_at": "2026-02-16T12:00:00Z",
          "updated_at": "2026-02-16T12:00:00Z",
          "note": null,
          "links": [
            {
              "rel": "self",
              "uri": "/v2/enrolments/enrl_abc123"
            }
          ]
        }
      ],
      "count": 1
    }
    curl -X GET "https://api.chargebackstop.com/v2/enrolments/enrl_abc123" \
      -H "Authorization: Bearer <partner_api_key>"
    {
      "id": "enrl_abc123",
      "organisation_id": "org_xyz456",
      "merchant_ids": ["mrch_abc123", "mrch_def456"],
      "type": "ETHOCA_ALERT",
      "status": "PENDING",
      "ethoca_alert": {
        "descriptors": [
          {
            "descriptor": "ECOMM.COM",
            "match_type": "STARTS_WITH",
            "status": "PENDING"
          }
        ]
      },
      "created_at": "2026-02-16T12:00:00Z",
      "updated_at": "2026-02-16T12:00:00Z",
      "note": null,
      "links": [
        {
          "rel": "self",
          "uri": "/v2/enrolments/enrl_abc123"
        }
      ]
    }
    curl -X DELETE "https://api.chargebackstop.com/v2/enrolments/enrl_abc123" \
      -H "Authorization: Bearer <partner_api_key>"
    {
      "id": "enrl_abc123",
      "organisation_id": "org_xyz456",
      "merchant_ids": ["mrch_abc123", "mrch_def456"],
      "type": "ETHOCA_ALERT",
      "status": "CANCELLED",
      "ethoca_alert": {
        "descriptors": [
          {
            "descriptor": "ECOMM.COM",
            "match_type": "STARTS_WITH",
            "status": "PENDING"
          }
        ]
      },
      "created_at": "2026-02-16T12:00:00Z",
      "updated_at": "2026-02-16T12:10:00Z",
      "note": "Enrolment cancelled via API request",
      "links": [
        {
          "rel": "self",
          "uri": "/v2/enrolments/enrl_abc123"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "ERROR_CODE",
          "message": "Human-readable message"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "UNAUTHORISED",
          "message": "Unauthorised"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "FORBIDDEN",
          "message": "Forbidden"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "MERCHANTS_DIFFERENT_ORGANISATIONS",
          "message": "All merchants must belong to the same organisation"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "ENROLMENT_NOT_PENDING",
          "message": "Only enrolments in PENDING state can be cancelled"
        }
      ]
    }
    curl -X POST "https://api.chargebackstop.com/v1/memberships/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_abc123",
        "first_name": "Casey",
        "last_name": "Jordan",
        "email": "[email protected]",
        "role": "ADMIN",
        "is_alert_action_required_email_enabled": true,
        "is_alert_resolved_email_enabled": true,
        "is_alert_dismissed_email_enabled": true,
        "is_evidence_requested_email_enabled": true
      }'
    {
      "id": "mem_abc123",
      "organisation_id": "org_abc123",
      "user_id": "usr_abc123",
      "first_name": "Casey",
      "last_name": "Jordan",
      "email": "[email protected]",
      "role": "ADMIN",
      "is_alert_action_required_email_enabled": true,
      "is_alert_resolved_email_enabled": true,
      "is_alert_dismissed_email_enabled": true,
      "is_evidence_requested_email_enabled": true,
      "created_at": "2026-02-17T10:01:00Z",
      "updated_at": "2026-02-17T10:01:00Z"
    }
    curl -X POST "https://api.chargebackstop.com/v1/merchants/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_abc123",
        "name": "Acme Fitness Main Store",
        "type": "GENERIC",
        "external_id": "acct_1ABCDEF2345678"
      }'
    {
      "id": "mrch_abc123",
      "organisation_id": "org_abc123",
      "name": "Acme Fitness Main Store",
      "type": "GENERIC",
      "external_id": "acct_1ABCDEF2345678",
      "default_representment_service_type": null,
      "created_at": "2026-02-17T10:02:00Z",
      "updated_at": "2026-02-17T10:02:00Z"
    }
    curl -X POST "https://api.chargebackstop.com/v1/integrations/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_abc123",
        "name": "Acme Fitness Orders",
        "type": "CUSTOM_ORDERS",
        "status": "ENABLED",
        "merchant_ids": ["mrch_abc123"]
      }'
    {
      "id": "int_abc123",
      "organisation_id": "org_abc123",
      "name": "Acme Fitness Orders",
      "type": "CUSTOM_ORDERS",
      "status": "ENABLED",
      "merchant_ids": ["mrch_abc123"]
    }
    curl -X POST "https://api.chargebackstop.com/v2/enrolments/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "merchant_ids": ["mrch_abc123"],
        "type": "ETHOCA_ALERT",
        "ethoca_alert": {
          "descriptors": [
            {
              "descriptor": "ACMEFIT",
              "match_type": "STARTS_WITH"
            }
          ]
        }
      }'
    {
      "id": "enrl_ethoca123",
      "organisation_id": "org_abc123",
      "merchant_ids": ["mrch_abc123"],
      "type": "ETHOCA_ALERT",
      "status": "PENDING",
      "ethoca_alert": {
        "descriptors": [
          {
            "descriptor": "ACMEFIT",
            "match_type": "STARTS_WITH"
          }
        ]
      },
      "created_at": "2026-02-17T10:03:00Z",
      "updated_at": "2026-02-17T10:03:00Z",
      "note": null
    }
    curl -X POST "https://api.chargebackstop.com/v1/orders/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '[
        {
          "type": "COMPLETE",
          "organisation_id": "org_abc123",
          "integration_id": "int_abc123",
          "reference_id": "order-10001",
          "order_datetime": "2026-02-17T09:59:00Z",
          "order_number": "AF-10001",
          "order_subtotal_amount_in_cents": 4900,
          "order_currency": "USD",
          "order_total_amount_in_cents": 4900,
          "order_status": "CLOSED_COMPLETE",
          "customer_email": "[email protected]",
          "transactions": [
            {
              "reference_id": "txn-10001",
              "amount_in_cents": 4900,
              "currency": "USD",
              "payment_method_type": "CARD",
              "authorisation_status": "SETTLED",
              "payment_method_reference_id": "pi_3QJ2ABCD12345678",
              "authorised_at": "2026-02-17T09:59:05Z",
              "payment_method_card_brand": "VISA",
              "payment_method_card_last_4": "4242",
              "acquirer_reference_number": "74027012345678901234567"
            }
          ]
        }
      ]'
    {
      "created": 1,
      "failed": 0,
      "results": [
        {
          "id": "ord_abc123",
          "reference_id": "order-10001",
          "type": "COMPLETE",
          "organisation_id": "org_abc123",
          "integration_id": "int_abc123",
          "created_at": "2026-02-17T10:05:00Z",
          "transactions": [
            {
              "reference_id": "txn-10001",
              "amount_in_cents": 4900,
              "currency": "USD",
              "payment_method_type": "CARD",
              "authorisation_status": "SETTLED",
              "payment_method_card_brand": "VISA",
              "payment_method_card_last_4": "4242",
              "acquirer_reference_number": "74027012345678901234567"
            }
          ]
        }
      ],
      "errors": []
    }
    node onboarding-flow.js
    /*
     * Simple onboarding flow example for partner API keys.
     *
     * Update the variables in the CONFIG section, then run:
     * node onboarding-flow.js
     */
    
    // -----------------------------------------------------------------------------
    // CONFIG
    // -----------------------------------------------------------------------------
    const API_BASE_URL = "https://api.chargebackstop.com";
    const API_KEY = "REPLACE_WITH_PARTNER_API_KEY";
    
    const MEMBER_USER_EMAIL = "[email protected]";
    const MEMBER_FIRST_NAME = "Casey";
    const MEMBER_LAST_NAME = "Jordan";
    
    const ORGANISATION_NAME = "Acme Fitness";
    const MERCHANT_NAME = "Acme Fitness Main Store";
    const MERCHANT_TYPE = "GENERIC";
    const MERCHANT_EXTERNAL_ID = "acct_1ABCDEF2345678";
    
    const INTEGRATION_NAME = "Acme Fitness Orders";
    
    const ORDER_REFERENCE_ID = "order-10001";
    const ORDER_NUMBER = "AF-10001";
    const ORDER_CUSTOMER_EMAIL = MEMBER_USER_EMAIL;
    const ORDER_TRANSACTION_REFERENCE_ID = "txn-10001";
    
    // -----------------------------------------------------------------------------
    // HELPERS
    // -----------------------------------------------------------------------------
    function fail(message, details) {
      console.error(`\nERROR: ${message}`);
      if (details !== undefined) {
        console.error(JSON.stringify(details, null, 2));
      }
      process.exit(1);
    }
    
    function logStep(stepNumber, title) {
      console.log(`\n[Step ${stepNumber}] ${title}`);
    }
    
    function printJson(label, data) {
      console.log(`${label}:`);
      console.log(JSON.stringify(data, null, 2));
    }
    
    async function apiRequest({ method, path, body }) {
      const response = await fetch(`${API_BASE_URL}${path}`, {
        method,
        headers: {
          Authorization: `Bearer ${API_KEY}`,
          "Content-Type": "application/json",
        },
        body: body ? JSON.stringify(body) : undefined,
      });
    
      const rawText = await response.text();
      let data = null;
    
      if (rawText.length > 0) {
        try {
          data = JSON.parse(rawText);
        } catch (error) {
          data = { raw: rawText };
        }
      }
    
      if (!response.ok) {
        fail(`Request failed: ${method} ${path} (${response.status})`, data);
      }
    
      return data;
    }
    
    // -----------------------------------------------------------------------------
    // FLOW
    // -----------------------------------------------------------------------------
    async function main() {
      if (API_KEY.includes("REPLACE_WITH_PARTNER_API_KEY")) {
        fail("Set API_KEY at the top of this file before running the script.");
      }
    
      const createdIds = {
        organisation_id: null,
        membership_id: null,
        merchant_id: null,
        integration_id: null,
        ethoca_enrolment_id: null,
        verifi_enrolment_id: null,
        order_id: null,
      };
    
      logStep(1, "Create organisation");
      const organisation = await apiRequest({
        method: "POST",
        path: "/v1/organisations/",
        body: {
          name: ORGANISATION_NAME,
        },
      });
      createdIds.organisation_id = organisation.id;
      printJson("Response", organisation);
      console.log(`Saved organisation_id: ${createdIds.organisation_id}`);
    
      logStep(2, "Create membership");
      const membership = await apiRequest({
        method: "POST",
        path: "/v1/memberships/",
        body: {
          organisation_id: createdIds.organisation_id,
          first_name: MEMBER_FIRST_NAME,
          last_name: MEMBER_LAST_NAME,
          email: MEMBER_USER_EMAIL,
          role: "ADMIN",
          is_alert_action_required_email_enabled: true,
          is_alert_resolved_email_enabled: true,
          is_alert_dismissed_email_enabled: true,
          is_evidence_requested_email_enabled: true,
        },
      });
      createdIds.membership_id = membership.id;
      printJson("Response", membership);
      console.log(`Saved membership_id: ${createdIds.membership_id}`);
    
      logStep(3, "Create merchant");
      const merchant = await apiRequest({
        method: "POST",
        path: "/v1/merchants/",
        body: {
          organisation_id: createdIds.organisation_id,
          name: MERCHANT_NAME,
          type: MERCHANT_TYPE,
          external_id: MERCHANT_EXTERNAL_ID,
        },
      });
      createdIds.merchant_id = merchant.id;
      printJson("Response", merchant);
      console.log(`Saved merchant_id: ${createdIds.merchant_id}`);
    
      logStep(4, "Create custom orders integration");
      const integration = await apiRequest({
        method: "POST",
        path: "/v1/integrations/",
        body: {
          organisation_id: createdIds.organisation_id,
          name: INTEGRATION_NAME,
          type: "CUSTOM_ORDERS",
          status: "ENABLED",
          merchant_ids: [createdIds.merchant_id],
        },
      });
      createdIds.integration_id = integration.id;
      printJson("Response", integration);
      console.log(`Saved integration_id: ${createdIds.integration_id}`);
    
      logStep(5, "Create Ethoca enrolment");
      const ethocaEnrolment = await apiRequest({
        method: "POST",
        path: "/v2/enrolments/",
        body: {
          merchant_ids: [createdIds.merchant_id],
          type: "ETHOCA_ALERT",
          ethoca_alert: {
            descriptors: [
              {
                descriptor: "ACMEFIT",
                match_type: "STARTS_WITH",
              },
            ],
          },
        },
      });
      createdIds.ethoca_enrolment_id = ethocaEnrolment.id;
      printJson("Response", ethocaEnrolment);
      console.log(`Saved ethoca_enrolment_id: ${createdIds.ethoca_enrolment_id}`);
    
      logStep(6, "Create Verifi RDR enrolment");
      const verifiEnrolment = await apiRequest({
        method: "POST",
        path: "/v2/enrolments/",
        body: {
          merchant_ids: [createdIds.merchant_id],
          type: "VERIFI_RDR",
          verifi_rdr: {
            bin: "424242",
            caid: "ABC1234567",
          },
        },
      });
      createdIds.verifi_enrolment_id = verifiEnrolment.id;
      printJson("Response", verifiEnrolment);
      console.log(`Saved verifi_enrolment_id: ${createdIds.verifi_enrolment_id}`);
    
      logStep(7, "Submit COMPLETE order for alert matching");
      const orderResponse = await apiRequest({
        method: "POST",
        path: "/v1/orders/",
        body: [
          {
            type: "COMPLETE",
            organisation_id: createdIds.organisation_id,
            integration_id: createdIds.integration_id,
            reference_id: ORDER_REFERENCE_ID,
            order_datetime: "2026-02-17T09:59:00Z",
            order_number: ORDER_NUMBER,
            order_subtotal_amount_in_cents: 4900,
            order_currency: "USD",
            order_total_amount_in_cents: 4900,
            order_status: "CLOSED_COMPLETE",
            customer_email: ORDER_CUSTOMER_EMAIL,
            transactions: [
              {
                reference_id: ORDER_TRANSACTION_REFERENCE_ID,
                amount_in_cents: 4900,
                currency: "USD",
                payment_method_type: "CARD",
                authorisation_status: "SETTLED",
                payment_method_reference_id: "pi_3QJ2ABCD12345678",
                authorised_at: "2026-02-17T09:59:05Z",
                payment_method_card_brand: "VISA",
                payment_method_card_last_4: "4242",
                acquirer_reference_number: "74027012345678901234567",
              },
            ],
          },
        ],
      });
      printJson("Response", orderResponse);
    
      if (orderResponse.failed > 0) {
        console.log("\nOrder was not created. API returned validation errors.");
      } else if (orderResponse.results && orderResponse.results.length > 0) {
        createdIds.order_id = orderResponse.results[0].id;
      }
    
      console.log("\nDone. IDs to save for future requests:");
      printJson("Created IDs", createdIds);
    }
    
    main().catch((error) => {
      fail("Unexpected script error", {
        message: error.message,
        stack: error.stack,
      });
    });
    curl -X POST "https://api.chargebackstop.com/v2/enrolments/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "merchant_ids": ["mrch_abc123"],
        "type": "VERIFI_RDR",
        "verifi_rdr": {
          "bin": "424242",
          "caid": "ABC1234567"
        }
      }'
    {
      "merchant_ids": ["mrch_abc123"],
      "type": "VERIFI_RDR",
      "verifi_rdr": {
        "arns": ["74027012345678901234567"]
      }
    }
    {
      "id": "enrl_verifi123",
      "organisation_id": "org_abc123",
      "merchant_ids": ["mrch_abc123"],
      "type": "VERIFI_RDR",
      "status": "PENDING",
      "verifi_rdr": {
        "bin": "424242",
        "caid": "ABC1234567"
      },
      "created_at": "2026-02-17T10:04:00Z",
      "updated_at": "2026-02-17T10:04:00Z",
      "note": null
    }
    curl -X POST "https://api.chargebackstop.com/v1/rulesets/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_abc123",
        "enrolment_ids": ["enrl_verifi123"],
        "outcome": "ACCEPT_DISPUTE",
        "join_operator": "AND",
        "rules": [
          {
            "type": "AMOUNT",
            "parameters": {
              "operator": "GREATER_THAN",
              "currency_code": "USD",
              "amount_in_cents": 5000
            }
          }
        ]
      }'
    curl -X POST "https://api.chargebackstop.com/v1/rulesets/" \
      -H "Authorization: Bearer <partner_api_key>" \
      -H "Content-Type: application/json" \
      -d '{
        "organisation_id": "org_abc123",
        "enrolment_ids": ["enrl_ethoca123"],
        "outcome": "REFUND_AND_CANCEL",
        "join_operator": "AND",
        "rules": [
          {
            "type": "DESCRIPTOR",
            "parameters": {
              "descriptors": [
                {"value": "ACMEFIT", "match_type": "STARTS_WITH"}
              ]
            }
          }
        ]
      }'

    Webhooks

    ChargebackStop currently supports ten types of webhook events:

    • alert.created

    • alert.updated

    enrolment.created
  • enrolment.updated

  • representment.created

  • representment.updated

  • scheme_notice.created

  • scheme_notice.updated

  • lookup.created

  • lookup.updated

  • To add a webhook endpoint, go to the Partner settings page and click “Add Endpoint” in the section at the bottom of the page.

    In the modal window, enter the URL ChargebackStop should send events to, and select the event types you want to receive.

    Once the endpoint is saved, it appears in the table at the bottom of the page. You can use the eye icon to reveal the webhook secret that the ChargebackStop platform uses to sign webhooks.

    Open your ChargebackStop dashboard, then select “Settings” from the left-hand menu. From the tabs at the top, pick “Webhooks”.

    To add a webhook, click the “Add webhook” button and fill in the form with your endpoint URL and the events you want to receive.

    Once the endpoint is saved, it appears in the table at the bottom of the page. You can use the eye icon to reveal the webhook secret that the ChargebackStop platform uses to sign webhooks.

    • The payload will be a JSON object (see below for details).

    • We include an X-Signature header, which is an HMAC-SHA512 hash of the timestamp and payload, allowing you to verify request authenticity. The signing secret is unique to your webhook subscription.

    • We include an X-Idempotency-Key header with the unique delivery ID.

    • We expect a successful HTTP response (2xx status code) within 20 seconds.

    • If the initial delivery attempt fails (e.g., due to a network error or a 4xx/5xx response from your server), we automatically retry delivery.

    • Our retry strategy includes 5 attempts over approximately 2 days, with increasing delays between attempts: 1 minute, 5 minutes, 30 minutes, 2 hours, and finally 12 hours.

      • Retries for the same delivery keep the same X-Idempotency-Key value (the delivery ID). The header helps prevent processing duplicate deliveries. To ensure you process each event only once, rely on the event ID from the payload (id), which stays the same across retries of that event.

    • If all retries are exhausted and the delivery remains unsuccessful, the delivery will be marked as FAILED.

    • If multiple delivery attempts to a given endpoint start failing, the system will automatically disable the webhook endpoint due to poor health.

    To ensure webhook security and authenticity, we include a unique signature with each request. This signature allows you to verify that the webhook originated from us and that its payload was not tampered with in transit.

    1

    How the X-Signature header is generated

    • Timestamp: We take the current Unix timestamp (the number of seconds since January 1, 1970 UTC). This timestamp is included directly in the signature header.

    • Payload: This is the raw JSON body of the webhook request.

    • Concatenation: We create a string by concatenating the timestamp, a period (.), and the UTF-8 decoded payload. For example: "{timestamp}.{payload_string}".

    • HMAC-SHA512: We then use your unique webhook secret (provided to you when you set up the webhook subscription) to create an HMAC of the concatenated string using the SHA512 hashing algorithm.

    • Hex Digest: The resulting HMAC is encoded into a hexadecimal string.

    • Formatted signature: Finally, the signature is formatted as t={timestamp},v1={hex_digest}.

    Notes on the formatted signature:

    • t={timestamp}: Unix timestamp when the signature was generated. You can compare this with your current time and discard webhooks that are too old to help prevent replay attacks. We recommend tolerating reasonable clock skew (e.g., a few minutes) between your servers and ours.

    • v1={hex_digest}: Signature scheme version (currently v1) followed by the hexadecimal HMAC-SHA512 digest.

    2

    How to verify a received signature

    1. Verify the timestamp (t=): Extract the timestamp from the X-Signature header and compare it with your current server time. If the difference is too large (outside your acceptable tolerance for clock skew and message delivery times), you may choose to discard the request.

    Webhook payload contains the following fields:

    • id - unique event ID.

    • type - event type, currently one of alert.created, alert.updated, enrolment.created, enrolment.updated, representment.created, representment.updated, scheme_notice.created, scheme_notice.updated, lookup.created, or lookup.updated.

    • created_at - date and time of when event was created.

    • data - object containing the main body of the event.

      • object - a snapshot of the entity the webhook was generated for. For alert events it matches the alert object from the API (); representment and scheme notice events follow their corresponding public event payload schemas.

      • previous_attributes

    Sample alert.created payload. data→object body matches the alert object from the API (https://api.chargebackstop.com/v1/docs#/Alerts/src_api_alerts_get_alerts).

    Sample alert.updated body. Please note the previous_attributes object.

    • enrolment.created is sent when a new enrolment is created.

    • enrolment.updated is currently emitted when an enrolment status changes.

    • This status-only behavior is the current implementation and is not a strict long-term contract. Additional enrolment field changes may also emit enrolment.updated in the future.

    • Status updates performed through simulation tooling (for example, PATCH /v1/simulate/enrolments/{enrolment_id} for TEST organisations) follow the same behavior and can emit enrolment.updated.

    • Enrolment webhook payloads are versioned as api_version: "v2".

    • For update events, data.previous_attributes includes tracked fields and their previous values at event creation time.

    Sample enrolment.created payload.

    Sample enrolment.updated payload. Please note the previous_attributes object.

    Sample representment.created event

    Sample representment.updated event

    • scheme_notice.created is sent when a new scheme notice is created.

    • scheme_notice.updated is emitted when a tracked field on a scheme notice changes. Currently tracked fields are: is_revoked, notice_revoked_at, fraud_reported_at, and transaction_purchase_date.

    • A scheme_notice.updated event is only emitted after a scheme_notice.created event exists for that notice.

    • For update events, data.previous_attributes includes only the tracked fields that changed and their previous values.

    • Scheme notice webhook payloads are versioned as api_version: "v1".

    Sample scheme_notice.created payload.

    Sample scheme_notice.updated payload. In this example, the notice was revoked. Please note the previous_attributes object.

    Scheme notice field definitions:

    • scheme_notice_type: TC15, TC40, or SAFE

    • notice_type: FRAUD_NOTICE or DISPUTE_NOTICE

    • scheme: VISA, MASTERCARD, or OTHER

    • fraud_reported_at: Date when the fraud was reported

    • fraud_type: Free-form string from the upstream network (e.g., CARD_NOT_PRESENT, STOLEN, COUNTERFEIT, ACCOUNT_TAKEOVER, etc.)

    • fraud_dispute_eligible: Whether the fraud is eligible for a dispute

    • lookup.created is sent when a new digital receipt lookup is created (from Ethoca Consumer Clarity or Verifi Order Insight).

    • lookup.updated is emitted when a tracked field on a lookup changes. Currently tracked fields are: lookup_status and deflection_status.

    • A lookup.updated event is only emitted after a lookup.created event exists for that lookup.

    • For update events, data.previous_attributes includes only the tracked fields that changed and their previous values.

    • Lookup webhook payloads are versioned as api_version: "v1".

    Sample lookup.created payload.

    Sample lookup.updated payload. In this example, the deflection status changed from PENDING to SUCCEEDED. Please note the previous_attributes object.

    Lookup field definitions:

    • type: ETHOCA_CONSUMER_CLARITY, ETHOCA_FIRST_PARTY_TRUST, VERIFI_ORDER_INSIGHT, or VERIFI_COMPELLING_EVIDENCE_3

    • lookup_status: PENDING, SUCCEEDED, FAILED, or TIMEOUT

    • deflection_status: NOT_ATTEMPTED, PENDING, SUCCEEDED, or FAILED

    • parent_lookup_id: ID of the parent lookup (e.g., for HISTORICAL lookups linked to a DISPUTED lookup)

    • transaction_amount: Transaction amount in cents

    • integration_id: Platform Integration ID for the matched transaction's payment processor integration

    • integration_transaction_id: Payment processor's transaction ID (e.g., Stripe charge ID, Adyen PSP reference)

    We created a Postman collection that allows you to send sample webhooks.

    It contains a pre-request script that generates a correct signature every time you send the request.

    Postman collection: https://www.postman.com/chargebackstop/chargebackstop/collection/2yu40q8/chargebackstop-webhooks

    Event types

    verifySignature.js
    import crypto from 'crypto';
    
    /**
     * Verify a webhook signature.
     *
     * @param {string} rawBody            – the exact request body
     * @param {string} signatureHeader    – the entire value of the x-signature header
     * @param {string} secret             – your webhook signing secret
     * @throws {Error} on any verification failure
     */
    function verifySignature(rawBody, signatureHeader, secret) {
      if (!secret) {
        throw new Error('Missing webhook secret');
      }
      if (!signatureHeader) {
        throw new Error('Missing signature header');
      }
    
      // e.g. "t=1618884471,v1=abcdef123456…"
      const parts = signatureHeader.split(',');
      let timestamp = null;
      let receivedSig = null;
    
      for (const part of parts) {
        const [key, val] = part.split('=');
        if (key === 't') {
          timestamp = val;
        } else if (key === 'v1') {
          receivedSig = val;
        }
      }
    
      if (!timestamp) {
        throw new Error('Signature header missing timestamp (t)');
      }
      if (!receivedSig) {
        throw new Error('Signature header missing signature (v1)');
      }
    
      // Enforce 5 minute tolerance
      const sentTime = Number(timestamp);
      if (Number.isNaN(sentTime)) {
        throw new Error('Invalid timestamp in signature header');
      }
      const now = Math.floor(Date.now() / 1000);
      const FIVE_MINUTES = 5 * 60;
      if (Math.abs(now - sentTime) > FIVE_MINUTES) {
        throw new Error('Timestamp is outside the allowed 5 minute window');
      }
    
      // Compute expected HMAC
      const payload = `${timestamp}.${rawBody}`;
      const expectedSig = crypto
        .createHmac('sha512', secret)
        .update(payload)
        .digest('hex');
    
      const receivedBuf = Buffer.from(receivedSig, 'hex');
      const expectedBuf = Buffer.from(expectedSig, 'hex');
      // Protect against timing attacks
      if (receivedBuf.length !== expectedBuf.length ||
          !crypto.timingSafeEqual(receivedBuf, expectedBuf)) {
        throw new Error('Invalid signature');
      }
    
      // All checks passed
      return true;
    }
    verifySignature.php
    /**
     * Verify a webhook signature.
     *
     * @param  string  $rawBody  The exact request body
     * @param  string  $signatureHeader  The value of the X-Signature header
     * @param  string  $secret  Your webhook signing secret
     *
     * @throws Exception on any verification failure
     */
    function verifySignature(string $rawBody, string $signatureHeader, string $secret) : bool
    {
        if (empty($secret)) {
            throw new Exception('Missing webhook secret');
        }
        if (empty($signatureHeader)) {
            throw new Exception('Missing signature header');
        }
    
        // Split header like "t=1618884471,v1=abcdef123456…"
        $parts = explode(',', $signatureHeader);
        $timestamp = null;
        $receivedSig = null;
    
        foreach ($parts as $part) {
            [$key, $val] = array_pad(explode('=', $part, 2), 2, null);
            if ('t' === $key) {
                $timestamp = $val;
            } elseif ('v1' === $key) {
                $receivedSig = $val;
            }
        }
    
        if (null === $timestamp) {
            throw new Exception('Signature header missing timestamp (t)');
        }
        if (null === $receivedSig) {
            throw new Exception('Signature header missing signature (v1)');
        }
        if (! ctype_digit($timestamp)) {
            throw new Exception('Invalid timestamp in signature header');
        }
    
        // Enforce 5 minute skew
        $sentTime = (int) $timestamp;
        $now = time();
        if (abs($now - $sentTime) > 5 * 60) {
            throw new Exception('Timestamp is outside the allowed 5 minute window');
        }
    
        // Compute expected signature
        $payload = $timestamp . '.' . $rawBody;
        $expectedSig = hash_hmac('sha512', $payload, $secret);
    
        // Timing-safe comparison
        if (! hash_equals($expectedSig, $receivedSig)) {
            throw new Exception('Invalid signature');
        }
    
        return true;
    }
    verify_signature.py
    import hmac
    import hashlib
    import time
    
    def verify_signature(raw_body: bytes, signature_header: str, secret: str) -> None:
        if not secret:
            raise ValueError('Missing webhook secret')
        if not signature_header:
            raise ValueError('Missing signature header')
    
        parts = dict(p.split('=', 1) for p in signature_header.split(',') if '=' in p)
        t = parts.get('t')
        v1 = parts.get('v1')
    
        if t is None:
            raise ValueError('Signature header missing timestamp (t)')
        if v1 is None:
            raise ValueError('Signature header missing signature (v1)')
        if not t.isdigit():
            raise ValueError('Invalid timestamp in signature header')
    
        ts = int(t)
        now = int(time.time())
        FIVE_MINUTES = 5 * 60
        if abs(now - ts) > FIVE_MINUTES:
            raise ValueError('Timestamp is outside the allowed 5 minute window')
    
        payload = f'{t}.{raw_body.decode("utf-8")}'.encode('utf-8')
        expected = hmac.new(secret.encode(), payload, hashlib.sha512).hexdigest()
    
        if not hmac.compare_digest(expected, v1):
            raise ValueError('Invalid signature')
    x-signature: t=1746901125,v1=71d294712c109472c92e6afc2f0fcafce611bda73ba027f7221f8910d37b29de6fdd65489d28b28678c74d3ea62edb76f13631286d661833b0c4d4880be4d2ba
    x-idempotency-key: whdl_CXwgJJye6EoZYxtFbx78Q
    {
      "id": "evt_dbXKdyUWLzSP98HMVdoFW",
      "type": "alert.created",
      "created_at": "2025-05-10T18:17:35.635870+00:00",
      "data": {
        "object": {
          "id": "netalrt_yxMihZ4JhB7h5unn36F18",
          "note": null,
          "status": "ACTION_REQUIRED",
          "created_at": "2025-05-10T13:56:56.312045Z",
          "updated_at": "2025-05-10T13:56:58.111532Z",
          "merchant_id": "mrch_YoaBvAq2H2R8JYXjXodkE",
          "enrolment_type": "ETHOCA_ALERT",
          "organisation_id": "org_RoExcMDGGjmmGXKxAUAkR",
          "transaction_card_bin": null,
          "chargeback_reason_code": null,
          "transaction_card_last4": "5455",
          "transaction_network_id": null,
          "transaction_card_issuer": "BofA",
          "transaction_card_scheme": "MASTERCARD",
          "action_required_deadline": "2025-05-12T13:56:56.300274Z",
          "transaction_authorised_at": "2025-05-05T13:56:56.300274Z",
          "transaction_currency_code": "USD",
          "transaction_refund_outcome": null,
          "subscription_cancel_outcome": null,
          "transaction_amount_in_cents": 6606,
          "transaction_authorisation_code": "7XP81U",
          "transaction_statement_descriptor": "ECOM-STUFF.COM",
          "transaction_acquirer_reference_number": "012533471273304331125644612",
          "integration_id": "int_ZSHVZukGYs5SdVcwkEZrL",
    		  "integration_transaction_id": "pi_3SPJO4KRFSLReU4y04XJUvLN"
        }
      },
      "api_version": "v1"
    }
    x-signature: t=1746901218,v1=5ef9423caa3366f28eaf2411c3c3b3b6d660ddcc1a03c190ac124038e04d927bcbaae622f21c011feb27a9bae1ad96da4f74407cb1533ba1cdf8c0d8e1733b37
    x-idempotency-key: whdl_ghRygm8zYiHD4vjNSQ9uT
    {
      "id": "evt_NUpgzGLGJTj5j1MZ6jb1d",
      "type": "alert.updated",
      "created_at": "2025-05-10T18:20:18.430390+00:00",
      "data": {
        "object": {
          "id": "netalrt_yxMihZ4JhB7h5unn36F18",
          "note": null,
          "status": "RESOLVED",
          "created_at": "2025-05-10T13:56:56.312045Z",
          "updated_at": "2025-05-10T18:20:18.419298Z",
          "merchant_id": "mrch_YoaBvAq2H2R8JYXjXodkE",
          "enrolment_type": "ETHOCA_ALERT",
          "organisation_id": "org_RoExcMDGGjmmGXKxAUAkR",
          "transaction_card_bin": null,
          "chargeback_reason_code": null,
          "transaction_card_last4": "5455",
          "transaction_network_id": null,
          "transaction_card_issuer": "BofA",
          "transaction_card_scheme": "MASTERCARD",
          "action_required_deadline": "2025-05-12T13:56:56Z",
          "transaction_authorised_at": "2025-05-05T13:56:56Z",
          "transaction_currency_code": "USD",
          "transaction_refund_outcome": "REFUNDED",
          "subscription_cancel_outcome": null,
          "transaction_amount_in_cents": 6606,
          "transaction_authorisation_code": "7XP81U",
          "transaction_statement_descriptor": "ECOM-STUFF.COM",
          "transaction_acquirer_reference_number": "012533471273304331125644612",
          "integration_id": "int_ZSHVZukGYs5SdVcwkEZrL",
    		  "integration_transaction_id": "pi_3SPJO4KRFSLReU4y04XJUvLN"
        },
        "previous_attributes": {
          "status": "ACTION_REQUIRED",
          "transaction_refund_outcome": null
        }
      },
      "api_version": "v1"
    }
    {
      "id": "evt_hxgqT7vA8am77QbJCMiFA",
      "type": "enrolment.created",
      "created_at": "2026-02-25T15:02:49.256560+00:00",
      "data": {
        "object": {
          "id": "enrl_pfNupxFzfYDaEf1UrD6wU",
          "organisation_id": "org_MSALEuBsAywqDA3SQVqc8",
          "merchant_ids": [
            "mrch_XXiP48XqnnYbRvnUFVH6G"
          ],
          "type": "VERIFI_ORDER_INSIGHT",
          "status": "IN_PROGRESS",
          "created_at": "2026-02-25T15:02:49.256560Z",
          "updated_at": "2026-02-25T15:03:14.460982Z",
          "note": ""
        }
      },
      "api_version": "v2"
    }
    {
      "id": "evt_aXCsMEEaxP3Jvk9SmxBaQ",
      "type": "enrolment.updated",
      "created_at": "2026-02-25T15:05:31.102891+00:00",
      "data": {
        "object": {
          "id": "enrl_pfNupxFzfYDaEf1UrD6wU",
          "organisation_id": "org_MSALEuBsAywqDA3SQVqc8",
          "merchant_ids": [
            "mrch_XXiP48XqnnYbRvnUFVH6G"
          ],
          "type": "VERIFI_ORDER_INSIGHT",
          "status": "ENABLED",
          "created_at": "2026-02-25T15:02:49.256560Z",
          "updated_at": "2026-02-25T15:05:31.083449Z",
          "note": ""
        },
        "previous_attributes": {
          "status": "IN_PROGRESS"
        }
      },
      "api_version": "v2"
    }
    {
      "id": "evt_S4VJrD42E1mVRVuCeapmt",
      "type": "representment.created",
      "created_at": "2025-05-22T19:09:09.512272+00:00",
      "data": {
        "object": {
          "id": "rep_DenAQk14kzDmwKSJn7cU3",
          "created_at": "2025-05-22T19:09:09.495869Z",
          "managed_by": "PARTNER",
          "updated_at": "2025-05-22T19:09:09.496523Z",
          "disputed_at": "2024-11-19T00:00:00",
          "merchant_id": "mrch_bQXg83B18qgACnp5Y4qU8",
          "service_type": "ONLINE_SERVICES",
          "dispute_stage": "CHARGEBACK",
          "dispute_due_by": "2024-12-03T00:00:00",
          "dispute_reason": "SUBSCRIPTION_CANCELED",
          "dispute_schema": "MASTERCARD",
          "dispute_status": "OPEN",
          "organisation_id": "org_tmo8Dq484yRUiiAcJuRPd",
          "dispute_reason_code": null,
          "dispute_reference_id": null,
          "dispute_currency_code": "USD",
          "dispute_amount_in_cents": 4444,
          "transaction_reference_id": null,
          "transaction_currency_code": "USD",
          "transaction_amount_in_cents": 4444,
          "transaction_authorisation_date": "2024-11-12T00:00:00",
          "transaction_acquirer_reference_number": null
        }
      },
      "api_version": "v1"
    }
    {
      "id": "evt_2rzszUnkDUNFiBKqe6DdT",
      "type": "representment.updated",
      "created_at": "2025-05-22T20:14:51.041381+00:00",
      "data": {
        "object": {
          "id": "rep_wMxBaE4ivxQ7zvPy1dmNx",
          "created_at": "2025-05-22T19:08:25.245116Z",
          "managed_by": "PARTNER",
          "updated_at": "2025-05-22T20:14:51.004632Z",
          "disputed_at": "2024-11-19T00:00:00",
          "merchant_id": "mrch_bQXg83B18qgACnp5Y4qU8",
          "service_type": "ONLINE_SERVICES",
          "dispute_stage": "CHARGEBACK",
          "dispute_due_by": "2024-12-03T00:00:00",
          "dispute_reason": "SUBSCRIPTION_CANCELED",
          "dispute_schema": "MASTERCARD",
          "dispute_status": "LOST",
          "organisation_id": "org_tmo8Dq484yRUiiAcJuRPd",
          "dispute_reason_code": null,
          "dispute_reference_id": null,
          "dispute_currency_code": "USD",
          "dispute_amount_in_cents": 4444,
          "transaction_reference_id": null,
          "transaction_currency_code": "USD",
          "transaction_amount_in_cents": 4444,
          "transaction_authorisation_date": "2024-11-12T00:00:00",
          "transaction_acquirer_reference_number": null
        },
        "previous_attributes": {
          "dispute_status": "OPEN"
        }
      },
      "api_version": "v1"
    }
    {
      "id": "evt_dbXKdyUWLzSP98HMVdoFW",
      "type": "scheme_notice.created",
      "created_at": "2026-03-01T10:30:45.123456+00:00",
      "data": {
        "object": {
          "id": "schntc_NFSPZDSTv3QgfU8GDhXKK",
          "organisation_id": "org_WVJ7aJzpT32FED9BqKPpM",
          "merchant_id": "mrch_bQXg83B18qgACnp5Y4qU8",
          "scheme_notice_type": "TC40",
          "notice_type": "FRAUD_NOTICE",
          "scheme": "VISA",
          "is_revoked": false,
          "notice_revoked_at": null,
          "fraud_reported_at": "2026-02-21T08:13:50.360977Z",
          "transaction_amount_in_cents": 14760,
          "transaction_currency_code": "USD",
          "transaction_card_bin": "411798",
          "transaction_card_last4": "3508",
          "transaction_merchant_name": "ECOM-STUFF OUTLET",
          "transaction_merchant_id": "274953873887879",
          "transaction_acquirer_reference_number": "77198913101798678449413",
          "transaction_authorisation_code": "96JNEP",
          "transaction_original_date": "2026-02-11T08:13:50.360977Z",
          "transaction_purchase_date": "2026-02-11T08:13:50.360977Z",
          "fraud_type": "CARD_NOT_PRESENT",
          "fraud_dispute_eligible": true,
          "created_at": "2026-03-01T10:30:45.123456Z",
          "updated_at": "2026-03-01T10:30:45.123456Z"
        }
      },
      "api_version": "v1"
    }
    {
      "id": "evt_NUpgzGLGJTj5j1MZ6jb1d",
      "type": "scheme_notice.updated",
      "created_at": "2026-03-01T12:00:00.541381+00:00",
      "data": {
        "object": {
          "id": "schntc_NFSPZDSTv3QgfU8GDhXKK",
          "organisation_id": "org_WVJ7aJzpT32FED9BqKPpM",
          "merchant_id": "mrch_bQXg83B18qgACnp5Y4qU8",
          "scheme_notice_type": "TC40",
          "notice_type": "FRAUD_NOTICE",
          "scheme": "VISA",
          "is_revoked": true,
          "notice_revoked_at": "2026-03-01T12:00:00.000000Z",
          "fraud_reported_at": "2026-02-21T08:13:50.360977Z",
          "transaction_amount_in_cents": 14760,
          "transaction_currency_code": "USD",
          "transaction_card_bin": "411798",
          "transaction_card_last4": "3508",
          "transaction_merchant_name": "ECOM-STUFF OUTLET",
          "transaction_merchant_id": "274953873887879",
          "transaction_acquirer_reference_number": "77198913101798678449413",
          "transaction_authorisation_code": "96JNEP",
          "transaction_original_date": "2026-02-11T08:13:50.360977Z",
          "transaction_purchase_date": "2026-02-11T08:13:50.360977Z",
          "fraud_type": "CARD_NOT_PRESENT",
          "fraud_dispute_eligible": true,
          "created_at": "2026-03-01T10:30:45.123456Z",
          "updated_at": "2026-03-01T12:00:00.541381Z"
        },
        "previous_attributes": {
          "is_revoked": false,
          "notice_revoked_at": null
        }
      },
      "api_version": "v1"
    }
    {
      "id": "evt_dbXKdyUWLzSP98HMVdoFW",
      "type": "lookup.created",
      "created_at": "2026-03-12T10:30:45.123456+00:00",
      "data": {
        "object": {
          "id": "lkup_NFSPZDSTv3QgfU8GDhXKK",
          "organisation_id": "org_WVJ7aJzpT32FED9BqKPpM",
          "enrollment_id": "enrl_pfNupxFzfYDaEf1UrD6wU",
          "type": "ETHOCA_CONSUMER_CLARITY",
          "parent_lookup_id": null,
          "lookup_status": "SUCCEEDED",
          "deflection_status": "NOT_ATTEMPTED",
          "transaction_card_bin": "411798",
          "transaction_card_last4": "3508",
          "transaction_arn": "77198913101798678449413",
          "transaction_auth_code": "96JNEP",
          "transaction_amount": 14760,
          "transaction_currency": "USD",
          "transaction_date": "2026-03-10T08:13:50.360977Z",
          "transaction_statement_descriptor": "ECOM-STUFF.COM",
          "transaction_network_id": null,
          "integration_id": "int_ZSHVZukGYs5SdVcwkEZrL",
          "integration_transaction_id": "pi_3SPJO4KRFSLReU4y04XJUvLN",
          "created_at": "2026-03-12T10:30:45.123456Z",
          "updated_at": "2026-03-12T10:30:45.123456Z"
        }
      },
      "api_version": "v1"
    }
    {
      "id": "evt_NUpgzGLGJTj5j1MZ6jb1d",
      "type": "lookup.updated",
      "created_at": "2026-03-12T12:00:00.541381+00:00",
      "data": {
        "object": {
          "id": "lkup_NFSPZDSTv3QgfU8GDhXKK",
          "organisation_id": "org_WVJ7aJzpT32FED9BqKPpM",
          "enrollment_id": "enrl_pfNupxFzfYDaEf1UrD6wU",
          "type": "ETHOCA_FIRST_PARTY_TRUST",
          "parent_lookup_id": null,
          "lookup_status": "SUCCEEDED",
          "deflection_status": "SUCCEEDED",
          "transaction_card_bin": "411798",
          "transaction_card_last4": "3508",
          "transaction_arn": "77198913101798678449413",
          "transaction_auth_code": "96JNEP",
          "transaction_amount": 14760,
          "transaction_currency": "USD",
          "transaction_date": "2026-03-10T08:13:50.360977Z",
          "transaction_statement_descriptor": "ECOM-STUFF.COM",
          "transaction_network_id": null,
          "integration_id": "int_ZSHVZukGYs5SdVcwkEZrL",
          "integration_transaction_id": "pi_3SPJO4KRFSLReU4y04XJUvLN",
          "created_at": "2026-03-12T10:30:45.123456Z",
          "updated_at": "2026-03-12T12:00:00.541381Z"
        },
        "previous_attributes": {
          "deflection_status": "PENDING"
        }
      },
      "api_version": "v1"
    }

    Adding webhook endpoints

    In the partner dashboard

    In the organisation dashboard

    Delivery mechanism

    Request Details

    Reliability and retries

    Signature

    JavaScript signature verification function

    PHP signature verification function

    Python signature verification function

    Payloads

    Examples

    Enrolment webhooks (enrolment.created, enrolment.updated)

    Scheme notice webhooks (scheme_notice.created, scheme_notice.updated)

    Lookup webhooks (lookup.created, lookup.updated)

    Postman collection

    Verify the signature (v1=): If the timestamp is acceptable, construct the signature string on your end:
    • Use the timestamp from the t= part of the received X-Signature header.

    • Use the raw request body as the payload.

    • Concatenate them: "{timestamp_from_header}.{raw_request_body}".

    • Calculate the HMAC-SHA512 hash of this concatenated string using your webhook secret.

    • Convert the hash to its hexadecimal representation.

    • Compare this generated signature with the v1= value from the received X-Signature header. They must match exactly.

    If the timestamp is recent enough and your generated signature matches the one provided in the header, you can be confident the webhook is genuine, untampered, and not a replayed request.

    - present only in ‘updated’ events, contains a list of fields that changed and their previous values.
    https://api.chargebackstop.com/v1/docs#/Alerts/src_api_alerts_get_alerts

    Orders

    Submit order data to ChargebackStop for chargeback prevention and dispute resolution. This API powers integrations with Mastercard Consumer Clarity, Visa Order Insight, and chargeback alert matching.

    Base URL: https://api.chargebackstop.com/v1/orders/

    Authentication: Bearer token via API key. Required abilities vary by endpoint (all newly created API keys include these Orders abilities by default):

    • orders:read for GET endpoints

    • orders:write for POST endpoints

    • orders:update for PATCH endpoints

    Rate limits:

    • 100 requests per minute per endpoint, per organisation/partner group

    • Each endpoint has an independent rate limit pool (e.g., hitting the list limit doesn't affect create)

    • Rate limits are applied by owner (organisation or partner group), not by API key

    Batch Limit: Maximum 100 orders per request (POST only).


    Retrieve a paginated list of orders with optional filtering and sorting.

    Authentication: Bearer token via API key with orders:read ability.

    Parameter
    Type
    Description

    Retrieve a single order by its internal id (the id field returned in JSON responses), not by reference_id.

    To retrieve an order by reference_id, use the list endpoint: GET /v1/orders?reference_id=<your_reference_id>.

    Authentication: Bearer token via API key with orders:read ability.

    Parameter
    Type
    Description

    Returns the full order object with all nested relations (transactions, deliveries, items, refunds, subscriptions, disputes).

    404 Not Found - Order does not exist or is not accessible:


    Submit order data to ChargebackStop for chargeback prevention and dispute resolution.

    Authentication: Bearer token via API key with orders:write ability.

    Rate Limit: 100 requests per minute per organisation/partner group.

    Batch Limit: Maximum 100 orders per request.

    Request Body: JSON array of order objects (even when submitting a single order).

    Schema validation before partial success: Partial success applies after request schema validation. If the top-level request is invalid (for example, body is not an array or fields have invalid types), the API returns a full-request 422 and no orders are processed.


    Mode
    Use Case
    Integration Type

    Important: Order type and integration type must match

    • COMPLETE orders can ONLY be created with CUSTOM_ORDERS integrations. Attempting to create a COMPLETE order on a Stripe, Adyen, or other payment processor integration will return INVALID_ORDER_TYPE.

    • PARTIAL orders can ONLY be created with non-CUSTOM_ORDERS integrations (Stripe, Adyen, Shopify, etc.) and require orders enrichment to be enabled by ChargebackStop support. Attempting to create a PARTIAL order on a CUSTOM_ORDERS integration will return INVALID_ORDER_TYPE


    Use PARTIAL mode when you already have a payment processor integration (Stripe, Adyen, Shopify, etc.) connected to ChargebackStop and want to enrich your orders with additional data.

    Prerequisites:

    • An existing integration (Stripe, Adyen, etc.) with orders enrichment enabled by the ChargebackStop team

    • API key with orders:write ability

    Minimal required fields:

    Field
    Description

    Device identifier required: PARTIAL orders must include at least one of: device_ip_address, device_id, or device_fingerprint. This is used for fraud prevention and dispute evidence.

    Example 1: Basic PARTIAL Order


    These field sets are required for PARTIAL mode, and are required for all order modes when digital receipts or deflection is enabled.

    Examples below use PARTIAL payloads, but the same field sets can be included in COMPLETE orders.

    Consumer Clarity helps reduce chargebacks by providing cardholders with detailed purchase information in their banking app, making transactions more recognisable.

    Required fields for Consumer Clarity:

    Field
    Description

    Example 2: Consumer Clarity (Mastercard)


    Order Insight provides Visa cardholders with purchase details directly in their banking app, helping them recognise legitimate transactions.

    Required fields for Order Insight:

    Field
    Description

    Example 3: Order Insight (Visa)


    Some merchants (particularly Merchant of Record platforms) may need to include product and merchant information with each order if default settings are not configured in the platform.

    Note: If product and merchant information varies per order, include it in each order submission. If the values are stable across all orders, you can set defaults in the ChargebackStop platform instead.

    Product information fields:

    Field
    Description

    Merchant information fields:

    Field
    Description

    Example 4: Product and merchant information


    First-Party Trust is a Mastercard programme that helps identify legitimate transactions by linking customer identity data (email, device) across purchases. This strengthens fraud prevention and reduces first-party fraud chargebacks.

    Required fields for FPT:

    Field
    Description

    Example 5: First-Party Trust (Mastercard)


    Compelling Evidence 3.0 is a Visa programme that helps merchants win disputes by proving the cardholder has a history of legitimate purchases. By submitting customer and device data with each order, you build evidence that can be used in dispute responses.

    Required fields for CE3.0:

    Field
    Description

    Example 6: Compelling Evidence 3.0 (Visa)


    Use COMPLETE mode when you do not have an existing payment processor integration to enrich and want to submit full order data directly to ChargebackStop. This mode supports digital receipts, deflection, and alert matching, and is for merchants using the CUSTOM_ORDERS integration type.

    Prerequisites:

    • A CUSTOM_ORDERS integration

    • API key with orders:write ability

    Required fields for COMPLETE orders:

    Field
    Description

    To match orders with chargeback alerts, you must include at least one transaction with specific fields that enable accurate matching. The richer the data set you provide, the better the matching accuracy will be — we recommend including as many transaction fields as possible.

    Required transaction fields:

    Field
    Description

    Additional required fields for card payments:

    Field
    Description

    Matching identifiers (send all three whenever possible):

    Identifier
    Recommendation
    Notes

    For card payments, at least one matching identifier is required. Best practice is to send all three identifiers whenever available, or as many as possible.

    Why these fields matter:

    • ARN (Acquirer Reference Number): The most reliable identifier for matching - directly links to the network transaction

    • Authorisation Code: The 6-digit code from the issuer, used with card last 4 when ARN is not available

    • Card BIN: The first 6-8 digits of the card, helps narrow down matches when combined with other card details and amount

    Note: It is worth sending any related refunds and disputes for the order. Including these records helps us detect invalid alerts more accurately.

    Example 7: Alert matching (COMPLETE)


    This example includes all available fields for a COMPLETE order.


    Required column abbreviations:

    Abbreviation
    Feature

    Validation wording note:

    • Required means the field must be present in the request payload. It does not, by itself, imply a non-empty string value.

    • 1-255 chars means the API enforces a non-empty string.

    • Up to 255 chars means the API enforces only a maximum length, and an empty string may still be accepted when the field is otherwise optional.


    Field
    Type
    Required
    Validation
    Description
    Field
    Type
    Required
    Validation
    Description
    Field
    Type
    Required
    Validation
    Description
    Field
    Type
    Required
    Validation
    Description

    Field
    Type
    Required
    Validation
    Description

    Field
    Type
    Required
    Validation
    Description

    At least one device identifier is required for PARTIAL orders, and for FPT/CE3.0 when enabled.


    Field
    Type
    Required
    Validation
    Description
    Field
    Type
    Required
    Description

    Request/response shape: Both requests and responses use nested merchant_address.


    Limit: Maximum 10 transactions per order.

    At least one transaction is required for Alert Matching.

    Field
    Type
    Required
    Validation
    Description

    When payment_method_type is CARD, the following fields are required:

    Field
    Type
    Required
    Description

    Note: For alert matching with card payments, send all three identifiers whenever available (acquirer_reference_number, authorisation_code, and payment_method_card_bin). If you cannot provide all three, provide at least one of the following combinations:

    • acquirer_reference_number (works on its own)

    Field
    Type
    Required
    Description

    Limit: Maximum 10 deliveries per order.

    Field
    Type
    Required
    Description

    Create uniqueness scope: On POST, deliveries are unique per integration by reference_id. Reusing a delivery reference_id for the same integration returns DUPLICATE_DELIVERY.

    Field
    Type
    Required
    Description

    When type is PHYSICAL, the following fields are required:

    Field
    Type
    Required
    Description
    Field
    Type
    Required
    Description

    Limit: Maximum 10 items per order.

    Field
    Type
    Required
    Description

    Limit: Maximum 10 refunds per order.

    Field
    Type
    Required
    Description

    Create uniqueness scope: On POST, refunds are unique per integration by reference_id. Reusing a refund reference_id for the same integration returns DUPLICATE_REFUND.


    Limit: Maximum 10 subscriptions per order.

    Upsert behaviour: Subscriptions are identified by reference_id per integration. If a subscription with the same reference_id already exists, it will be updated with the new values. The subscription will be linked to the new order while maintaining links to previous orders. This allows the same subscription to span multiple orders (e.g., monthly renewals).

    Warning: Full replace semantics - When updating a subscription, ALL optional fields are replaced, not merged. If you omit a field in a subsequent request, it will be set to NULL. For example, if Order 1 creates a subscription with display_name: "Pro Plan" and Order 2 references the same subscription without display_name, the display name will be cleared.

    Field
    Type
    Required
    Description

    Limit: Maximum 10 disputes per order.

    Field
    Type
    Required
    Description

    Create uniqueness scope: On POST, disputes are unique per integration by reference_id. Reusing a dispute reference_id for the same integration returns DUPLICATE_DISPUTE.


    All address objects (billing, shipping, merchant) use this structure:

    Field
    Type
    Required
    Validation

    Note: When providing an address, include at least one of line_1, line_2, or line_3, plus city, country_subdivision, postal_code, and country.


    All currency fields must be valid ISO 4217 codes. Common examples: USD, EUR, GBP, CAD, AUD, JPY. See the for the full list.

    Phone fields must be in E.164 format:

    • Start with +

    • Followed by 1-15 digits

    • No spaces or special characters

    Valid: +14155551234, +442071234567 Invalid: 415-555-1234, (415) 555-1234

    All email fields are validated for proper email format.

    All *_in_cents fields must be non-negative integers (>= 0).


    Code
    Description

    The API uses partial success semantics for per-order processing: valid orders are created even if other orders in the same batch fail. Each order is processed independently, and failures do not cause a rollback of successfully created orders.

    This behaviour applies after request schema validation. Schema-level validation failures return a full-request 422 response and skip per-order processing.

    The response includes:

    • created: Number of orders successfully created

    • failed: Number of orders that failed validation

    • results: Array of successfully created orders

    Returned when you exceed 100 requests per minute for the endpoint.

    Successful GET /v1/orders, GET /v1/orders/{order_id}, POST /v1/orders, and PATCH /v1/orders/{order_id} responses all use the same canonical order object shape.

    Each order object includes:

    • Core fields: id, reference_id, type, organisation_id, integration_id, created_at

    • Any documented order, customer, device, and merchant fields that are present for that order

    Each nested object includes its own server-generated id plus the documented fields for that resource.


    Partially update an existing order and its nested objects.

    Authentication: Bearer token via API key with orders:update ability.

    URL parameters:

    • order_id (required): The order ID to update


    All fields are optional. Only provided fields will be updated.

    Field
    Type
    Description

    Update deliveries that belong to the order. Each delivery is identified by reference_id.

    Important:

    • Only deliveries belonging to this order can be updated

    • Delivery type (DIGITAL or PHYSICAL) cannot be changed after creation

    • Fields are type-constrained: digital fields only work on DIGITAL deliveries, physical fields only work on

    Field
    Type
    Description

    If you include physical_shipping_address in a PATCH request, send a complete valid address object rather than a partial address fragment.

    Example 9: Update physical delivery status


    Update existing subscriptions by reference_id. Only subscriptions that already exist can be updated - to create new subscriptions, use the POST endpoint when creating an order.

    Field
    Type
    Required
    Description

    Example 10: Update subscription status


    Create new refunds or update existing refunds. For existing refunds, amount_in_cents and currency are immutable, while status, original_transaction_reference_id, and refund_datetime can be updated.

    Field
    Type
    Required
    Description

    Example 11: Create new refund

    Example 12: Update existing refund status


    Create new disputes or update existing disputes. For existing disputes, amount_in_cents, currency, and type are immutable, while stage, status, network_reason_code, is_rapid_dispute_resolution, evidence_due_by, payment_method_type, and card_brand can be updated.

    Field
    Type
    Required
    Description

    Example 13: Update dispute status


    Code
    Description

    Returns the updated order with all nested objects.

    Success Response (200)

    Error Response (422)

    Not Found Response (404)

    Exceeding the limit returns 429 Too Many Requests

    string

    Filter by exact reference_id

    type

    string

    Filter by order type: COMPLETE or PARTIAL

    order_status

    string

    Filter by status: OPEN_PENDING, OPEN_PENDING_RETURN, CLOSED_COMPLETE, CLOSED_CANCELLED, OTHER

    created_at_gte

    datetime

    Orders created on or after this timestamp (ISO 8601)

    created_at_lte

    datetime

    Orders created on or before this timestamp (ISO 8601)

    sort

    string

    Sort field: created_at (oldest first), -created_at (newest first, default), order_datetime, -order_datetime

    limit

    integer

    Number of results per page (default: 100)

    offset

    integer

    Number of results to skip for pagination

    .

    Unique order identifier

    order_email

    Email associated with the order

    customer_account_id

    Customer identifier (email, username, or account ID)

    Currency code (ISO 4217)

    order_total_amount_in_cents

    Total amount including tax

    Merchant website URL

    Unique order identifier

    order_datetime

    When the order was placed

    order_number

    Customer-facing order number

    order_subtotal_amount_in_cents

    Subtotal before tax

    order_currency

    Currency code (ISO 4217)

    order_total_amount_in_cents

    Total amount

    order_status

    Order status

    Payment method (e.g., CARD)

    authorisation_status

    Status (e.g., SETTLED)

    Send whenever available

    Improves matching when combined with card details and amount/currency

    Compelling Evidence 3.0 (Visa)

    string

    Yes

    Valid org ID

    Your organisation ID

    integration_id

    string

    Yes

    Valid integration ID

    Integration ID

    reference_id

    string

    Yes

    1-255 chars

    Unique order identifier

    string

    COMPLETE orders, and for CC when enabled

    Up to 255 chars

    Customer-facing order number

    order_subtotal_amount_in_cents

    integer

    COMPLETE orders, and for CC when enabled

    >= 0

    Subtotal before tax

    order_currency

    string

    COMPLETE orders, and for CC when enabled

    ISO 4217

    Currency code

    order_tax_amount_in_cents

    integer

    No

    >= 0

    Tax amount

    order_total_amount_in_cents

    integer

    COMPLETE orders, and for CC when enabled

    >= 0

    Total amount

    order_status

    enum

    COMPLETE orders

    OPEN_PENDING, OPEN_PENDING_RETURN, CLOSED_COMPLETE, CLOSED_CANCELLED, OTHER

    Order status

    order_status_other_description

    string

    If order_status is OTHER

    1-255 chars

    Description when status is OTHER

    order_phone

    string

    No

    E.164 format

    Order contact phone

    order_is_adult_content

    boolean

    No

    -

    Adult content flag

    string

    No

    Valid URL, up to 255 chars

    Reorder URL

    order_write_review_url

    string

    No

    Valid URL, up to 255 chars

    Review URL

    order_view_url

    string

    No

    Valid URL, up to 255 chars

    Order view URL

    string

    No

    Up to 1000 chars

    Communications history

    string

    No

    Up to 255 chars

    First name

    customer_last_name

    string

    No

    Up to 255 chars

    Last name

    customer_account_id

    string

    PARTIAL orders

    Up to 255 chars

    Customer identifier

    order_email

    string

    PARTIAL orders, and for FPT when enabled

    Valid email

    Order email

    string

    PARTIAL orders, and for FPT/CE3.0 when enabled (at least one)

    Up to 255 chars

    Device ID

    device_fingerprint

    string

    PARTIAL orders, and for FPT/CE3.0 when enabled (at least one)

    Up to 255 chars

    Device fingerprint

    string

    When default merchant not configured

    Up to 255 chars

    Corporate name

    merchant_store_name

    string

    When default merchant not configured

    Up to 255 chars

    Store name

    merchant_store_description

    string

    No

    Up to 255 chars

    Store description

    merchant_contact_email

    string

    No

    Valid email

    Receipt email

    merchant_customer_service_email

    string

    No

    Valid email

    Support email

    merchant_contact_phone

    string

    When default merchant not configured

    E.164

    Support phone

    merchant_url

    string

    When default merchant not configured

    URL

    Merchant URL

    merchant_store_url

    string

    No

    URL

    Store URL

    merchant_terms_and_conditions_url

    string

    No

    URL

    T&C URL

    merchant_logo_url

    string

    No

    URL

    Logo URL

    merchant_refund_policy_url

    string

    No

    URL

    Refund policy URL

    Address line 2

    merchant_address.line_3

    string

    At least one line required when merchant_address is provided

    Address line 3

    merchant_address.city

    string

    Required when merchant_address is provided

    City

    merchant_address.country_subdivision

    string

    Required when merchant_address is provided

    State/province

    merchant_address.postal_code

    string

    Required when merchant_address is provided

    Postal code

    merchant_address.country

    string

    Required when merchant_address is provided

    Country code

    integer

    Always

    >= 0

    Amount

    currency

    string

    Always

    ISO 4217

    Currency

    payment_method_type

    enum

    Always

    CARD, STRIPE_LINK, BANK_ACCOUNT, OTHER

    Payment method

    authorisation_status

    enum

    Always

    AUTHORISED, CAPTURED, SETTLED, REVERTED

    Auth status

    payment_method_reference_id

    string

    Always

    Up to 255 chars

    Payment method ID

    authorised_at

    datetime

    For Alert Matching

    ISO 8601

    Auth timestamp

    descriptor

    string

    No

    Up to 255 chars

    Billing descriptor

    descriptor_prefix

    string

    No

    Up to 255 chars

    Descriptor prefix

    descriptor_suffix

    string

    No

    Up to 255 chars

    Descriptor suffix

    authorisation_code

    string

    For Alert Matching (CARD, at least one)

    Up to 6 chars

    Auth code

    acquirer_reference_number

    string

    For Alert Matching (CARD, at least one)

    50 chars

    ARN

    network_id

    string

    No

    50 chars

    Network transaction identifier

    settlement_datetime

    datetime

    No

    ISO 8601

    Settlement time

    cvc_verified

    boolean

    No

    -

    CVC verified

    three_d_secure_verified

    boolean

    No

    -

    3DS verified

    Last 4 digits

    payment_method_card_exp_month

    integer

    No

    Exp month

    payment_method_card_exp_year

    integer

    No

    Exp year

    payment_method_card_bin

    string

    For Alert Matching (at least one identifier)

    Card BIN

    payment_method_card_wallet_type

    enum

    No

    AMEX_EXPRESS_CHECKOUT, APPLE_PAY, GOOGLE_PAY, LINK, MASTERPASS, SAMSUNG_PAY, VISA_CHECKOUT, REVOLUT_PAY, OTHER

    payment_method_card_issuer

    string

    No

    Card issuer

    authorisation_code + payment_method_card_last_4
  • payment_method_card_bin + payment_method_card_last_4 + payment_method_card_brand + amount_in_cents + currency

  • Address line 2

    billing_address.line_3

    string

    At least one line required when billing_address is provided

    Address line 3

    billing_address.city

    string

    Required when billing_address is provided

    City

    billing_address.country_subdivision

    string

    Required when billing_address is provided

    State/province

    billing_address.postal_code

    string

    Required when billing_address is provided

    Postal code

    billing_address.country

    string

    Required when billing_address is provided

    Country code

    DIGITAL or PHYSICAL

    Download start

    digital_download_end_datetime

    datetime

    No

    Download end

    digital_delivery_ip_address

    string

    No

    Download IP

    digital_notification_sent

    boolean

    No

    Notification sent

    digital_notification_sent_datetime

    datetime

    No

    Notification time

    digital_notification_method

    enum

    No

    EMAIL, SMS, PUSH, OTHER

    Tracking number

    physical_shipping_status

    enum

    If type is PHYSICAL

    NOT_SHIPPED, BACKORDERED, IN_TRANSIT, PARTIAL_SHIPPED, SHIPPED, CANCELLED, SHIPPING_EXCEPTION, PICKED_UP_BY_CUSTOMER, DELIVERED, OTHER

    physical_shipping_status_other_description

    string

    If physical_shipping_status is OTHER

    Description when status is OTHER

    physical_shipping_datetime_shipped

    datetime

    If type is PHYSICAL

    Ship date

    physical_shipping_datetime_delivered

    datetime

    No

    Delivery date

    Address line 2

    physical_shipping_address.line_3

    string

    At least one line required when physical_shipping_address is provided

    Address line 3

    physical_shipping_address.city

    string

    Required when physical_shipping_address is provided

    City

    physical_shipping_address.country_subdivision

    string

    Required when physical_shipping_address is provided

    State/province

    physical_shipping_address.postal_code

    string

    Required when physical_shipping_address is provided

    Postal code

    physical_shipping_address.country

    string

    Required when physical_shipping_address is provided

    Country code

    Product name

    price_in_cents

    integer

    Yes

    Price in cents (≥ 0)

    quantity

    integer

    Yes

    Quantity (≥ 1)

    product_url

    string

    No

    Product URL

    product_reference_id

    string

    No

    Internal product ID

    sku

    string

    No

    SKU

    delivery_reference_id

    string

    No

    Links to delivery (must reference a delivery in the same request)

    subscription_reference_id

    string

    No

    Links to subscription (must reference a subscription in the same request)

    Refund amount

    currency

    string

    Always

    Currency

    status

    enum

    Always

    PENDING, SUCCEEDED, FAILED

    original_transaction_reference_id

    string

    No

    Links to transaction

    refund_datetime

    datetime

    For CC when enabled

    When the refund was processed (ISO 8601)

    DAY, WEEK, MONTH, YEAR

    interval_price_in_cents

    integer

    Always

    Price per interval

    interval_currency

    string

    Always

    Currency

    status

    enum

    No

    ACTIVE, CANCELLED, TRIALING, PAST_DUE

    display_name

    string

    No

    Display name (up to 255 chars)

    trial_start_date

    datetime

    No

    Trial start

    trial_end_date

    datetime

    No

    Trial end

    trial_price_in_cents

    integer

    No

    Trial price

    trial_currency

    string

    No

    Trial currency

    start_date

    datetime

    No

    Subscription start

    cancellation_date

    datetime

    No

    Cancellation date

    next_charge_date

    datetime

    No

    Next billing date

    Dispute amount

    currency

    string

    Always

    Currency

    stage

    enum

    Always

    1ST_CHARGEBACK, 2ND_CHARGEBACK

    status

    enum

    Always

    OPEN, UNDER_REVIEW, WON, LOST

    type

    enum

    Always

    INQUIRY, CHARGEBACK

    network_reason_code

    string

    No

    Network reason code

    is_rapid_dispute_resolution

    boolean

    No

    RDR flag

    evidence_due_by

    datetime

    No

    Evidence deadline

    payment_method_type

    enum

    No

    CARD, KLARNA, PAYPAL

    card_brand

    enum

    If payment_method_type is CARD

    AMEX, DINERS, DISCOVER, EFTPOS_AU, JCB, MASTERCARD, UNIONPAY, VISA, CARTES_BANCAIRES, OTHER

    Up to 255 chars

    line_3

    string

    At least one line required

    Up to 255 chars

    city

    string

    Always

    1-255 chars

    country_subdivision

    string

    Always

    1-255 chars

    postal_code

    string

    Always

    1-255 chars

    country

    string

    Always

    ISO 3166-1 alpha-2 uppercase code

    Duplicate reference_id in deliveries array (within same request)

    DUPLICATE_DISPUTE

    Dispute with same reference_id already exists for this integration

    DUPLICATE_DISPUTE_REFERENCE

    Duplicate reference_id in disputes array (within same request)

    DUPLICATE_ITEM

    Item with same reference_id already exists for this integration

    DUPLICATE_ITEM_REFERENCE

    Duplicate reference_id in items array (within same request)

    DUPLICATE_ORDER

    Order with same reference_id already exists for this integration

    DUPLICATE_REFERENCE_ID

    Fallback error when a duplicate reference_id is detected

    DUPLICATE_REFUND

    Refund with same reference_id already exists for this integration

    DUPLICATE_REFUND_REFERENCE

    Duplicate reference_id in refunds array (within same request)

    DUPLICATE_SUBSCRIPTION_REFERENCE

    Duplicate reference_id in subscriptions array (within same request)

    DUPLICATE_TRANSACTION

    Transaction with same reference_id already exists for this integration

    DUPLICATE_TRANSACTION_REFERENCE

    Duplicate reference_id in transactions array (within same request)

    ENRICHMENT_NOT_ENABLED

    Orders enrichment is not enabled for a non-CUSTOM_ORDERS integration when submitting a PARTIAL order

    INTERNAL_ERROR

    Internal server error

    INVALID_DELIVERY_REFERENCE

    Item references a non-existent delivery

    INVALID_INTEGRATION

    Integration not found or not accessible

    INVALID_ORDER_TYPE

    Order type doesn't match integration type

    INVALID_SUBSCRIPTION_REFERENCE

    Item references a non-existent subscription

    MISSING_FIELD

    Required field is missing for the configured integration

    DELIVERY_NOT_FOUND

    Referenced delivery not found in order (PATCH only)

    IMMUTABLE_FIELD

    Attempting to modify immutable fields on existing refund/dispute records (amount_in_cents, currency, and for disputes also type) (PATCH only)

    INVALID_FIELD_FOR_TYPE

    Updating wrong type fields on delivery (PATCH only)

    SUBSCRIPTION_NOT_FOUND

    Referenced subscription not found (PATCH only)

    TOO_MANY_DELIVERIES

    Maximum 10 deliveries allowed per order

    TOO_MANY_DISPUTES

    Maximum 10 disputes allowed per order

    TOO_MANY_ITEMS

    Maximum 10 items allowed per order

    TOO_MANY_REFUNDS

    Maximum 10 refunds allowed per order

    TOO_MANY_SUBSCRIPTIONS

    Maximum 10 subscriptions allowed per order

    TOO_MANY_TRANSACTIONS

    Maximum 10 transactions allowed per order

    errors: Array of error details for failed orders

    Nested arrays: transactions, deliveries, items, refunds, subscriptions, disputes

    string

    Updated communications history

    deliveries

    array

    Deliveries to update (by reference_id)

    subscriptions

    array

    Subscriptions to update (by reference_id)

    refunds

    array

    Refunds to create/update

    disputes

    array

    Disputes to create/update

    PHYSICAL
    deliveries

    various

    For PHYSICAL deliveries only

    physical_shipping_address

    object

    Full address object. If provided, it must satisfy the shared address schema.

    DAY, WEEK, MONTH, YEAR

    interval_price_in_cents

    integer

    No

    Price per interval

    interval_currency

    string

    No

    ISO 4217 currency code

    status

    enum

    No

    ACTIVE, CANCELLED, TRIALING, PAST_DUE

    display_name

    string

    No

    Display name (up to 255 chars)

    Other fields

    various

    No

    See subscription fields in POST documentation

    Refund amount (immutable on existing)

    currency

    string

    New only

    Currency code (immutable on existing)

    status

    enum

    Yes

    PENDING, SUCCEEDED, FAILED

    original_transaction_reference_id

    string

    No

    Related transaction

    refund_datetime

    datetime

    No

    When the refund was processed (ISO 8601)

    Dispute amount (immutable on existing)

    currency

    string

    New only

    Currency code (immutable on existing)

    type

    enum

    New only

    INQUIRY, CHARGEBACK (immutable on existing)

    stage

    enum

    Yes

    1ST_CHARGEBACK, 2ND_CHARGEBACK

    status

    enum

    Yes

    OPEN, UNDER_REVIEW, WON, LOST

    Other fields

    various

    No

    See dispute fields in POST documentation

    Duplicate reference_id in refunds array

    DUPLICATE_SUBSCRIPTION_REFERENCE

    Duplicate reference_id in subscriptions array

    IMMUTABLE_FIELD

    Attempting to modify immutable fields on existing refund/dispute records (amount_in_cents, currency, and for disputes also type)

    INVALID_FIELD_FOR_TYPE

    Updating wrong type fields on delivery (e.g., physical fields on digital delivery)

    MISSING_FIELD

    New refund/dispute missing required fields

    SUBSCRIPTION_NOT_FOUND

    Referenced subscription not found

    TOO_MANY_DELIVERIES

    Maximum 10 deliveries allowed per order

    TOO_MANY_DISPUTES

    Maximum 10 disputes allowed per order (including existing + new)

    TOO_MANY_REFUNDS

    Maximum 10 refunds allowed per order (including existing + new)

    TOO_MANY_SUBSCRIPTIONS

    Maximum 10 subscriptions allowed per order

    organisation_id

    string

    Filter by organisation ID

    integration_id

    string

    Filter by integration ID

    order_id

    string

    The internal order ID (e.g., ord_abc123)

    PARTIAL

    You have an existing payment processor integration (Stripe, Adyen, etc.) and want to submit enrichment data linked to those processor transactions

    Any non-CUSTOM_ORDERS integration

    COMPLETE

    You do not have an existing payment processor integration to enrich and want to submit full order data directly (for digital receipts, deflection, or alert matching)

    CUSTOM_ORDERS integration only

    type

    Must be "PARTIAL"

    organisation_id

    Your organisation ID

    integration_id

    Your integration ID

    order_datetime

    When the order was placed (ISO 8601)

    order_number

    Customer-facing order number

    order_subtotal_amount_in_cents

    Subtotal before tax

    items

    Array with at least one item containing name

    items[].name

    Product name

    items[].price_in_cents

    Item price

    items[].quantity

    Quantity ordered

    merchant_name

    Corporate/parent company name

    merchant_contact_phone

    Customer service phone (E.164 format)

    merchant_store_name

    Store name recognisable to customer

    customer_email

    Customer's email address

    order_email

    Email associated with the order

    Device identifier

    At least one of: device_ip_address, device_id, or device_fingerprint

    customer_email

    Customer's email address

    Device identifier

    At least one of: device_ip_address, device_id, or device_fingerprint

    type

    Must be "COMPLETE"

    organisation_id

    Your organisation ID

    integration_id

    Your CUSTOM_ORDERS integration ID

    amount_in_cents

    Transaction amount

    currency

    Currency code

    authorised_at

    When authorisation occurred

    payment_method_card_last_4

    Last 4 digits of card

    payment_method_card_brand

    Card brand (e.g., VISA)

    acquirer_reference_number

    Send whenever available

    Most reliable; directly links to the network transaction

    authorisation_code

    Send whenever available

    Improves matching when paired with card details (especially payment_method_card_last_4)

    CC

    Consumer Clarity (Mastercard)

    FPT

    First Party Trust (Mastercard)

    OI

    Order Insight (Visa)

    type

    string

    Yes

    COMPLETE or PARTIAL

    Order type discriminator

    order_datetime

    datetime

    COMPLETE orders, and for CC when enabled

    ISO 8601

    When the order was placed

    order_request_refund_url

    string

    No

    Valid URL, up to 255 chars

    Refund request URL

    order_proof_of_consent

    string

    No

    Up to 500 chars

    Proof of customer consent

    customer_email

    string

    For FPT, CE3.0

    Valid email

    Customer's email

    device_ip_address

    string

    PARTIAL orders, and for FPT/CE3.0 when enabled (at least one)

    IPv4/IPv6

    Customer's IP

    merchant_reference_id

    string

    No

    Up to 255 chars

    Internal merchant reference

    merchant_address.line_1

    string

    At least one line required when merchant_address is provided

    Address line 1

    merchant_address.line_2

    string

    reference_id

    string

    Always

    1-255 chars

    Transaction ID (unique within the integration)

    payment_method_card_brand

    enum

    If payment_method_type is CARD

    AMEX, DINERS, DISCOVER, EFTPOS_AU, JCB, MASTERCARD, UNIONPAY, VISA, CARTES_BANCAIRES, OTHER

    payment_method_card_last_4

    string

    billing_address.line_1

    string

    At least one line required when billing_address is provided

    Address line 1

    billing_address.line_2

    string

    reference_id

    string

    Always

    Delivery ID (unique within the integration)

    type

    enum

    digital_delivery_datetime

    datetime

    No

    Delivery time

    digital_download_start_datetime

    datetime

    physical_shipping_carrier

    string

    No

    Carrier name

    physical_shipping_tracking_number

    string

    physical_shipping_address.line_1

    string

    At least one line required when physical_shipping_address is provided

    Address line 1

    physical_shipping_address.line_2

    string

    reference_id

    string

    Yes

    Item ID (unique within the integration)

    name

    string

    reference_id

    string

    Always

    Refund ID (unique within the integration)

    amount_in_cents

    integer

    reference_id

    string

    Always

    Subscription ID (unique per integration)

    interval

    enum

    reference_id

    string

    Always

    Dispute ID (unique within the integration)

    amount_in_cents

    integer

    line_1

    string

    At least one line required

    Up to 255 chars

    line_2

    string

    RATE_LIMITED

    Rate limit exceeded (100 requests/min per endpoint)

    BATCH_SIZE_EXCEEDED

    More than 100 orders in request

    DUPLICATE_DELIVERY

    Delivery with same reference_id already exists for this integration

    order_status

    enum

    New order status

    order_status_other_description

    string

    Required when order_status is OTHER

    reference_id

    string

    Required. Delivery to update

    digital_* fields

    various

    For DIGITAL deliveries only

    reference_id

    string

    Yes

    Subscription identifier

    interval

    enum

    reference_id

    string

    Yes

    Refund identifier

    amount_in_cents

    integer

    reference_id

    string

    Yes

    Dispute identifier

    amount_in_cents

    integer

    DELIVERY_NOT_FOUND

    Referenced delivery not found in this order

    DUPLICATE_DELIVERY_REFERENCE

    Duplicate reference_id in deliveries array

    DUPLICATE_DISPUTE_REFERENCE

    Duplicate reference_id in disputes array

    GET /v1/orders - List Orders

    Query parameters

    Example request

    Example response

    GET /v1/orders/{order_id} - Get Order by ID

    URL parameters

    Example request

    Example response

    Error responses

    POST /v1/orders - Create Orders

    Which mode should I use?

    PARTIAL mode - enrichment for existing integrations

    Getting started

    Digital receipts and deflection field sets

    Mastercard Consumer Clarity

    Visa Order Insight

    Product and merchant information

    First-Party Trust (FPT) - Mastercard

    Compelling Evidence 3.0 (CE3.0) - Visa

    COMPLETE mode

    Getting started

    Alert matching

    Example 8: Full COMPLETE Order

    API reference

    Order fields

    Core fields

    Order details

    Order URLs

    Order evidence

    Customer fields

    Device fields

    Merchant fields

    Merchant address

    Transactions

    Card payment fields

    Billing address

    Deliveries

    Digital delivery fields

    Physical delivery fields

    Physical shipping address

    Items

    Refunds

    Subscriptions

    Disputes

    Address schema

    Field validation

    Currency codes

    Phone numbers

    Email addresses

    Amounts

    Error codes

    Response format

    Success response

    Error response

    Rate-limited response (429)

    Canonical order object

    PATCH /v1/orders/{order_id} - Update an Order

    Request body

    Delivery updates

    Subscription updates

    Refund updates

    Dispute updates

    PATCH error codes

    PATCH response

    ISO 4217 standard

    reference_id

    reference_id

    order_currency

    merchant_url

    reference_id

    payment_method_type

    payment_method_card_bin

    CE3.0

    organisation_id

    order_number

    order_buy_again_url

    order_communications

    customer_first_name

    device_id

    merchant_name

    At least one line required when merchant_address is provided

    amount_in_cents

    If payment_method_type is CARD

    At least one line required when billing_address is provided

    No

    No

    No

    At least one line required when physical_shipping_address is provided

    Yes

    Always

    Always

    Always

    At least one line required

    DUPLICATE_DELIVERY_REFERENCE

    order_communications

    physical_* fields

    No

    New only

    New only

    DUPLICATE_REFUND_REFERENCE

    curl -X GET "https://api.chargebackstop.com/v1/orders/?reference_id=order-2024-001&sort=-created_at&limit=10" \
      -H "Authorization: Bearer <api_key>"
    {
      "items": [
        {
          "id": "ord_abc123",
          "reference_id": "order-2024-001",
          "type": "COMPLETE",
          "organisation_id": "org_xyz",
          "integration_id": "int_123",
          "created_at": "2024-01-15T10:30:00Z",
          "order_datetime": "2024-01-15T10:30:00Z",
          "order_number": "ORD-2024-001",
          "order_status": "CLOSED_COMPLETE",
          "order_currency": "USD",
          "order_total_amount_in_cents": 9720,
          "transactions": [...],
          "deliveries": [...],
          "items": [...],
          "refunds": [...],
          "subscriptions": [...],
          "disputes": [...],
          "links": [
            {
              "rel": "self",
              "uri": "/v1/orders/ord_abc123"
            }
          ]
        }
      ],
      "count": 1
    }
    curl -X GET "https://api.chargebackstop.com/v1/orders/ord_abc123" \
      -H "Authorization: Bearer <api_key>"
    {
      "id": "ord_abc123",
      "reference_id": "order-2024-001",
      "type": "COMPLETE",
      "organisation_id": "org_xyz",
      "integration_id": "int_123",
      "created_at": "2024-01-15T10:30:00Z",
      "order_datetime": "2024-01-15T10:30:00Z",
      "order_number": "ORD-2024-001",
      "order_status": "CLOSED_COMPLETE",
      "order_currency": "USD",
      "order_total_amount_in_cents": 9720,
      "customer_email": "[email protected]",
      "transactions": [...],
      "deliveries": [...],
      "items": [...],
      "refunds": [...],
      "subscriptions": [...],
      "disputes": [...],
      "links": [
        {
          "rel": "self",
          "uri": "/v1/orders/ord_abc123"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "NOT_FOUND",
          "message": "Not found"
        }
      ]
    }
    [
      {
        "type": "PARTIAL",
        "organisation_id": "org_abc123",
        "integration_id": "int_stripe456",
        "reference_id": "order-2024-001",
        "order_email": "[email protected]",
        "customer_account_id": "[email protected]",
        "device_ip_address": "216.24.60.17"
      }
    ]
    [
      {
        "type": "PARTIAL",
        "organisation_id": "org_abc123",
        "integration_id": "int_stripe456",
        "reference_id": "order-2024-001",
        "order_email": "[email protected]",
        "customer_account_id": "cust-12345",
        "device_ip_address": "216.24.60.83",
    
        "order_datetime": "2024-01-15T10:30:00Z",
        "order_number": "ORD-2024-001",
        "order_subtotal_amount_in_cents": 4500,
        "order_currency": "USD",
        "order_total_amount_in_cents": 4950
      }
    ]
    [
      {
        "type": "PARTIAL",
        "organisation_id": "org_abc123",
        "integration_id": "int_stripe456",
        "reference_id": "order-2024-001",
        "order_email": "[email protected]",
        "customer_account_id": "cust-12345",
        "device_ip_address": "216.24.60.142",
    
        "items": [
          {
            "reference_id": "item-001",
            "name": "Widget Pro",
            "price_in_cents": 4500,
            "quantity": 1
          }
        ]
      }
    ]
    [
      {
        "type": "PARTIAL",
        "organisation_id": "org_abc123",
        "integration_id": "int_stripe456",
        "reference_id": "order-2024-001",
        "order_email": "[email protected]",
        "customer_account_id": "cust-12345",
        "device_ip_address": "216.24.60.201",
    
        "merchant_name": "Example Corporation",
        "merchant_contact_phone": "+14155551234",
        "merchant_store_name": "Example Store",
        "merchant_url": "https://example.com",
    
        "items": [
          {
            "reference_id": "item-001",
            "name": "Widget Pro",
            "price_in_cents": 4500,
            "quantity": 1
          }
        ]
      }
    ]
    [
      {
        "type": "PARTIAL",
        "organisation_id": "org_abc123",
        "integration_id": "int_stripe456",
        "reference_id": "order-2024-001",
    
        "customer_email": "[email protected]",
        "order_email": "[email protected]",
        "customer_account_id": "cust-12345",
    
        "device_ip_address": "216.24.60.58",
        "device_id": "device-abc123",
        "device_fingerprint": "fp-xyz789"
      }
    ]
    [
      {
        "type": "PARTIAL",
        "organisation_id": "org_abc123",
        "integration_id": "int_stripe456",
        "reference_id": "order-2024-001",
    
        "customer_email": "[email protected]",
        "order_email": "[email protected]",
        "customer_account_id": "cust-12345",
    
        "device_ip_address": "216.24.60.229",
        "device_fingerprint": "fp-xyz789"
      }
    ]
    [
      {
        "type": "COMPLETE",
        "organisation_id": "org_abc123",
        "integration_id": "int_custom789",
        "reference_id": "order-2024-001",
    
        "order_datetime": "2024-01-15T10:30:00Z",
        "order_number": "ORD-2024-001",
        "order_subtotal_amount_in_cents": 9000,
        "order_currency": "USD",
        "order_tax_amount_in_cents": 720,
        "order_total_amount_in_cents": 9720,
        "order_status": "CLOSED_COMPLETE",
    
        "customer_email": "[email protected]",
        "customer_first_name": "John",
        "customer_last_name": "Doe",
    
        "transactions": [
          {
            "reference_id": "txn-001",
            "amount_in_cents": 9720,
            "currency": "USD",
            "payment_method_type": "CARD",
            "authorisation_status": "SETTLED",
            "payment_method_reference_id": "pm_card_abc123",
            "authorised_at": "2024-01-15T10:30:05Z",
            "descriptor": "EXAMPLE STORE",
            "descriptor_prefix": "EXAMPLE",
            "descriptor_suffix": "STORE",
            "settlement_datetime": "2024-01-16T00:00:00Z",
            "cvc_verified": true,
            "three_d_secure_verified": true,
    
            "acquirer_reference_number": "74027012345678901234567",
            "authorisation_code": "123456",
            "network_id": "network-txn-123",
    
            "payment_method_card_brand": "VISA",
            "payment_method_card_last_4": "4242",
            "payment_method_card_bin": "424242",
            "payment_method_card_exp_month": 12,
            "payment_method_card_exp_year": 2026,
            "payment_method_card_wallet_type": "APPLE_PAY",
            "payment_method_card_issuer": "Chase Bank",
            "billing_address": {
              "line_1": "123 Main St",
              "line_2": "Apt 4B",
              "city": "New York",
              "country_subdivision": "NY",
              "postal_code": "10001",
              "country": "US"
            }
          }
        ],
    
        "refunds": [
          {
            "reference_id": "refund-001",
            "amount_in_cents": 4500,
            "currency": "USD",
            "status": "SUCCEEDED",
            "original_transaction_reference_id": "txn-001",
            "refund_datetime": "2024-01-17T12:00:00Z"
          }
        ],
    
        "disputes": [
          {
            "reference_id": "dispute-001",
            "amount_in_cents": 4500,
            "currency": "USD",
            "stage": "1ST_CHARGEBACK",
            "status": "OPEN",
            "type": "CHARGEBACK",
            "network_reason_code": "10.4",
            "is_rapid_dispute_resolution": false,
            "evidence_due_by": "2024-02-15T23:59:59Z",
            "payment_method_type": "CARD",
            "card_brand": "VISA"
          }
        ]
      }
    ]
    [
      {
        "type": "COMPLETE",
        "organisation_id": "org_abc123",
        "integration_id": "int_custom789",
        "reference_id": "order-2024-001",
    
        "order_datetime": "2024-01-15T10:30:00Z",
        "order_number": "ORD-2024-001",
        "order_subtotal_amount_in_cents": 9000,
        "order_currency": "USD",
        "order_tax_amount_in_cents": 720,
        "order_total_amount_in_cents": 9720,
        "order_status": "CLOSED_COMPLETE",
        "order_phone": "+14155551234",
        "order_is_adult_content": false,
    
        "order_request_refund_url": "https://example.com/orders/ORD-2024-001/refund",
        "order_buy_again_url": "https://example.com/orders/ORD-2024-001/reorder",
        "order_write_review_url": "https://example.com/orders/ORD-2024-001/review",
        "order_view_url": "https://example.com/orders/ORD-2024-001",
    
        "order_proof_of_consent": "Customer agreed to Terms of Service on 2024-01-15 via checkout checkbox",
        "order_communications": "Order confirmation email sent 2024-01-15. Shipping notification sent 2024-01-16.",
    
        "customer_email": "[email protected]",
        "customer_first_name": "John",
        "customer_last_name": "Doe",
        "customer_account_id": "[email protected]",
        "order_email": "[email protected]",
    
        "device_ip_address": "216.24.60.94",
        "device_id": "device-abc123",
        "device_fingerprint": "fp-xyz789",
    
        "merchant_reference_id": "merchant-001",
        "merchant_name": "Example Corporation",
        "merchant_store_name": "Example Store",
        "merchant_store_description": "Your one-stop shop for widgets and gadgets",
        "merchant_contact_email": "[email protected]",
        "merchant_customer_service_email": "[email protected]",
        "merchant_contact_phone": "+14155559876",
        "merchant_address": {
          "line_1": "100 Commerce St",
          "line_2": "Suite 500",
          "line_3": "Building A",
          "city": "San Francisco",
          "country_subdivision": "CA",
          "postal_code": "94105",
          "country": "US"
        },
        "merchant_store_url": "https://store.example.com",
        "merchant_url": "https://example.com",
        "merchant_terms_and_conditions_url": "https://example.com/terms",
        "merchant_logo_url": "https://example.com/logo.png",
        "merchant_refund_policy_url": "https://example.com/refund-policy",
    
        "transactions": [
          {
            "reference_id": "txn-001",
            "amount_in_cents": 9720,
            "currency": "USD",
            "payment_method_type": "CARD",
            "authorisation_status": "SETTLED",
            "payment_method_reference_id": "pm_card_abc123",
            "authorised_at": "2024-01-15T10:30:05Z",
            "descriptor": "EXAMPLE STORE",
            "descriptor_prefix": "EXAMPLE",
            "descriptor_suffix": "STORE",
            "authorisation_code": "123456",
            "acquirer_reference_number": "74027012345678901234567",
            "network_id": "network-txn-123",
            "settlement_datetime": "2024-01-16T00:00:00Z",
            "cvc_verified": true,
            "three_d_secure_verified": true,
            "payment_method_card_brand": "VISA",
            "payment_method_card_last_4": "4242",
            "payment_method_card_exp_month": 12,
            "payment_method_card_exp_year": 2026,
            "payment_method_card_bin": "424242",
            "payment_method_card_wallet_type": "APPLE_PAY",
            "payment_method_card_issuer": "Chase Bank",
            "billing_address": {
              "line_1": "123 Main St",
              "line_2": "Apt 4B",
              "city": "New York",
              "country_subdivision": "NY",
              "postal_code": "10001",
              "country": "US"
            }
          }
        ],
    
        "deliveries": [
          {
            "reference_id": "dlv-physical-001",
            "type": "PHYSICAL",
            "physical_shipping_carrier": "UPS",
            "physical_shipping_tracking_number": "1Z999AA10123456784",
            "physical_shipping_status": "DELIVERED",
            "physical_shipping_datetime_shipped": "2024-01-16T08:00:00Z",
            "physical_shipping_datetime_delivered": "2024-01-18T14:30:00Z",
            "physical_shipping_address": {
              "line_1": "123 Main St",
              "line_2": "Apt 4B",
              "city": "New York",
              "country_subdivision": "NY",
              "postal_code": "10001",
              "country": "US"
            }
          },
          {
            "reference_id": "dlv-digital-001",
            "type": "DIGITAL",
            "digital_delivery_datetime": "2024-01-15T10:35:00Z",
            "digital_download_start_datetime": "2024-01-15T10:36:00Z",
            "digital_download_end_datetime": "2024-01-15T10:37:00Z",
            "digital_delivery_ip_address": "216.24.60.175",
            "digital_notification_sent": true,
            "digital_notification_sent_datetime": "2024-01-15T10:35:00Z",
            "digital_notification_method": "EMAIL"
          }
        ],
    
        "items": [
          {
            "reference_id": "item-001",
            "name": "Widget Pro",
            "price_in_cents": 4500,
            "quantity": 2,
            "product_url": "https://example.com/products/widget-pro",
            "product_reference_id": "prod-widget-pro",
            "sku": "WIDGET-PRO-001",
            "delivery_reference_id": "dlv-physical-001"
          },
          {
            "reference_id": "item-002",
            "name": "Digital License Key",
            "price_in_cents": 0,
            "quantity": 1,
            "product_url": "https://example.com/products/license",
            "product_reference_id": "prod-license",
            "sku": "LICENSE-001",
            "delivery_reference_id": "dlv-digital-001",
            "subscription_reference_id": "sub-001"
          }
        ],
    
        "refunds": [
          {
            "reference_id": "refund-001",
            "amount_in_cents": 4500,
            "currency": "USD",
            "status": "SUCCEEDED",
            "original_transaction_reference_id": "txn-001",
            "refund_datetime": "2024-01-17T12:00:00Z"
          }
        ],
    
        "subscriptions": [
          {
            "reference_id": "sub-001",
            "interval": "MONTH",
            "interval_price_in_cents": 2999,
            "interval_currency": "USD",
            "status": "ACTIVE",
            "display_name": "Pro Plan Monthly",
            "trial_start_date": "2024-01-01T00:00:00Z",
            "trial_end_date": "2024-01-14T23:59:59Z",
            "trial_price_in_cents": 0,
            "trial_currency": "USD",
            "start_date": "2024-01-15T00:00:00Z",
            "next_charge_date": "2024-02-15T00:00:00Z"
          }
        ],
    
        "disputes": [
          {
            "reference_id": "dispute-001",
            "amount_in_cents": 4500,
            "currency": "USD",
            "stage": "1ST_CHARGEBACK",
            "status": "OPEN",
            "type": "CHARGEBACK",
            "network_reason_code": "10.4",
            "is_rapid_dispute_resolution": false,
            "evidence_due_by": "2024-02-15T23:59:59Z",
            "payment_method_type": "CARD",
            "card_brand": "VISA"
          }
        ]
      }
    ]
    {
      "created": 2,
      "failed": 0,
      "results": [
        {
          "id": "ord_abc123",
          "reference_id": "order-001",
          "type": "COMPLETE",
          "organisation_id": "org_xyz",
          "integration_id": "int_123",
          "created_at": "2024-01-15T10:30:00Z",
          "transactions": [...],
          "items": [...],
          ...,
          "links": [
            {
              "rel": "self",
              "uri": "/v1/orders/ord_abc123"
            }
          ]
        }
      ],
      "errors": []
    }
    {
      "created": 1,
      "failed": 1,
      "results": [...],
      "errors": [
        {
          "index": 1,
          "reference_id": "order-002",
          "code": "DUPLICATE_ORDER",
          "message": "Order with reference_id 'order-002' already exists for this integration",
          "field": "reference_id"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "RATE_LIMITED",
          "message": "Too many requests"
        }
      ]
    }
    {
      "deliveries": [
        {
          "reference_id": "dlv-001",
          "physical_shipping_status": "DELIVERED",
          "physical_shipping_datetime_delivered": "2024-01-18T14:30:00Z"
        }
      ]
    }
    {
      "subscriptions": [
        {
          "reference_id": "sub-001",
          "status": "CANCELLED"
        }
      ]
    }
    {
      "refunds": [
        {
          "reference_id": "ref-001",
          "amount_in_cents": 5000,
          "currency": "USD",
          "status": "SUCCEEDED"
        }
      ]
    }
    {
      "refunds": [
        {
          "reference_id": "ref-001",
          "status": "SUCCEEDED"
        }
      ]
    }
    {
      "disputes": [
        {
          "reference_id": "disp-001",
          "stage": "1ST_CHARGEBACK",
          "status": "WON"
        }
      ]
    }
    {
      "id": "ord_abc123",
      "reference_id": "order-001",
      "type": "COMPLETE",
      "organisation_id": "org_xyz",
      "integration_id": "int_123",
      "created_at": "2024-01-15T10:30:00Z",
      "order_status": "CLOSED_COMPLETE",
      "transactions": [...],
      "deliveries": [...],
      "items": [...],
      "refunds": [...],
      "subscriptions": [...],
      "disputes": [...],
      "links": [
        {
          "rel": "self",
          "uri": "/v1/orders/ord_abc123"
        }
      ]
    }
    {
      "errors": [
        {
          "code": "IMMUTABLE_FIELD",
          "message": "Cannot modify amount_in_cents on existing refund"
        }
      ]
    }
    {
      "detail": "Order with ID ord_nonexistent not found"
    }