Table of Contents

Overview

Webhooks provide real-time notifications for events occurring in your Fipto workspace, such as new transactions and transaction status updates. To monitor all these activities, configure a webhook, and Fipto will ensure that relevant events are broadcasted to your chosen endpoint.

Configuration

To add a new webhook, prepare an endpoint, and contact our customer support. The chosen endpoint must use HTTPS protocol to ensure a secure connection between Fipto and your service.

IP Allowlist

All incoming requests will be served, depending on environment, from these IPs:

  • Demo
    • 3.77.91.94
    • 3.73.145.20
    • 3.120.72.252
  • Production
    • 3.77.126.242
    • 52.29.119.142
    • 3.120.13.37

Request Validation

The authenticity of Fipto as the issuer of webhook notifications can be verified by checking the signature of the message attached to the header. The signature is generated as follows:

Fipto-Signature: Base64(RSASSA-PKCS1-v1_5(_WEBHOOK_PRIVATE_KEY_, SHA-512, SHA-512(eventBody))) 

To validate the signature, depending on environment, please use the following public key:

  • Demo
    -----BEGIN PUBLIC KEY-----
    MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsfIjnlRELLgHMUb5EdIT
    MZt+N569AlGGyz0DNX8VKdBIyLwgVHSt1FU7F0hZTHeMGYnqwtbxEDX92JnTZji9
    gDuD7es3jz7PpmKBn4xHJmvOu/UdEZ9YAHuR66x8DR5Pl2eHXItAozKraVzIRhbK
    WIowA60PGf5BvpLMRjN7sIX5ErGyffBP7IoqVWnIsAruEORYO3iiPbqwdaEAWK52
    ayt1E9qdAvWZnQs3uCdkR30Xf4dduiTzx1+7oTwFURCnzayJui5PQ+sK6dOs4qjK
    /XrEL2QdChjmt2dG4N/HXSGvOfKFLxDPC5QF9T7plutF210AgdPZCGgPbRFqfV7L
    clNZ246fPaQ96faEhGz5287P5G3i98pcIM3r799m3Gkhmmc+2OjfCojdB7nQe77B
    ZtSyfDvLlOnwa+Q/wfuMqTlJ375MTBcM9PlQXIgV7SBOkVYyPtOzHDX6E9NgK1YJ
    fpCG9No8eOTvRnt2ZM04Kb2sxfiBNEHM0NHjC+A1pCXPjtsv18oJaGyaplDWIuqu
    zSWj83ni6o9NzHmTYtazNj9MOmUqGxDFrGc2Aa9UBM1DDYCtV+LITMK3+XXkZdbt
    cNxeFARvdi/P1uOo5xhuEOTykhU0RPSNXAxyGfKdkeyd9g1hfwco5eJKAKEMwPxt
    nxCa4IgAVAJxCCKyejAdqK0CAwEAAQ==
    -----END PUBLIC KEY-----
    
  • Production
    -----BEGIN PUBLIC KEY-----
    MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAx324lPvb4LK7E2QbqF+B
    tlQ4dzi0BoiWrZVeCBlBreNbFZqmT+1fmoEOTvB64aRyUCSZUNK2BzTnDVXFAWMA
    e3jQ9N+zrknPeUVR6/jWzvC/t9Z4RjiUzMA4fOOq1kHZRjnYUA3EEsA/MiUwLVFj
    M9ja9IyDHtVRpjuSs2uLdwLpTbNOtIdj1U6eU16GGr8PeoBm5kejy/OqUN0Le0Iy
    3hAwDe7tdp7LxWS75bIk+5BDX4fP98yzqVvIk4ZJsjdYvk4eIfWBKtjZVSIHDmTk
    b/+bDHxoMazOMX8YlGgvXKLacyBwyXlSHtlze28fTR54H6mfTUpDLuDLHotQJ72X
    6nCqLUOkum9V5tTqoTjiT8bjk1cX9imFXOmHx3s73KqZ4DqXaoodIDwuThWhQfZV
    43SE4R1e5LzpbNjV9olxOnJkLMwGBfTlEc4jYzw7wMBeT84dwwju+TQHyuuMFlni
    mnQCl0YX3E9XbYoSi6m0h8wSyMKinOaZwdqp/yqD+6ErlGZlXhgb6IG10C0CzEzM
    j86flHmZ3PZvRPFmjBzBXjsxrKGMXV7G5WTTjf4BitBlZ4l6t8ySiILDIZFMIaMU
    6VIQxHk4ePJpZ/QMC6qy9FaOPbPpl9qObMb+7wHiDBRP7zoOriQdRviwbYLnI32L
    BcESaj2xk2B4yZy9xQtwifECAwEAAQ==
    -----END PUBLIC KEY-----
    

