---
page_source: https://juspay.io/in/docs/lotuspay/web/base-integration/webhooks
page_title: Webhooks
---


# **Webhooks** 



Use webhooks to be notified about events that happen in a LotusPay account.

LotusPay can send webhook events that notify your application any time an event happens on your account. This is especially useful for events (like mandates being activated and many recurring billing events) that are not triggered by a direct API request. This mechanism is also useful for services that are not directly responsible for making an API request, but still need to know the response from that request.

You can register a webhook URL that we will notify any time an event happens in your account. When the event occurs (an ACH debit is collected successfully on a customer’s subscription, a settlement is paid, a mandate is activated, etc.) LotusPay creates an Event object.

This `event` object contains all the relevant information about what just happened, including the type of event and the data associated with that event. LotusPay then sends the `event` object, via an HTTP POST request, to the endpoint URL that you have defined in your account’s Webhooks settings.


### Step 1.1 a When to use webhooks


Webhooks are necessary only for behind-the-scenes transactions. Many LotusPay requests (e.g. creating mandates or subscriptions) generate results that are reported synchronously to your code. These don’t require webhooks for verification.

NACH Debit requires using webhooks so that your integration can be notified about asynchronous changes to the status of `mandate` and `ach_debit` objects.

You might also use webhooks as the basis to:

* Update a customer's membership record in your database when a subscription ACH debit succeeds.
* Email a customer when a subscription ACH debit fails.
* Examine the Dashboard if you see that an ACH debit has failed.
* Log an accounting entry when a settlement is paid out.




### Step 1.1 b Configuring your Webhooks settings


Webhooks are configured in the Dashboard's Developers section. Here you can add a URL for receiving webhooks.

You can enter any URL as the destination for events. However, this should be a dedicated page on your server that is set up to receive webhook notifications. The URL will be notified of all event types.

Your current environment — whether you're using a test or live LotusPay account — determines whether test events or live events are sent to your configured URL. If you want to send both live and test events to the same URL, you need to create two separate settings in each environment.

LotusPay sends webhook notifications from the following static IP addresses. You may wish to whitelist these IP addresses in your network firewall.

* 35.154.239.213 (Live)
* 15.206.252.18 (Test)
  
  
  #### Java Code Snippet:
  
  ```java
  import javax.crypto.Cipher;
  import javax.crypto.spec.SecretKeySpec;
  import javax.crypto.spec.IvParameterSpec;
  import java.util.Base64;
  
  public class WebhookDecrypt {
  
      public static String decryptAes128Cbc(String encryptedData, byte[] key) throws Exception {
          if (key.length != 16) {
              throw new IllegalArgumentException("Key must be 16 bytes (AES-128 requires a 128-bit key).");
          }
  
          String ivString = encryptedData.substring(0, 16);
          byte[] iv = ivString.getBytes("UTF-8");
  
          String base64Data = encryptedData.substring(16);
          byte[] encryptedBytes = Base64.getDecoder().decode(base64Data);
  
          if (encryptedBytes.length % 16 != 0) {
              throw new IllegalArgumentException("Encrypted data length must be a multiple of the block size (16 bytes for AES).");
          }
  
          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
          SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
          IvParameterSpec ivSpec = new IvParameterSpec(iv);
  
          cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
  
          byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
  
          return new String(decryptedBytes, "UTF-8");
      }
  
      public static void main(String[] args) {
          try {
              // Replace <webhook_key> with your actual key.
              byte[] key = "<webhook_key>".getBytes("UTF-8");
              // Replace <encrypted_string> with your actual encrypted string.
              String encryptedData = "<encrypted_string>";
  
              String decryptedText = decryptAes128Cbc(encryptedData, key);
              System.out.println("Decrypted text: " + decryptedText);
          } catch (Exception e) {
              System.err.println("Error during decryption: " + e.getMessage());
          }
      }
  }
  ```
  
  
  
  #### php Code Snippet:
  
  ```php
  {"success":false,"message":"No Data found for the given path"}
  ```
  
  
  
  #### Python Code Snippet:
  
  ```python
  {"success":false,"message":"No Data found for the given path"}
  ```
  
  
  
  #### Node.js Code Snippet:
  
  ```node.js
  {"success":false,"message":"No Data found for the given path"}
  ```
  
  
  
  #### NewLanguage-42039 Code Snippet:
  
  ```newlanguage-42039
  import javax.crypto.Cipher;
  import javax.crypto.spec.SecretKeySpec;
  import javax.crypto.spec.IvParameterSpec;
  import java.util.Base64;
  
  public class WebhookDecrypt {
  
      public static String decryptAes128Cbc(String encryptedData, byte[] key) throws Exception {
          if (key.length != 16) {
              throw new IllegalArgumentException("Key must be 16 bytes (AES-128 requires a 128-bit key).");
          }
  
          String ivString = encryptedData.substring(0, 16);
          byte[] iv = ivString.getBytes("UTF-8");
  
          String base64Data = encryptedData.substring(16);
          byte[] encryptedBytes = Base64.getDecoder().decode(base64Data);
  
          if (encryptedBytes.length % 16 != 0) {
              throw new IllegalArgumentException("Encrypted data length must be a multiple of the block size (16 bytes for AES).");
          }
  
          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
          SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
          IvParameterSpec ivSpec = new IvParameterSpec(iv);
  
          cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
  
          byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
  
          return new String(decryptedBytes, "UTF-8");
      }
  
      public static void main(String[] args) {
          try {
              // Replace <webhook_key> with your actual key.
              byte[] key = "<webhook_key>".getBytes("UTF-8");
              // Replace <encrypted_string> with your actual encrypted string.
              String encryptedData = "<encrypted_string>";
  
              String decryptedText = decryptAes128Cbc(encryptedData, key);
              System.out.println("Decrypted text: " + decryptedText);
          } catch (Exception e) {
              System.err.println("Error during decryption: " + e.getMessage());
          }
      }
  }
  ```




