Skip to navigation

Onboarding Webhooks

Webhook events Coinflow sends your server as your sub-merchants submit, get approved or declined, and receive and answer information requests.

Onboarding webhooks tell your server about each sub-merchant’s onboarding progress, whether or not the sub-merchant is in your page at the time. They’re sent to your webhook URL, the parent account’s, for every sub-merchant under it.

Subscribe

In the merchant dashboard, go to Developers → Webhooks, choose webhook Version 2 or later, and subscribe to the five events below. Webhook URLs are configured in the dashboard only. See Partner Setup.

Events

EventWhen it fires
Sub-merchant Application SubmittedThe sub-merchant submits its onboarding application
Sub-merchant Application ApprovedCoinflow approves the sub-merchant and its account goes live
Sub-merchant Application DeclinedUnderwriting declines the application. Sent once
Sub-merchant RFI SentAn information request is sent to the sub-merchant, during onboarding or after it’s live. Sent again, with the same rfiId, each time the request is reopened
Sub-merchant RFI SubmittedThe sub-merchant submits its answers to an information request. Sent again each time it answers a reopened request

Payload

{
eventType:
| 'Sub-merchant Application Submitted'
| 'Sub-merchant Application Approved'
| 'Sub-merchant Application Declined'
| 'Sub-merchant RFI Sent'
| 'Sub-merchant RFI Submitted';
category: 'KYC';
created: string;
data: {
merchantId: string; // the sub-merchant's merchantId
status: 'not_started' | 'in_progress' | 'submitted' | 'action_required' | 'approved' | 'declined';
timestamp: string; // ISO 8601
rfiId?: string; // only on the two RFI events
};
}
Example
{
"eventType": "Sub-merchant RFI Sent",
"category": "KYC",
"created": "2026-10-28T15:04:05.000Z",
"data": {
"merchantId": "acme-store",
"status": "action_required",
"timestamp": "2026-10-28T15:04:05.000Z",
"rfiId": "6720f1c2a4b5c6d7e8f90123"
}
}

data.status is the onboarding status at the time of the event, the same value Get Onboarding returns. For example:

  • Sub-merchant Application Submitted reports action_required when the sub-merchant still has a step to finish, such as choosing where its funds settle, and submitted otherwise.
  • After the last open RFI is submitted, Sub-merchant RFI Submitted reports submitted again for a sub-merchant in review, or approved for a live one.

Treat a status you don’t recognize as still in progress, and ignore fields you don’t recognize.

Handling deliveries

  • Verify the sender. Check that the Authorization header matches your Webhook Validation Key before trusting a delivery. See Verifying Webhook Signatures.
  • Respond quickly. Return a 200 within 5 seconds and do the work in the background. Failed deliveries are retried; see Configuring Webhooks.
  • Expect duplicates and out-of-order delivery. Deliveries can repeat and arrive out of order. When in doubt, call Get Onboarding for the current state.
Server
app.post('/coinflow/webhooks', express.json(), (req, res) => {
if (req.get('Authorization') !== process.env.COINFLOW_WEBHOOK_VALIDATION_KEY)
return res.sendStatus(401);
const {eventType, data} = req.body;
if (eventType?.startsWith('Sub-merchant '))
onboardingQueue.add({eventType, ...data});
res.sendStatus(200);
});

Turning events off for a sub-merchant

These events aren’t sent for a sub-merchant whose webhook settings turn off forwarding webhooks to its parent.