Example function to verify signature in TypeScript:

import { createVerify } from "crypto";

/**
 * Verifies the signature of a request sent by Fipto as a webhook.
 *
 * @param pubKey Fipto's public key.
 * @param reqBody Request body as string.
 * @param signature Content of "Fipto-Signature" header.
 */
export function verifySignature(
  pubKey: string,
  reqBody: string,
  signature: string
): boolean {
  return createVerify("RSA-SHA512")
    .update(reqBody)
    .verify(pubKey, signature, "base64");
}

Response

The Fipto server expects your endpoint to instantly respond with a 2XX HTTP status code to confirm webhook notification was received. In case of unexpected status code or lack of response within 5 seconds, a retry will be issued according to our retry policy.

Retry Policy

If Fipto server doesn't receive a 2XX HTTP response to the POST request within 5 seconds, it will retry the request with exponential back off. A maximum of 10 retries can be issued, with the final triggered 15 minutes after the last failure. The exact retry schedule (in seconds) is: 2, 4, 8, 16, 32, 64, 128, 256, 512, 900. Consequently, the final request will be made about 32 minutes after the first failure.

Request De-duplication

A consequence of the retry policy is the possibility of delivering the same event twice, therefore, it is important to ignore events with event_id that was already processed.

Payload

The webhook notification is sent as a POST request with a JSON object payload that provides information about a specific event. Each payload contains a generic structure that outlines the event type that triggered the notification, unique event_id for the request de-duplication, and the associated data object. The data object includes a unique identifier, the type of data, and a nested attributes object that holds detailed information specific to the data type.

FieldTypeDescription
eventstringThe type of event that triggered the webhook. Possible values: PAYIN_CREATED, PAYIN_COMPLETED, PAYIN_REJECTED, PAYOUT_COMPLETED, PAYOUT_REJECTED, PAYMENT_LINK_COMPLETED.
event_idstringThe UUID of the event, designated for the request de-duplication.
dataobjectThe main data object containing details about the event.
data.idstringThe UUID of the data object.
data.typestringThe type of data. Possible values: payin or payout.
data.attributesobjectContains the attributes related to the data object.

Payin

The following table describes the fields within data.attributes for when data.type is payin:

FieldTypeDescription
amountstringThe amount of the payin, in decimal format.
asset_codestringThe code of the asset being used (e.g., BTC for Bitcoin).
created_atstringThe timestamp when the payin was created, in ISO 8601 format.
sourceobjectThe source information of the payin.
source.addressstringThe external wallet address that initiated the payment.
source.ibanstringThe IBAN of the bank account that initiated the payment.
source.bicstringThe BIC of the bank account that initiated the payment.
source.namestringThe name of the bank account that initiated the payment.
source.physical_addressstringThe physical address of the bank account that initiated the payment.
source.countrystringThe country of the bank account that initiated the payment.
destinationobjectThe destination information for the payin.
destination.wallet_idstringThe UUID of the wallet receiving the payin.
destination.wallet_namestringThe name of the wallet receiving the payin.
destination.wallet_details_namestringThe name of the wallet details.
destination.wallet_details_addressstringThe address of the wallet details.
destination.wallet_details_tagstringThe tag associated with the wallet details.
destination.wallet_details_ibanstringThe IBAN associated with the wallet details.
referencestringPayment reference used in fiat transactions to convey information about the payment being made.
statusstringThe status of the payin. Possible values: in transit or completed.
transaction_idstringThe UUID for the transaction.
valuationsarrayAn array of valuation objects, each containing an asset and its corresponding value.
valuations[].assetstringThe code of the asset for the valuation (e.g., USD, EUR).
valuations[].valuestringThe value of the asset in the specified currency.
blockchain_dataobjectContains blockchain-specific data.
blockchain_data.transaction_hashstringThe hash of the blockchain transaction.
blockchain_data.block_explorer_linkstringA link to view the transaction on a blockchain explorer.