### Step 1.1 c Receiving a webhook notification


Creating a webhook endpoint on your server is no different from creating any page on your website. With PHP, you might create a new .php file on your server; with a framework like Sinatra, you would add a new route with the desired URL.

Webhook data is sent as JSON in the POST request body. The full event details are included and can be used directly, after parsing the JSON into an Event object.

Webhook data is encrypted using the AES 128 algorithm. To decrypt the data, you will need to use your webhook key, which you can find in your LotusPay dashboard.

Here is sample code for decrypting the webhook post.

Steps for testing in Java:

1. Save the sample code as WebHookDecrypt.java
2. Replace the contents of and as per specification, and save the file.
3. Compile using `javac WebHookDecrypt.java`.
4. If compilation succeeds, run using `java WebHookDecrypt`.
5. You should see the decrypted event data in your console.




### Step 1.1 d Receiving webhooks with an HTTPS server


If you use an HTTPS URL for your webhook endpoint, LotusPay will validate that the connection to your server is secure before sending your webhook data. For this to work, your server must be correctly configured to support HTTPS with a valid server certificate.




### Step 1.1 e Order of webhooks


LotusPay does not guarantee delivery of events in the order in which they are generated. For example, submitting a source might generate the following events: source.submitted mandate.active Your endpoint should not expect delivery of these events in this order and should handle this accordingly. You can also use the API to fetch any missing objects (e.g. you can fetch the source and mandate objects using the information from mandate.active if you happen to receive this event first).




### Step 1.1 f Responding to a webhook


To acknowledge receipt of a webhook, your endpoint should return a 2xx HTTP status code. All response codes outside this range, including 3xx codes, will indicate to LotusPay that you did not receive the webhook. This does mean that a URL redirection or a "Not Modified" response will be treated as a failure. LotusPay will ignore any other information returned in the request headers or request body.

If the initial webhook post fails for an event, we will re-attempt to post up to nine times with an exponential back off between attempts (in minutes: 1, 2, 4, 8, 16, 32, 64, 128, 256), ceasing if successful or after nine re-attempts (whichever is sooner). If you miss any event webhooks, you can reconcile either by manually retrying using the POST Event Webhook API endpoint, or you can query for the event with the GET Event API endpoint.




### Step 1.1 g Best practices


Before going live, test that your webhook is working properly. You can do so by using the test environment. To do this, add the endpoint to which test events should be sent. Next, click the **Test Webhook**  button (visible to admin users only). Note that because these are dummy, test events, they will not map to real customers, mandates, ACH debits, or other objects in your account.

If your webhook script performs complex logic, or makes network calls, it's possible that the script would time out before LotusPay sees its complete execution. For that reason, you might want to have your webhook endpoint immediately acknowledge receipt by returning a 2xx HTTP status code, and then perform the rest of its duties.

Webhook endpoints might occasionally receive the same event more than once. We advise you to guard against duplicated event receipts by making your event processing idempotent. One way of doing this is logging the events you've processed, and then not processing already-logged events. Additionally, we recommend verifying webhook signatures to confirm that received events are being sent from LotusPay.



## Sample Code Snippets:
### Top Header:

#### Source Sample Webhook Code Snippet:

```source sample webhook
{"success":false,"message":"No Data found for the given path"}
```

#### Mandate Sample Webhook Code Snippet:

```mandate sample webhook
{"success":false,"message":"No Data found for the given path"}
```

#### Customer Sample Webhook Code Snippet:

```customer sample webhook
{"success":false,"message":"No Data found for the given path"}
```

