Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.dollarpe.xyz/llms.txt

Use this file to discover all available pages before exploring further.

Webhooks push real-time updates to your server when objects in DollarPe change state. Use them instead of polling. They are the recommended way to drive your integration logic.
To configure your webhook URL, see the Webhook Configuration API reference.

How it works

When an event fires, DollarPe sends an HTTP POST to your configured endpoint. Your server must respond with a 2xx status code to acknowledge receipt. Non-2xx responses are treated as delivery failures.

Webhook structure

All events share the same envelope:
{
  "type": "string",       // Entity type: PAYIN, PAYOUT, CUSTOMER, BANK, EDD
  "id": "string",         // Unique ID of the entity
  "event": "string",      // The state the entity moved to
  "timestamp": "string",  // ISO 8601 timestamp
  "metadata": {
    "failure_reason": "string"   // Present on FAILED events
  }
}
Use id to deduplicate events. Webhooks may occasionally be delivered more than once, so your handler should be idempotent.

Signature validation

Every request includes two headers:
X-TIMESTAMP: 1752670745
X-SIGNATURE: ohmVyfuNup6eKWOdOZBBZut5CMPdPTfFSB/zDT/eXQo=
  • X-TIMESTAMP โ€” Unix timestamp when the webhook was generated
  • X-SIGNATURE โ€” HMAC-SHA256 of the request, Base64 encoded
Validate both on every incoming request. Reject anything with a stale timestamp or a signature mismatch.
import base64
import hmac
import hashlib
import json

def generate_hmac_signature(api_key, api_secret, timestamp, body={}):
    body = json.dumps(body, sort_keys=True, separators=(",", ":"))
    message = f"{api_key}|{timestamp}|{body}".encode()
    signature = hmac.new(api_secret.encode(), message, hashlib.sha256).digest()
    return base64.b64encode(signature).decode()

def verify_hmac_signature(api_key, timestamp, signature, body, api_secret):
    expected = generate_hmac_signature(api_key, api_secret, timestamp, body)
    return hmac.compare_digest(expected, signature)
Usage:
is_valid = verify_hmac_signature(
    api_key="your_api_key",
    api_secret="your_api_secret",
    timestamp=received_timestamp,
    signature=received_signature,
    body=webhook_body_dict,
)

if not is_valid:
    return 401  # reject
Always validate the signature before processing any webhook payload. Never trust the payload without verification.

Metadata fields

The metadata object carries event-specific context.

Payin events

  • failure_reason โ€” present on FAILED. Values: INCORRECT_UTR, PAYMENT_NOT_RECEIVED, and others. See Failure Reason Reference
  • refund_reason โ€” present on REFUND_INITIATED and REFUNDED. Values: INCORRECT_AMOUNT, PAYMENT_FROM_NON_WHITELISTED_ACCOUNT, THIRD_PARTY_PAYMENT

Payout events

  • utr โ€” present on SUCCESS. The UTR number for the bank transfer, usable as a reconciliation reference

Customer events

  • failure_reason โ€” present on FAILED. Values: DOCUMENT_VERIFICATION_FAILED, TAX_VERIFICATION_FAILED, KYC_FAILED

Bank events

  • failure_reason โ€” present on FAILED. Values: ACCOUNT_TYPE_NRE, PENNY_DROP_FAILED, NAME_MISMATCH, BANK_RISK_CHECK_FAILED
Metadata fields are only present when relevant. Successful events typically have an empty metadata object.

Event catalog

Customer events

Fired when a customerโ€™s KYC status changes.
EventDescription
VERIFIEDKYC passed. Customer can link banks and transact
FAILEDKYC failed or account suspended
{
  "type": "CUSTOMER",
  "event": "FAILED",
  "id": "12348400-e29b-41d4-a716-446655440000",
  "timestamp": "2024-03-13T10:00:00Z",
  "metadata": {
    "failure_reason": "TAX_VERIFICATION_FAILED"
  }
}

Bank events

Fired when a bank account or UPI ID verification resolves.
EventDescription
VERIFIEDBank account or UPI ID ready for orders
FAILEDVerification failed
{
  "type": "BANK",
  "event": "VERIFIED",
  "id": "12348400-e29b-41d4-a716-446655440000",
  "timestamp": "2024-03-13T10:00:00Z",
  "metadata": {}
}

Payin events

Fired when a payin order changes state.
EventDescription
SUCCESSPayment received, crypto released
FAILEDPayin failed
REFUND_INITIATEDRefund process started
REFUNDEDFiat returned to source
ON_HOLDPayment flagged and held for review
{
  "type": "PAYIN",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "event": "SUCCESS",
  "timestamp": "2024-03-13T10:00:00Z",
  "metadata": {}
}
{
  "type": "PAYIN",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "event": "FAILED",
  "timestamp": "2024-03-13T10:00:00Z",
  "metadata": {
    "failure_reason": "INCORRECT_UTR"
  }
}
{
  "type": "PAYIN",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "event": "REFUND_INITIATED",
  "timestamp": "2024-03-13T10:00:00Z",
  "metadata": {
    "refund_reason": "INCORRECT_AMOUNT"
  }
}

Payout events

Fired when a payout order changes state.
EventDescription
SUCCESSFunds delivered to beneficiary
FAILEDPayout failed
REFUNDEDPayout amount returned
CANCELLEDPayout cancelled
{
  "type": "PAYOUT",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "event": "SUCCESS",
  "timestamp": "2024-03-13T10:00:00Z",
  "metadata": {
    "utr": "RATN12341234XYZ"
  }
}

EDD events

Fired when Enhanced Due Diligence verification resolves.
EventDescription
VERIFIEDEDD passed. Customer gets enhanced payin limits
FAILEDEDD failed. Standard limits remain
{
  "type": "EDD",
  "event": "VERIFIED",
  "id": "12348400-e29b-41d4-a716-446655440000",
  "timestamp": "2024-03-13T10:00:00Z",
  "metadata": {}
}