Example PAYIN_CREATED event in fiat currency:

{
  "event": "PAYIN_CREATED",
  "event_id": "0e8540ee-fcf9-4322-bc86-85eba7108a22",
  "data": {
    "id": "b99e9a17-1332-4e07-8c5a-1113b64c31c7",
    "type": "payin",
    "attributes": {
      "amount": "100.55",
      "created_at": "2023-07-10T14:30:00Z",
      "asset_code": "EUR",
      "source": {
        "iban": "GB90MOCK00000003779553",
        "bic": "MOCKGB21",
        "name": "John Kowalski",
        "physical_address": "25 rue François 1er, Paris, 75009",
        "country": "FR"
      },
      "destination": {
        "wallet_id": "cf3377f9-95d8-4371-9908-e700cd5025b1",
        "wallet_name": "Savings",
        "wallet_details_name": "Primary",
        "wallet_details_iban": "FR93MOCK00000003340671"
      },
      "reference": "Payment for order 12345",
      "status": "completed",
      "transaction_id": "562108da-222d-4895-acf4-2135462d7821"
    }
  }
}

Example PAYIN_COMPLETED event in digital currency:

{
  "event": "PAYIN_COMPLETED",
  "event_id": "205ad3f4-985e-413d-a9cc-1ce9b200a74e",
  "data": {
    "id": "b99e9a17-1332-4e07-8c5a-1113b64c31c7",
    "type": "payin",
    "attributes": {
      "amount": "1.50",
      "created_at": "2023-07-10T14:30:00Z",
      "asset_code": "BTC",
      "source": {
        "address": "tz1MzL4XgAo84vpJJGzNRz7KuAYuS6biwKsz"
      },
      "destination": {
        "wallet_id": "78526183-7755-4dfb-9f0b-b470ac9bb36a",
        "wallet_name": "Bitcoin Wallet",
        "wallet_details_name": "Primary",
        "wallet_details_address": "tz1a4GT7THHaGDiTxgXoatDWcZfJ5j29z5RC",
        "wallet_details_tag": ""
      },
      "status": "completed",
      "transaction_id": "ed0ca371-625c-40e7-a64f-c0431b80370d",
      "valuations": [
        { "asset": "USD", "value": "58140.31" },
        { "asset": "EUR", "value": "53633.26" }
      ],
      "blockchain_data": {
        "transaction_hash": "8ecfd4162367d5919cbbc071ec33df9800978cdc34c80d98cade61fa7d88be00",
        "block_explorer_link": "https://chain.so/tx/BTC/8ecfd4162367d5919cbbc071ec33df9800978cdc34c80d98cade61fa7d88be00"
      }
    }
  }
}

Example PAYIN_REJECTED event in fiat currency:

{
  "event": "PAYIN_REJECTED",
  "event_id": "da5be5cf-63c1-55af-adb6-05a6bc254f10",
  "data": {
    "id": "725cb2c2-173c-4dcd-b62f-d589e9526b00",
    "type": "payin",
    "attributes": {
      "asset_code": "EUR",
      "amount": "400000",
      "destination": {
        "wallet_id": "597165e7-1860-4037-be8a-03c4cb52ffbf",
        "wallet_name": "EUR wallet",
        "wallet_details_name": "Primary wallet details",
        "wallet_details_iban": "GB21MOCK00000003984495"
      },
      "source": {
        "name": "John Doe",
        "iban": "DE91100000000123456789",
        "bic": "AGRIFRPI",
        "country": "GB",
        "physical_address": "Address Line 1 "
      },
      "status": "rejected",
      "transaction_id": "9c96d8bf-e141-4891-9919-a479e0a650c8",
      "created_at": "2024-08-13T07:44:57Z",
      "reference": "Payment from John Doe"
    }
  }
}

