Onboarding webhooks

Wire up a webhook handler that responds correctly to every event emitted during a child account's onboarding.

Who this section is for

Developers wiring up webhook handlers for child-account onboarding. This page describes the two event families you receive, their payloads, and how to react to each.

Overview

Onboarding emits webhook events at two points in the lifecycle:

  • Identity verification events — fire when an identity verification session completes. Tell you whether to proceed or restart the identity verification step.
  • Activation events — fire when PayMongo finishes reviewing a child account after you call Activate. Tell you whether the account is live.

Activation events are delivered to the parent's registered webhook endpoint. Identity verification events are delivered to the account that triggered the verification — see Who receives identity verification events. To receive payment, payout, and other transaction events for a child after activation, register webhooks on the child — see Best practices for webhooks.

📘

Scope

These events fire on child accounts created through either onboarding path (Create an account or Invite) once activation runs. Invitation lifecycle events for the Invite path (sent / accepted / cancelled) belong to Account Linking and are documented under Linked accounts when they ship.

Before you begin

🚧

Prerequisites

  1. Register an HTTPS endpoint via the Webhook resource.
  2. Subscribe to the events you need from the lists below.
  3. Configure your handler for signature verification and idempotency.

Event catalog

EventFires when
account.identity_verification.passedThe authorized representative's identity verification session completed successfully.
account.identity_verification.failedThe identity verification session was unsuccessful (failed liveness, document issue, expired session, etc.).
merchant.activatedA child of type merchant has been activated and can transact.
merchant.declinedA child of type merchant was declined during risk review.
consumer.activatedA child of type consumer has been activated.
consumer.declinedA child of type consumer was declined during risk review.

Identity verification events

Who receives identity verification events

Identity verification events go to the webhook of the account that triggered the verification:

Who triggered itEvent delivered to
The parent, by calling POST /v2/accounts/{id}/identity_verification with the child's ID in the pathThe parent's webhook
The child, by starting the verification itselfThe child's webhook

In both cases, data.attributes.data.account_id names the account being verified.

account.identity_verification.passed

{
  "data": {
    "id": "evt_example_passed",
    "type": "event",
    "attributes": {
      "type": "account.identity_verification.passed",
      "livemode": true,
      "data": {
        "id": "verif_example_passed",
        "account_id": "org_example_account",
        "status": "completed",
        "result": "passed",
        "created_at": "2026-04-15T01:34:50Z",
        "expired_at": "2026-04-15T01:34:50Z"
      },
      "previous_data": {},
      "pending_webhooks": 1,
      "created_at": 1776149210,
      "updated_at": 1776149210
    }
  }
}

What to do: call Update account to fill in any remaining details, then Activate account.

account.identity_verification.failed

{
  "data": {
    "id": "evt_example_failed",
    "type": "event",
    "attributes": {
      "type": "account.identity_verification.failed",
      "livemode": true,
      "data": {
        "id": "verif_example_failed",
        "account_id": "org_example_account",
        "status": "completed",
        "result": "failed",
        "created_at": "2026-04-15T01:34:50Z",
        "expired_at": "2026-04-15T01:34:50Z",
        "failure_reason": "Please retry. Move closer to the camera, use even lighting, and ensure the face takes up at least half the image height."
      },
      "previous_data": {},
      "pending_webhooks": 1,
      "created_at": 1776149210,
      "updated_at": 1776149210
    }
  }
}

What to do: present failure_reason to the representative, then start a fresh identity verification session. See Best practices for identity verification for retry guidance.

Field reference

FieldTypeDescription
data.idstringEvent ID. Prefixed evt_.
data.typestringAlways event.
data.attributes.typestringaccount.identity_verification.passed or account.identity_verification.failed.
data.attributes.livemodebooleantrue for live events. Sandbox support is coming.
data.attributes.data.idstringVerification session ID. Prefixed verif_.
data.attributes.data.account_idstringThe child account this verification belongs to. Prefixed org_.
data.attributes.data.statusstringpending, in_progress, or completed.
data.attributes.data.resultstringpending, passed, failed, or invalid.
data.attributes.data.expired_atstringWhen the verification session expires (sessions are valid for 72 hours from creation).
data.attributes.data.failure_reasonstringHuman-readable reason; present on failed events only.

Activation events

These events fire when PayMongo finishes risk review after you call Activate account. They are the reliable signal that a child is ready to transact.

📘

No child API keys

Child API keys are not shared for accounts created with the Accounts API — the activation events carry no keys object and no wallet secret keys. Act on the child with Linked transactions (Account-ID). The legacy Onboarding API still sends child keys in these events until January 1, 2027, when it is removed.

