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.
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"
}'Three things your code does. We do the rest.
Send us the merchant
One API call with the customer info you already have. We assign a merchant_id immediately.
Listen to underwriting
Subscribe to webhooks. We push status updates as our team works the file. No polling required.
Link the activation
When merchant.activated fires, save our merchant_id against your customer. That’s the entire processing handshake.
Single bearer token. Two environments.
No webhook in production without an explicitly verified signing secret. No partial keys, no environment ambiguity.
https://api.sandbox.chargeloop.com/v1Submit test merchants. Receive simulated underwriting events. Verify your webhook handler end-to-end before you ship.
https://api.chargeloop.com/v1Real underwriting. Signed webhooks enforced. Activation events flip merchants into your processing book.
Authenticate with Authorization: Bearer <your-api-key>.
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.
Submit a merchant
Refer a customer for underwriting. Include your platform_customer_id so we can link back later.
Check merchant status
Pull current underwriting state. Use this sparingly — prefer webhooks for real-time updates.
Register webhook endpoints
Subscribe to merchant lifecycle and payout events. Signed delivery, idempotent.
List payouts
Read-only visibility into payouts to your merchants. Filter by merchant or date for rev-share reporting.
Every state change, signed and delivered.
Subscribe once. Watch a merchant’s lifecycle play out without polling.
merchant.submittedWe received the merchant from your API call and assigned an id.
merchant.underwriting_startedOur underwriting team has the file and is reviewing.
merchant.approvedUnderwriting cleared. Final activation steps in progress.
merchant.activatedMerchant is fully provisioned and processing-ready.
merchant.declinedDeclined with reason in the payload. Rare — we say yes a lot.
payout.completedA payout settled to one of your merchants. Useful for rev-share reporting.
Three handlers, end-to-end.
Submit, listen, activate. Everything else — KYB, underwriting, processor routing, charging, payouts — runs on our side.
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"
}'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;
}
}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;
}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.
- Sandbox API keys + webhook signing secret
- Full endpoint reference + event schema (PDF)
- Postman collection for the three handlers above