***

title: How to Decrypt the Webhook Payload
slug: guides/how-to-decrypt-webhook-payload
subtitle: Verify and decode the encrypted `data` field returned in Transak webhook events
---------------------

For a complete page index, fetch https://docs.transak.com/llms.txt

Transak sends the webhook payload in the `data` field as a signed JWT. To read the actual order or KYC payload, verify the JWT using your **Partner Access Token** and then decode its claims on your backend.

## Before You Start

* Your webhook endpoint must already be configured with Transak.
* You need a valid **Partner Access Token**. Follow [How to Create a Partner Access Token](/guides/how-to-create-partner-access-token).
* Perform verification and decoding only on your **server**. Do not expose the access token in frontend code.

<Frame>
  <div>
    Always verify the JWT signature before trusting any webhook data. Do not decode the payload without verification.
  </div>
</Frame>

## How It Works

When Transak sends a webhook, the payload includes an encrypted `data` field. Your backend should:

<Steps>
  <Step title="Receive the webhook request">
    Store the raw `data` field exactly as received from the webhook body.
  </Step>

  <Step title="Load your Partner Access Token">
    Use the Partner Access Token as the JWT signing secret.
  </Step>

  <Step title="Verify the JWT signature">
    Verify the webhook `data` field before processing it. Reject the request if signature validation fails.
  </Step>

  <Step title="Read the decoded claims">
    Once verified, parse the claims to access the original `webhookData` object and event details.
  </Step>
</Steps>

## Code Samples

<Tabs>
  <Tab title="JavaScript">
    <Steps>
      <Step title="Install the dependency">
        **NPM Package:** [`jsonwebtoken`](https://www.npmjs.com/package/jsonwebtoken)

        ```bash
        npm install jsonwebtoken
        ```
      </Step>

      <Step title="Verify and decode the webhook payload">
        ```javascript
        import jwt from "jsonwebtoken";

        // JWT token received from the webhook response's data field
        const webhookData = "eyJhbGciOiJIU.eyJ3ZWJob29-rRGF0.W07q-JG6jlyzid4";

        // Your Access Token — used as the signing secret
        const accessToken = "ACCESS_TOKEN";

        // Verify and decode the JWT token
        const decodedData = jwt.verify(webhookData, accessToken);

        console.log(decodedData);
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Java">
    <Tabs>
      <Tab title="Gradle">
        <Steps>
          <Step title="Install dependencies">
            ```groovy
            dependencies {
                implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
                implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
                implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
            }
            ```
          </Step>

          <Step title="Verify and decode the webhook payload">
            ```java
            package com.transak.webhookjavamaven;

            import io.jsonwebtoken.Claims;
            import io.jsonwebtoken.Jwts;
            import io.jsonwebtoken.security.Keys;
            import javax.crypto.SecretKey;

            public class WebhookJavaMavenApplication {

                public static void main(String[] args) {
                    // JWT token received from the webhook response's data field
                    String webhookData = "eyJhbGciOiJIU.eyJ3ZWJob29-rRGF0.W07q-JG6jlyzid4";

                    // Your Access Token — used as the signing secret
                    String accessToken = "ACCESS_TOKEN";

                    SecretKey key = Keys.hmacShaKeyFor(accessToken.getBytes());

                    Claims claims = Jwts.parserBuilder()
                            .setSigningKey(key)
                            .build()
                            .parseClaimsJws(webhookData)
                            .getBody();

                    System.out.println("Claims: " + claims);
                }
            }
            ```
          </Step>
        </Steps>
      </Tab>

      <Tab title="Maven">
        <Steps>
          <Step title="Install dependencies">
            ```xml
            <dependencies>
                <dependency>
                    <groupId>io.jsonwebtoken</groupId>
                    <artifactId>jjwt-api</artifactId>
                    <version>0.11.5</version>
                </dependency>
                <dependency>
                    <groupId>io.jsonwebtoken</groupId>
                    <artifactId>jjwt-impl</artifactId>
                    <version>0.11.5</version>
                </dependency>
                <dependency>
                    <groupId>io.jsonwebtoken</groupId>
                    <artifactId>jjwt-jackson</artifactId>
                    <version>0.11.5</version>
                </dependency>
            </dependencies>
            ```
          </Step>

          <Step title="Verify and decode the webhook payload">
            ```java
            package com.transak.webhookjavamaven;

            import io.jsonwebtoken.Claims;
            import io.jsonwebtoken.Jwts;
            import io.jsonwebtoken.security.Keys;
            import javax.crypto.SecretKey;

            public class WebhookJavaMavenApplication {

                public static void main(String[] args) {
                    // JWT token received from the webhook response's data field
                    String webhookData = "eyJhbGciOiJIU.eyJ3ZWJob29-rRGF0.W07q-JG6jlyzid4";

                    // Your Access Token — used as the signing secret
                    String accessToken = "ACCESS_TOKEN";

                    SecretKey key = Keys.hmacShaKeyFor(accessToken.getBytes());

                    Claims claims = Jwts.parserBuilder()
                            .setSigningKey(key)
                            .build()
                            .parseClaimsJws(webhookData)
                            .getBody();

                    System.out.println("Claims: " + claims);
                }
            }
            ```
          </Step>
        </Steps>
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Go">
    <Steps>
      <Step title="Install dependencies">
        **Package:** [`github.com/golang-jwt/jwt/v5`](https://pkg.go.dev/github.com/golang-jwt/jwt/v5)

        ```bash
        go get github.com/golang-jwt/jwt/v5
        ```
      </Step>

      <Step title="Verify and decode the webhook payload">
        ```go
        package main

        import (
          "encoding/json"
          "fmt"
          "log"

          "github.com/golang-jwt/jwt/v5"
        )

        func main() {
          // JWT token received from the webhook response's data field
          webhookData := "eyJhbGciOiJIU.eyJ3ZWJob29-rRGF0.W07q-JG6jlyzid4"

          // Your Access Token — used as the signing secret
          secretKey := "ACCESS_TOKEN"

          token, _ := jwt.Parse(webhookData, func(token *jwt.Token) (interface{}, error) {
            return []byte(secretKey), nil
          })

          if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
            jsonData, _ := json.MarshalIndent(claims, "", "  ")
            fmt.Println("Decoded JWT Claims:\n", string(jsonData))
          } else {
            log.Println("Invalid JWT or claims")
          }
        }
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Sample Decrypted Payload