merchant.activated

{
  "data": {
    "id": "evt_xxxxxxxx",
    "type": "event",
    "attributes": {
      "type": "merchant.activated",
      "livemode": true,
      "data": {
        "merchant_id": "org_xxxxxxxx",
        "account": {
          "legal_name": "ABC Trading",
          "trade_name": "ABC Store",
          "type": "sole_proprietor"
        },
        "activation_status": "activated",
        "features": ["qrph"]
      },
      "previous_data": {},
      "created_at": 1746755984,
      "updated_at": 1746755984
    }
  }
}
{
  "data": {
    "id": "evt_xxxxxxxx",
    "type": "event",
    "attributes": {
      "type": "merchant.activated",
      "livemode": true,
      "data": {
        "merchant_id": "org_xxxxxxxx",
        "account": {
          "legal_name": "Legal Name",
          "trade_name": "PayMongo Test Account",
          "type": "partnership"
        },
        "activation_status": "activated",
        "features": ["standard_wallet"],
        "wallet": {
          "id": "wallet_xxxxxxxx",
          "account_number": "123456789101",
          "status": "activated",
          "type": "standard"
        }
      },
      "previous_data": {},
      "created_at": 1746755984,
      "updated_at": 1746755984
    }
  }
}

What to do: mark the child as ready in your system, and optionally subscribe to that child's transaction events. See Best practices for webhooks.

merchant.declined

{
  "data": {
    "id": "evt_xxxxxxxx",
    "type": "event",
    "attributes": {
      "type": "merchant.declined",
      "livemode": true,
      "data": {
        "merchant_id": "org_xxxxxxxx",
        "account": {
          "legal_name": "Jose Rizal",
          "trade_name": "Jose Rizal",
          "type": "individual"
        },
        "activation_status": "declined",
        "declined_message": "The information provided, along with our independent verification process, failed to provide a sufficient basis to meet the required Know-Your-Customer standards."
      },
      "previous_data": {},
      "created_at": 1715684435,
      "updated_at": 1715684435
    }
  }
}

What to do: show declined_message to your team. Activation declines are final for the account; if you believe a decline was made in error, contact [email protected].

consumer.activated

{
  "data": {
    "id": "evt_xxxx",
    "type": "event",
    "attributes": {
      "type": "consumer.activated",
      "livemode": true,
      "data": {
        "consumer_id": "org_xxxx",
        "account": {
          "first_name": "John",
          "last_name": "Doe",
          "email_address": "[email protected]"
        },
        "activation_status": "activated",
        "features": ["fully_verified_standard_wallet"],
        "wallet": {
          "id": "wallet_xxxx",
          "account_number": "1234567890",
          "status": "activated",
          "type": "fully_verified_standard"
        }
      },
      "previous_data": {},
      "created_at": 1746675190,
      "updated_at": 1746675190
    }
  }
}

consumer.declined

{
  "data": {
    "id": "evt_xxxx",
    "type": "event",
    "attributes": {
      "type": "consumer.declined",
      "livemode": true,
      "data": {
        "consumer_id": "org_xxxxx",
        "account": {
          "first_name": "John",
          "last_name": "Doe",
          "email_address": "[email protected]"
        },
        "activation_status": "declined",
        "decline_message": "The information provided, along with our independent verification process, failed to provide a sufficient basis to meet the required Know-Your-Customer standards."
      },
      "previous_data": {},
      "created_at": 1746598148,
      "updated_at": 1746598148
    }
  }
}

Field reference

FieldTypeDescription
data.attributes.typestringmerchant.activated, merchant.declined, consumer.activated, or consumer.declined.
data.attributes.data.merchant_id / consumer_idstringThe child account ID. Prefixed org_.
data.attributes.data.accountobjectSnapshot of the child's profile at the time of the event.
data.attributes.data.activation_statusstringactivated or declined.
data.attributes.data.featuresarrayCapabilities provisioned at activation. Always present on activated events.
data.attributes.data.walletobjectWallet details when a wallet was provisioned at activation.
data.attributes.data.declined_message / decline_messagestringHuman-readable reason; present on declined events only.

Delivery and retries

Webhook events are delivered via HTTPS POST. Respond with a 2xx status to acknowledge receipt. PayMongo retries up to twelve times using exponential backoff if your endpoint returns anything else. For full delivery semantics, signing keys, and verification examples, see the Webhook resource and Securing webhooks reference.

Related pages


Did this page help you?