Event Notifications and Webhooks

The Pay.io Payment Gateway provides real-time event notifications, so merchants can stay up to date with deposits and withdrawals as they happen.

You can consume these events through Webhooks, the gateway pushes event notifications to your HTTP endpoint.


Event Types for Webhooks

The gateway sends notifications for the following transaction events:

Deposit Events

  • Processing Event - The deposit has been detected on the blockchain and is being processed.

  • Confirmation Event - The blockchain has confirmed the transaction, funds are now available in the wallet.

Withdrawal Events

  • Successful Event - The withdrawal was completed successfully, confirms that funds have been transferred.


Webhook Integration

Setup Requirements

  1. Webhook URL - Update the URL, which Payment Gateway will call in the Merchant Portal.

  2. IP Whitelisting - Contact support for the list of IPs to allow.

  3. Public Key - Obtain your Pay.io public key from the Merchant Console.

  4. Secure Storage - Store the key securely in your application configuration.

  5. Signature Verification - Implement verification on all incoming requests.

Webhook Security Verification

Each webhook request includes headers you must validate:

Header
Description

X-Signature

Base64-encoded request signature

X-Timestamp

UNIX timestamp when the event was sent

X-Algorithm

Signing algorithm, always RSA-SHA256

Verification steps:

  1. Extract the raw JSON request payload.

  2. Read X-Signature, X-Timestamp, and X-Algorithm headers.

signature = request.headers.get('X-Signature')
timestamp = request.headers.get('X-Timestamp')
algorithm = request.headers.get('X-Algorithm')
  1. Build a string to verify:

    string_to_verify = json_payload + timestamp
  2. Decode the Base64 signature.

  3. Verify with RSA-SHA256 using the stored Pay.io public key.

Example: Verification in Elixir

def verify_signature(json_payload, signature, public_key_pem, timestamp) do
  case parse_public_key(public_key_pem) do
    {:ok, public_key} ->
      string_to_verify = json_payload <> to_string(timestamp)
      signature_bytes = Base.decode64!(signature)
      case :public_key.verify(string_to_verify, :sha256, signature_bytes, public_key) do
        true -> {:ok, :verified}
        false -> {:error, :signature_invalid}
      end
    {:error, reason} ->
      {:error, reason}
  end
end

Event Structure

Each event payload includes:

  • event - Type of event (User Deposit, User Payout).

  • transaction - Full transaction details (currency, addresses, tx hash, etc.).

  • transaction_uuid - Unique transaction ID for reconciliation.

  • user_reference - Your internal user ID.

  • merchant_reference - Reference configured during transaction creation.

Example: Deposit Processing

{
  "event": "User Deposit",
  "transaction": {
    "id": "43dae597-f283-4631-8e73-1e40ecfaedfa",
    "status": "processing",
    "date": "2025-08-27T14:51:53Z",
    "currency": {
      "id": "c872e749-fd56-533e-b01f-de87ae38e7f1",
      "name": "USD Coin",
      "symbol": "$",
      "network": "Base Chain",
      "token_address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "currency_icon": "https://cdn.hub88.io/hub-wallet/USDC-ic.svg",
      "network_icon": "https://cdn.hub88.io/hub-wallet/BASE-ic.svg",
      "currency_code": "USDC"
    },
    "amount": 2.35,
    "provider_transaction_id": "pay_31sINaTdZeCYWCLobzX16X6QGFm",
    "to_address": "0x6d0e5b532ba0857ca391ee2d11b02c596fcded3c",
    "from_address": "0xabf7920042335cb1fd9e7c688f99822a1d879445",
    "tx_hash": "0xcd8fba9d72c3e25d55f7f63d58fffbc3411692df611e480c6975adfb2d8938cd",
    "transaction_type": "Deposit",
    "amount_usd": 2.35
  },
  "transaction_uuid": "43dae597-f283-4631-8e73-1e40ecfaedfa",
  "user_reference": "Jon14",
  "merchant_reference": "1_hubwallet-demo_6gmma63qfxdag",
  "payment_method": "Deposit"
}

Example: Deposit Confirmation

{
  "event": "User Deposit",
  "transaction": {
    "id": "43dae597-f283-4631-8e73-1e40ecfaedfa",
    "status": "succeeded",
    "date": "2025-08-27T14:53:59Z",
    "currency": {
      "id": "c872e749-fd56-533e-b01f-de87ae38e7f1",
      "name": "USD Coin",
      "symbol": "$",
      "network": "Base Chain",
      "token_address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "currency_icon": "https://cdn.hub88.io/hub-wallet/USDC-ic.svg",
      "network_icon": "https://cdn.hub88.io/hub-wallet/BASE-ic.svg",
      "currency_code": "USDC"
    },
    "amount": 2.35,
    "provider_transaction_id": "pay_31sINaTdZeCYWCLobzX16X6QGFm",
    "to_address": "0x6d0e5b532ba0857ca391ee2d11b02c596fcded3c",
    "from_address": "0xabf7920042335cb1fd9e7c688f99822a1d879445",
    "tx_hash": "0xcd8fba9d72c3e25d55f7f63d58fffbc3411692df611e480c6975adfb2d8938cd",
    "transaction_type": "Deposit",
    "amount_usd": 2.35
  },
  "transaction_uuid": "43dae597-f283-4631-8e73-1e40ecfaedfa",
  "user_reference": "Jon14",
  "merchant_reference": "1_hubwallet-demo_6gmma63qfxdag",
  "payment_method": "Deposit"
}

Example: Withdrawal Successful

{
  "event": "User Payout",
  "transaction": {
    "id": "492bcb88-149e-4d18-bfd4-2d2c2b29e87d",
    "status": "succeeded",
    "date": "2025-08-27T15:04:28Z",
    "currency": {
      "id": "c872e749-fd56-533e-b01f-de87ae38e7f1",
      "name": "USD Coin",
      "symbol": "$",
      "network": "Base Chain",
      "token_address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "currency_icon": "https://cdn.hub88.io/hub-wallet/USDC-ic.svg",
      "network_icon": "https://cdn.hub88.io/hub-wallet/BASE-ic.svg",
      "currency_code": "USDC"
    },
    "amount": 2.0,
    "provider_transaction_id": "pay_31sJg9321pd5yAWKOhVAIffWqVX",
    "to_address": "0xabf7920042335cB1FD9e7C688F99822a1D879445",
    "from_address": "0x09b8c5b24bcdd91af5a7d32f6a4ae9fa4183d4f4",
    "tx_hash": "0x76088442e6ce9524ead531be4296a379cf772dc96cddc9cbb9b2b01d5f0be7fa",
    "transaction_type": "Payout",
    "amount_usd": 1.9804985390232988
  },
  "transaction_uuid": "492bcb88-149e-4d18-bfd4-2d2c2b29e87d",
  "user_reference": "Jon14",
  "merchant_reference": "1_hubwallet-demo_6gmma63qfxdag",
  "payment_method": "Payout"
}

Last updated