API integration guide
Onboarding a new customer into your partner account
1
Create an organisation
curl -X POST "https://api.chargebackstop.com/v1/organisations/" \
-H "Authorization: Bearer <partner_api_key>" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Fitness"
}'{
"id": "org_abc123",
"name": "Acme Fitness",
"mode": "LIVE",
"created_at": "2026-02-17T10:00:00Z",
"updated_at": "2026-02-17T10:00:00Z"
}2
Add your customer users to their organisation
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"
}3
Add their merchant accounts into the newly created organisation
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"
}4
If you intend to use the Orders API, create an integration
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"]
}5
If you wish to enrol the customer with Ethoca or Verifi RDR, create enrolments
Create Ethoca enrolment
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
}Create Verifi RDR enrolment
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_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
}6
Start pushing orders to us using the Orders API
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",
"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": []
}7
Optional: Run this flow with a Node.js script
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,
});
});Actioning alerts
REFUND
CANCEL
REFUND_AND_CANCEL
ACCEPT_DISPUTE
Matching an alert to a transaction
Test organisation simulations
Last updated
Was this helpful?