<CodeBlock language="json">
  ```json
  {
    "webhookData": {
      "id": "181b6159-2192-4f68-8647-f48e6e8f58c7",
      "walletAddress": "0xD902d7eBF7bcE",
      "createdAt": "2024-08-23T10:33:09.426Z",
      "status": "COMPLETED",
      "fiatCurrency": "EUR",
      "userId": "243a8ce2-9cc6-41a9-aaeb-b0deeb09a3",
      "cryptoCurrency": "ETH",
      "isBuyOrSell": "BUY",
      "fiatAmount": 32,
      "ipAddress": "35.177.158.9",
      "amountPaid": 32,
      "paymentOptionId": "sepa_bank_transfer",
      "walletLink": "https://sepolia.etherscan.io/address/0xD902d7eBF7bcE",
      "quoteId": "0b9edf4d-2de1-4f2e-bdb6-07bc61c380f5",
      "orderProcessingType": "NORMAL",
      "addressAdditionalData": false,
      "network": "ethereum",
      "conversionPrice": 0.00041416655266757863,
      "cryptoAmount": 0.01211023,
      "totalFeeInFiat": 2.76,
      "fiatAmountInUsd": 35.57,
      "countryCode": "IN",
      "stateCode": "Karnataka",
      "orderChannelType": "WIDGET",
      "userKycType": "STANDARD",
      "cardPaymentData": {
        "orderId": "181b6159-2192-4f68-8647-f48e6e8f58c7",
        "paymentId": "66c8656bb38a7908fadc77db",
        "pgData": {
          "paymentOptions": [
            {
              "currency": "EUR",
              "id": "sepa_bank_transfer",
              "name": "Bank Transfer Details",
              "fields": [
                { "name": "Bank Name", "value": "Transak Limited" },
                { "name": "IBAN", "value": "GB69MOCK00000003743944" },
                { "name": "Bank Name", "value": "Modulr" },
                { "name": "Bank Address", "value": "Scale Space, 58 Wood Lane, London, W12 7RZ" }
              ]
            }
          ],
          "liquidityProvider": "MODULR",
          "status": "CREATED"
        },
        "liquidityProvider": "MODULR",
        "updatedAt": "2024-08-23T10:33:58.753Z",
        "status": "CAPTURED",
        "processedOn": "2024-08-23T10:33:57.000Z"
      },
      "statusHistories": [
        {
          "status": "PENDING_DELIVERY_FROM_TRANSAK",
          "createdAt": "2024-08-23T10:33:59.408Z",
          "message": "💸 Payment reconciled successfully. Received 32 EUR",
          "isEmailSentToUser": false,
          "partnerEventId": "ORDER_PROCESSING"
        }
      ],
      "isFirstOrder": false,
      "updatedAt": "2024-08-23T10:34:06.371Z",
      "completedAt": "2024-08-23T10:34:39.412Z",
      "transactionHash": "DUMMY_TX_ID",
      "transactionLink": "https://sepolia.etherscan.io/tx/DUMMY_TX_ID",
      "conversionPriceData": {
        "id": "139474c7-99c5-4232-9a05-c6ccd6a973ed",
        "createdAt": "2024-08-23T10:34:06.352Z",
        "fiatCurrency": "EUR",
        "cryptoCurrency": "ETH",
        "paymentMethod": "sepa_bank_transfer",
        "fiatAmount": 32,
        "network": "ethereum",
        "cryptoAmount": 0.01211023,
        "isBuyOrSell": "BUY",
        "conversionPrice": 0.00041416641727771563,
        "marketConversionPrice": 0.00041628949369556297,
        "slippage": 0.51,
        "cryptoLiquidityProvider": "transak",
        "fiatLiquidityProvider": "coinbase",
        "partnerApiKey": "d79671a4-b021-4a4f-a444-6862a680a94b",
        "sourceTokenAmount": 0.012110226041200406,
        "sourceToken": "ETH",
        "notes": [],
        "fiatFeeAmount": 2.76,
        "feeDecimal": 0.08625,
        "swaps": [
          {
            "sourceCurrency": "EUR",
            "destinationCurrency": "USDT",
            "sourceAmount": 32,
            "destinationAmount": 35.57563545494966,
            "paymentMethod": "sepa_bank_transfer",
            "liquidityProvider": "coinbase",
            "conversionPrice": 1.111738607967177,
            "feeInSourceAmount": 0,
            "networkFeeInSourceAmount": 0,
            "marketConversionPrice": 1.111738607967177,
            "isNonCustodial": false,
            "isFiatliquidityProvider": true,
            "isFiatPartnerDirectCryptoDeposit": false,
            "isFiatPartnerAccountWalletDeposit": false,
            "liquidityProviderData": false,
            "originalDestinationAmount": 35.57563545494966
          },
          {
            "sourceCurrency": "USDT",
            "destinationCurrency": "ETH",
            "sourceAmount": 35.57563545494966,
            "destinationAmount": 0.0132533253528869,
            "liquidityProvider": "transak",
            "conversionPrice": 0.0003725393849863884,
            "networkFeeInSourceAmount": 0,
            "networkFeeInDestinationAmount": 0,
            "marketConversionPrice": 0.0003725393849863884,
            "liquidityProviderData": false,
            "isNonCustodial": false
          },
          {
            "sourceCurrency": "ETH",
            "destinationCurrency": "ETH",
            "sourceAmount": 0.0132533253528869,
            "destinationAmount": 0.0132533253528869,
            "liquidityProvider": "transak",
            "conversionPrice": 1,
            "isCryptoliquidityProvider": true,
            "networkFeeInSourceAmount": 0.000067651170404,
            "networkFeeInDestinationAmount": 0.000067651170404,
            "marketConversionPrice": 1,
            "liquidityProviderData": false,
            "isFiatPartnerAccountWalletDeposit": false
          }
        ],
        "fees": [
          {
            "name": "Transak fee",
            "value": 2.6,
            "id": "transak_fee",
            "ids": ["transak_fee", "partner_fee"]
          },
          {
            "name": "Network/Exchange fee",
            "value": 0.16,
            "id": "network_fee",
            "ids": ["network_fee"]
          }
        ],
        "fiatAmountInUsd": 35.57,
        "internalFees": [
          { "name": "Network/Exchange fee", "id": "network_fee", "value": 0.16 },
          { "name": "Transak fee", "id": "transak_fee", "value": 1 },
          { "name": "Transak fee", "id": "partner_fee", "value": 1.6 }
        ],
        "cost": {
          "ethPriceInLocalCurrency": 2402.17448469,
          "gasCostinLocalCurrency": 0.16334786495892,
          "transakMinimumFee": 1,
          "transakFeeAmount": 1,
          "fiatLiquidityProviderFee": 0,
          "gasCostinLocalCurrencyByFiatPartner": 0,
          "gasCostinLocalCurrencyByCryptoPartner": 0,
          "partnerFeeDecimal": 0.05,
          "partnerFeeInLocalCurrency": 1.6,
          "totalFeeDecimal": 0.08625,
          "totalFeeAmount": 2.76,
          "gasCurrency": "ETH",
          "gasInNativeToken": 0.000068,
          "gasCurrencyRateInUsd": 0.0003744603090795391,
          "totalAmountChargedByTransak": 2.76334786495892
        }
      },
      "partnerFeeInLocalCurrency": 1.6
    },
    "eventID": "ORDER_COMPLETED",
    "createdAt": "2024-08-23T10:34:40.070Z"
  }
  ```
</CodeBlock>