Skip to main content
Webhook events are crucial for ensuring seamless data integration and communication between the Cobo payments service and your application. This guide provides an overview of how to create and manage an endpoint for receiving and processing webhook events.

Create an endpoint

First, choose a server environment, such as a cloud service like AWS, Google Cloud, or a self-hosted server, that supports receiving and processing webhook events. Then, define an endpoint URL on your server where the webhook events will be sent.

Implement handling logic

After you create the endpoint, you need to implement the logic on the server to handle the webhook events, including parsing the API request, verifying the signature, responding to the request and adding other handling logic if necessary.

Verify the signature

To prevent unauthorized access, when you receive a webhook event, you need to validate the authenticity of the API request by verifying the signature. The verification steps are as follows:
  1. Retrieve raw body and timestamp. Extract the original body string from the request payload and the timestamp from the request headers.
    raw_body = request.body().decode('utf8')
    timestamp = request.headers.get("BIZ_TIMESTAMP")
    
  2. Retrieve the signature. Fetch the signature value from the request header.
    signature = request.headers.get('BIZ_RESP_SIGNATURE')
    
  3. Concatenate and hash the message.
    import hashlib
    
    # Concatenate raw body and timestamp to form the message.
    message = "raw_body|timestamp"
    
    # Compute double SHA-256 hash.
    sha256_hash = hashlib.sha256(hashlib.sha256(message.encode()).digest()).digest()
    
  4. Select Cobo’s Public Key. Depending on the environment that you use, select the corresponding public key for verification:
    • Development environment: a04ea1d5fa8da71f1dcfccf972b9c4eba0a2d8aba1f6da26f49977b08a0d2718
    • Production environment: 8d4a482641adb2a34b726f05827dba9a9653e5857469b8749052bf4458a86729
  5. Verify the signature using the Ed25519 algorithm.
    import ed25519
    
    # Obtain the verifying key from Cobo's public key.
    vk = ed25519.VerifyingKey(bytes.fromhex(public_key)) 
    
    # Verify the signature against the computed message hash.
    vk.verify(bytes.fromhex(signature), sha256_hash)
    

Respond to the API request

When your webhook endpoint receives a webhook event, it should respond with a status code of 200 or 201 to indicate that the event has been successfully received and processed. Once this response is sent, the Cobo payments service will stop retrying to send the event and the event status will become Delivered on Cobo Portal. The default timeout for each webhook event is 2 seconds. If the webhook endpoint does not respond or responds with a status code other than 200 or 201, the Cobo payments service will continue to retry sending the event. If the number of retry attempts reaches 10 , the Cobo payments service will stop sending the event and the event status will become Failed· You can resend the event by clicking Retry on Cobo Portal > Developer > Webhook Events. Cobo does not guarantee that events will be delivered in the order they are generated. For example, creating a transfer will generate the following events:
  • wallets.transaction.created
  • wallets.transaction.updated
  • wallets.transaction.succeeded
Your endpoint should not assume that events will arrive in this sequence and must handle delivery appropriately.

Code samples

To see examples of how to implement the handling logic, refer to the following files in the GitHub repository:

⚠️⚠️⚠️Important notes

  • When receiving the webhook events, your endpoint should first return the correct status code promptly and then handle any subsequent processing asynchronously to prevent timeouts.
  • Due to the retry mechanism of webhook events, webhook endpoints may sometimes receive the same event multiple times. To protect against duplicate event processing, please log the event IDs, transaction hashes, or transaction IDs you’ve already processed and refrain from processing those that are already logged.