Developers

Send merchants. Receive activation. Done.

You don’t build a payments product on top of us — you plug into one. Submit merchants through the API, watch underwriting via webhooks, and link our approved processing back into your platform. We run the rest.

POST /v1/merchants · referral
curl -X POST https://api.chargeloop.com/v1/merchants \
  -H "Authorization: Bearer $CHARGELOOP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform_id": "isv_8f3...",
    "platform_customer_id": "cust_91a...",
    "merchant": {
      "legal_name": "Acme Salon LLC",
      "vertical": "salon_spa"
    },
    "risk_profile": "specialty"
  }'
How it fits together

Three things your code does. We do the rest.

01

Send us the merchant

One API call with the customer info you already have. We assign a merchant_id immediately.

02

Listen to underwriting

Subscribe to webhooks. We push status updates as our team works the file. No polling required.

03

Link the activation

When merchant.activated fires, save our merchant_id against your customer. That’s the entire processing handshake.

Auth & environments

Single bearer token. Two environments.

No webhook in production without an explicitly verified signing secret. No partial keys, no environment ambiguity.

Sandbox
https://api.sandbox.chargeloop.com/v1

Submit test merchants. Receive simulated underwriting events. Verify your webhook handler end-to-end before you ship.

Live
https://api.chargeloop.com/v1

Real underwriting. Signed webhooks enforced. Activation events flip merchants into your processing book.

Authenticate with Authorization: Bearer <your-api-key>.

Key endpoints

A small surface. On purpose.

You’re not building a payments product. You’re referring merchants and reading back our status. Four endpoints cover it.

POST/v1/merchants

Submit a merchant

Refer a customer for underwriting. Include your platform_customer_id so we can link back later.

GET/v1/merchants/:id

Check merchant status

Pull current underwriting state. Use this sparingly — prefer webhooks for real-time updates.

POST/v1/webhooks

Register webhook endpoints

Subscribe to merchant lifecycle and payout events. Signed delivery, idempotent.

GET/v1/payouts

List payouts

Read-only visibility into payouts to your merchants. Filter by merchant or date for rev-share reporting.

Webhook events

Every state change, signed and delivered.

Subscribe once. Watch a merchant’s lifecycle play out without polling.

merchant.submitted

We received the merchant from your API call and assigned an id.

merchant.underwriting_started

Our underwriting team has the file and is reviewing.

merchant.approved

Underwriting cleared. Final activation steps in progress.

merchant.activated

Merchant is fully provisioned and processing-ready.

merchant.declined

Declined with reason in the payload. Rare — we say yes a lot.

payout.completed

A payout settled to one of your merchants. Useful for rev-share reporting.

In code

Three handlers, end-to-end.

Submit, listen, activate. Everything else — KYB, underwriting, processor routing, charging, payouts — runs on our side.

1

Submit a merchant

Send us the customer signing up in your software. Include their platform_customer_id so we can reference them back to your record later.

curl -X POST https://api.chargeloop.com/v1/merchants \
  -H "Authorization: Bearer $CHARGELOOP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "platform_id": "isv_8f3...",
    "platform_customer_id": "cust_91a...",
    "merchant": {
      "legal_name": "Acme Salon LLC",
      "vertical": "salon_spa"
    },
    "risk_profile": "specialty"
  }'
2

Handle underwriting webhooks

We push status updates as our team works the file. Verify the signature, switch on event type, update your dashboard accordingly.

import { verifyWebhook } from "@chargeloop/node";

export async function POST(req: Request) {
  const sig = req.headers.get("chargeloop-signature");
  const body = await req.text();
  const event = verifyWebhook(
    body,
    sig!,
    process.env.CHARGELOOP_WEBHOOK_SECRET!,
  );

  switch (event.type) {
    case "merchant.underwriting_started":
    case "merchant.declined":
      // surface status in your dashboard
      await db.customers.update(
        { id: event.data.platform_customer_id },
        { processing_status: event.type },
      );
      break;

    case "merchant.approved":
    case "merchant.activated":
      // wired up in the activation flow below
      break;
  }
}
3

Link activation back to your customer

When merchant.activated fires, we’re ready to process. Save our merchant_id against your customer record and your software knows they’re live on payments.

// When merchant.activated fires, ChargeLoop is ready to process.
// Link our merchant_id back into your customer record so your
// software knows "this customer is now live on payments".

case "merchant.activated": {
  const { merchant_id, platform_customer_id } = event.data;

  await db.customers.update(
    { id: platform_customer_id },
    {
      chargeloop_merchant_id: merchant_id,
      processing_status: "active",
      activated_at: new Date(),
    },
  );

  // Optional: show the customer a "you're live" banner.
  await notify.customer(platform_customer_id, "payments_active");
  break;
}
Sandbox & access

Request keys.

Tell us about your stack and timeline. We’ll email sandbox credentials and the early-access doc bundle within one business day — and our integration team will reach out about wiring the API into your code.

What’s in the bundle
  • Sandbox API keys + webhook signing secret
  • Full endpoint reference + event schema (PDF)
  • Postman collection for the three handlers above