Payout

The following table describes the fields within data.attributes for when data.type is payout:

FieldTypeDescription
amountstringThe amount of the payout, in decimal format.
asset_codestringThe code of the asset being used (e.g., BTC for Bitcoin).
created_atstringThe timestamp when the payout was created, in ISO 8601 format.
sourceobjectThe source information of the payout.
source.wallet_idstringThe UUID of the wallet from which the payout originates.
source.wallet_namestringThe name of the wallet from which the payout originates.
destinationobjectThe destination information for the payout.
destination.beneficiary_idstringThe UUID of the beneficiary receiving the payout.
destination.beneficiary_descriptionstringThe description of the beneficiary receiving the payout.
destination.beneficiary_addressstringThe blockchain address of the beneficiary receiving the payout.
destination.beneficiary_ibanstringThe IBAN of the beneficiary receiving the payout.
referencestringPayment reference used in fiat transactions to convey information about the payout being made.
statusstringThe status of the payout. The only possible value is: completed.
transaction_idstringThe UUID for the transaction.
valuationsarrayAn array of valuation objects, each containing an asset and its corresponding value.
valuations[].assetstringThe code of the asset for the valuation (e.g., USD, EUR).
valuations[].valuestringThe value of the asset in the specified currency.
blockchain_dataobjectContains blockchain-specific data.
blockchain_data.transaction_hashstringThe hash of the blockchain transaction.
blockchain_data.block_explorer_linkstringA link to view the transaction on a blockchain explorer.

Example PAYOUT_COMPLETED event in fiat currency:

{
  "event": "PAYOUT_COMPLETED",
  "event_id": "7c8e9a9f-8e5e-4b6e-a2b1-9c7e7fa1b14b",
  "data": {
    "id": "a12b3c45-d678-90ef-gh12-ijklmnopq345",
    "type": "payout",
    "attributes": {
      "amount": "250.75",
      "created_at": "2024-07-15T10:00:00Z",
      "asset_code": "EUR",
      "source": {
        "wallet_id": "e7b9f2d0-1e5e-4b7e-855a-11e05cf87ed1",
        "wallet_name": "Business Account"
      },
      "destination": {
        "beneficiary_id": "f1c2d3e4-5678-90ab-cdef-1234567890ab",
        "beneficiary_description": "John Doe's Savings",
        "beneficiary_iban": "US12345678901234567890"
      },
      "reference": "Payout for invoice #67890",
      "status": "completed",
      "transaction_id": "f14d2e6b-1234-4567-89ab-cdef12345678",
      "signatures": {
        "quorum": 0,
        "signatories": [],
        "mfa": ["totp"]
      }
    }
  }
}

Example PAYOUT_COMPLETED event in digital currency:

{
  "event": "PAYOUT_COMPLETED",
  "event_id": "9c2d3f4a-6789-1234-5678-abcdef012345",
  "data": {
    "id": "a12b3c45-d678-90ef-gh12-ijklmnopq345",
    "type": "payout",
    "attributes": {
      "amount": "0.75",
      "created_at": "2024-07-15T10:00:00Z",
      "asset_code": "BTC",
      "source": {
        "wallet_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "wallet_name": "Bitcoin Wallet"
      },
      "destination": {
        "beneficiary_id": "b2c3d4e5-6789-1234-5678-abcdef123456",
        "beneficiary_description": "Alice's Main Wallet",
        "beneficiary_address": "tz1a4GT7THHaGDiTxgXoatDWcZfJ5j29z5RC"
      },
      "status": "completed",
      "transaction_id": "e9f8a7b6-5c4d-3e2f-1a2b-34567890abcd",
      "valuations": [
        { "asset": "USD", "value": "1250.00" },
        { "asset": "EUR", "value": "1150.00" }
      ],
      "blockchain_data": {
        "transaction_hash": "8ecfd4162367d5919cbbc071ec33df9800978cdc34c80d98cade61fa7d88be00",
        "block_explorer_link": "https://chain.so/tx/BTC/8ecfd4162367d5919cbbc071ec33df9800978cdc34c80d98cade61fa7d88be00"
      },
      "signatures": {
        "quorum": 0,
        "signatories": [],
        "mfa": ["totp"]
      }
    }
  }
}

