Webhooks

Webhooks allows you to receive notifications in your own backend whenever your company account or your payment objects changes state (you can find a visual of payment states in the Payments page ). This guide describes how to setup a webhook and verify the integrity of the notification.

  1. The notification payload
  2. Setting up a webhook
  3. Webhook signatures

Webhook Setup and Verification Guide

The notification payload:

All notifications contains a message type which is either company or payment, and the id and current state of the payment/company. A payment notification also contains type of payment, and optionally a parent id, if the payment is linked to another payment.

{
    "message_type": "Payment",
    "id": 123,
    "state": "PROCESSED",
    "type": "WITHDRAWAL",
    "parent": 1121
}
{
    "message_type": "Company",
    "id": 123,
    "state": "ACTIVE",
}

The fields expained:

  • id: The unique identifier of the object.
  • messageType: Payment, Company.
  • state: The current state of the object. Possible states include:
    • For payments (see also the Payments page):
      • PENDING
      • REJECTED_COMPLIANCE
      • REJECTED_APPROVAL
      • REJECTED_SIGNING
      • INITIATED_PAYMENT
      • PROCESSING_PAYMENT
      • PROCESSED
      • FAILED
      • REVERSED
    • For companies:
      • ACTIVE
      • FROZEN
      • UNDER_INVESTIGATION
      • DEACTIVATED
      • PENDING_KYC
      • PENDING_BLOCKCHAIN_ACTIVATION
      • FAILED_KYC
      • PENDING_CUSTOMER_CONSENT
      • PENDING_KYC_APPROVAL
      • PENDING_PASSWORD_CREATION

The following are relevant for payment objects only:

  • type: The PaymentType of the payment Object. Possible states include:
    • TRANSFER
    • PAYOUT
    • PAY_IN
    • WITHDRAWAL
  • parent: Id of the parent PaymentObject if it exists.
    • null - if no parent object exists
    • 123- integer id of the parent object

Setting Up a Webhook

To set up a webhook, follow these steps:

  1. Create an HTTP POST endpoint that accepts the JSON notification payload shown above. The endpoint must return a successful status code (200) as quickly as possible, before performing any complex logic that could cause a timeout.
  2. Register the endpoint with ComplyPay using the Create Payment Webhook endpoint.

Webhook Signatures

ComplyPay signs every webhook notification it sends to your endpoint by including an X-Payload-Signature header with the payload's signature. It is recommended to use these signatures to verify that the webhook request is legitimate and was generated by ComplyPay.

Steps to Verify a Webhook Request

  1. Retrieve the X-Payload-Signature header from the request.
  2. Retrieve the webhook HTTP body as bytes.
  3. Generate a signature by signing the body from step 2 with the secret key generated when creating the webhook. Use the HmacSHA512 algorithm for signing.
  4. Verify that the X-Payload-Signature header matches the signature generated in step 3.

Below is an example implementation in Java:

@ResponseBody
@PostMapping(produces = MediaType.APPLICATION_JSON_VALUE, value = "https://yourcompany.com/payment-webhook-consume", consumes = MediaType.APPLICATION_JSON_VALUE)
public void consumeData(@Valid @RequestBody byte[] body, @RequestHeader(name = "X-Payload-Signature") String signature) throws NoSuchAlgorithmException, InvalidKeyException {
    String ALGORITHM = "HmacSHA512";
    String SECRET = "<YOUR_WEBHOOK_SECRET_KEY>";
    SecretKey key = new SecretKeySpec(SECRET.getBytes(StandardCharsets.UTF_8), ALGORITHM);

    Mac mac = Mac.getInstance(ALGORITHM);
    mac.init(key);

    byte[] calculatedSignature = mac.doFinal(body);
    String calculatedSignatureString = Base64.getEncoder().encodeToString(calculatedSignature);
    boolean isValid = calculatedSignatureString.equals(signature);

    if (isValid) {
        // Process the webhook payload
    } else {
        // Handle the invalid signature
    }
}

By following these instructions, you can ensure that your application receives and verifies webhook notifications securely and efficiently.