Example PAYOUT_REJECTED event in fiat currency:

{
  "event": "PAYOUT_REJECTED",
  "event_id": "5a51d345-0308-59b7-b759-fdc99e34476c",
  "data": {
    "id": "14089fa4-9608-4974-be5b-cc56006a8fbf",
    "type": "payout",
    "attributes": {
      "amount": "19999.75",
      "created_at": "2024-07-15T10:00:00Z",
      "asset_code": "EUR",
      "source": {
        "wallet_id": "e7b9f2d0-1e5e-4b7e-855a-11e05cf87ed1",
        "wallet_name": "Business Account"
      },
      "destination": {
        "beneficiary_id": "f1c2d3e4-5678-90ab-cdef-1234567890ab",
        "beneficiary_description": "John Doe's Savings",
        "beneficiary_iban": "US12345678901234567890"
      },
      "reference": "Payout for invoice #77350",
      "status": "rejected",
      "transaction_id": "8b9d0375-4aff-4950-b2f9-e38299678e94",
      "signatures": {
        "quorum": 0,
        "signatories": [],
        "mfa": ["totp"]
      }
    }
  }
}

Payment link

The following table describes the fields within data.attributes for when data.type is payment_link:

FieldTypeDescription
base_amountstringThe desired payment amount expressed in the base_asset_code.
base_asset_codestringThe currency used as the basis for calculating the amount to be paid.
quote_amountstringThe amount of the payment expressed in the quote currency.
quote_asset_codestringThe currency used as the basis for calculating the amount paid.
created_atstringThe specific date on which the payment link was created.
expired_atstringThe specific date on which the payment link will be expired.
destinationobjectThe destination information for the payment link.
destination.typeobjectType of the destination for the payment link (beneficiary or wallet).
destination.beneficiary_idstringThe UUID of the beneficiary receiving the payment link.
destination.wallet_idstringThe UUID of the wallet receiving the payment link.
external_referencestringA reference to an external entity or resource.
notestringA custom message or note. This field allows for personalized communication or additional instructions to the payer.
statusstringThe status of the payment link. (completed, underpaid, overpaid, expired).
linkstringThe URL to the payment page.
network_namestringThe name of the network used for the transaction.
transaction_amountstringThe amount of the payment expressed in the transaction currency.
transaction_sourcestringThe source of the transaction.

Example PAYMENT_LINK_COMPLETED event:

{
  "event": "PAYMENT_LINK_COMPLETED",
  "event_id": "631ab6cd-a106-504d-a2ba-c908fe8b07fc",
  "data": {
    "id": "55ca325e-0ca5-4feb-b2a4-1603d7bb973f",
    "type": "payment_link",
    "attributes": {
      "base_amount": "1.11",
      "base_asset_code": "EUR",
      "status": "completed",
      "created_at": "2024-08-13T09:00:20.885644Z",
      "transaction_amount": "1.23",
      "transaction_source": "0xb38906c22C40981fcf116E2eaC1D82fca0bcf983",
      "network_name": "Binance_Smart_Chain Test",
      "link": "pay.testing.numias.tech/c7cace35-2b09-4100-a526-198829ab10fd",
      "quote_asset_code": "USDT_BSC_TEST",
      "quote_amount": "1.23",
      "quote_expired_at": "2024-08-13T09:15:27.124385Z",
      "destination": {
        "type": "wallet",
        "wallet_id": "8dd02bfa-92c6-11ee-adf2-e696041ed0d1"
      }
    }
  }
}