---
title: "Card encryption with JWE"
description: "Use JWE to encrypt card details for your custom card integration."
url: "https://docs.adyen.com/online-payments/card-encryption-with-jwe"
source_url: "https://docs.adyen.com/online-payments/card-encryption-with-jwe.md"
canonical: "https://docs.adyen.com/online-payments/card-encryption-with-jwe"
last_modified: "2025-07-09T09:28:00+02:00"
language: "en"
---

# Card encryption with JWE

Use JWE to encrypt card details for your custom card integration.

[View source](/online-payments/card-encryption-with-jwe.md)

You can use JSON Web Encryption (JWE) to encrypt your shopper's card details when implementing your own UI. With JWE, you use a third-party JWT library and an Adyen-provided encryption key to encrypt card details from your shopper's device.

## Requirements

Before you begin, take into account the following requirements, limitations, and preparations.

| Requirement                                                               | Description                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Integration type**                                                      | Make sure you have an [API only integration](/online-payments/build-your-integration/advanced-flow/?platform=Web\&integration=API%20only) for Web.                                                                          |
| **[API credential roles](/development-resources/api-credentials/roles/)** | Make sure that you have the following role:- **Checkout webservice role** (assigned by default)                                                                                                                             |
| **[Customer Area roles](/account/user-roles)**                            | Make sure that you have the **Manage API credentials** role.                                                                                                                                                                |
| **Limitations**                                                           | Make sure to check your PCI DSS requirements in the [PCI DSS compliance guide](/development-resources/pci-dss-compliance-guide).                                                                                            |
| **Setup steps**                                                           | Before you begin:- Make sure [your backend can make a payment](/online-payments/build-your-integration/advanced-flow/?platform=Web\&integration=API%20only#make-a-payment).
- Download CSE public key as X.509 certificate. |

## JSON Web Encryption (JWE)

We offer multiple ways for you to accept [card payments](/payment-methods/cards) for different use cases and different PCI compliance levels. Card detail encryption with JWE is for when you want to have access to the unencrypted card details from your frontend, for example when:

* Offering card payments with Adyen in a multiple-payment-service-provider setup.
* Running payments through your own [risk engine](/risk-management/#risk-engine).

In a JWE setup, you use a [third-party JWT library](https://jwt.io/libraries?language=JavaScript) to encrypt card details as a JSON Web Token. The encrypted details can be safely passed to your server, where you can use them for a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request. We never share decryption keys, so once you encrypt card details only Adyen can decrypt them to process your payment.

JWE supports multiple algorithms for encryption (`enc`) and securing the JSON Web Signature (`alg`). In our integration guide, we advise you use specific algorithms that meet our security standards.

## How it works

Encrypting card details using JWE involves the following:

1. You download your merchant account-specific X.509 certificate from the [Customer Area](https://ca-test.adyen.com/).
2. You compute your JSON Web Key (JWK) from your X.509 certificate.
3. Your shopper enters their card details in your checkout.
4. You encrypt the card details on the client side using your JWK key.
5. You pass the encrypted card details to your server.
6. You make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request using the encrypted card details.

## Get your X.509 certificate

Before you encrypt card details with JWE, get your X.509 Certificate:

1. In your [Customer Area](https://ca-test.adyen.com/), go to **Developers** > **API credentials**.
2. Select the relevant API credential.
3. From the **Client side encryption** section, under **X509 Certificate**, select **Download**.

## Compute your JWK

Then, use your X509 Certificate to compute your JWK.

1. Install and import a third-party Javascript [JWT library](https://jwt.io/libraries?language=JavaScript), for example [JavaScript Object Signing and Encryption (JOSE)](https://github.com/panva/jose).

   The following instructions use the JavaScript (JOSE) library.

2. Assign the content of the X.509 Certificate to a variable.

   **Assign the X509 Certificate to a variable**

   ```javascript
   const x509 = `-----BEGIN CERTIFICATE-----
   MIIBXjCCAQSgAwIBAgIGAXvykuMKMAoGCCqGSM49BAMCMDYxNDAyBgNVBAMMK3Np
   QXBNOXpBdk1VaXhXVWVGaGtjZXg1NjJRRzFyQUhXaV96UlFQTVpQaG8wHhcNMjEw
   OTE3MDcwNTE3WhcNMjIwNzE0MDcwNTE3WjA2MTQwMgYDVQQDDCtzaUFwTTl6QXZN
   VWl4V1VlRmhrY2V4NTYyUUcxckFIV2lfelJRUE1aUGhvMFkwEwYHKoZIzj0CAQYI
   KoZIzj0DAQcDQgAE8PbPvCv5D5xBFHEZlBp/q5OEUymq7RIgWIi7tkl9aGSpYE35
   UH+kBKDnphJO3odpPZ5gvgKs2nwRWcrDnUjYLDAKBggqhkjOPQQDAgNIADBFAiEA
   1yyMTRe66MhEXID9+uVub7woMkNYd0LhSHwKSPMUUTkCIFQGsfm1ecXOpeGOufAh
   v+A1QWZMuTWqYt+uh/YSRNDn
   -----END CERTIFICATE-----`
   ```

3. Create a public key from your X.509 certificate.

   **Create a public encryption key**

   ```javascript
   const rsaPublicKey = await jose.importX509(x509, 'RSA-OAEP-256')
   ```

## Encrypt card details

When making a payment, use the encryption key to encrypt card details.

1. Create an object to encrypt.

   **Create object to encrypt**

   ```javascript
   const dateTimeString = new Date().toISOString();
   const objectToEncrypt = JSON.stringify({
       "cvc": "737",
       "number": "4111111111111111",
       "expiryMonth": "03",
       "expiryYear": "2030",
       "generationtime": dateTimeString
   });
   ```

   * Card details to encrypt go by keys `cvc`, `number`, `expiryMonth`, and `expiryYear`. Go to [paymentMethod](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-paymentMethod) and select **CardDetails** to learn about the card detail parameters.
   * `generationtime` is a string representing the JavaScript date object, based on [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601).

2. Encrypt the card detail object.

   **Encrypt card details**

   ```javascript
   const jwe = await new jose.CompactEncrypt(new TextEncoder()
     .encode(objectToEncrypt))
     .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM', version: '1' })
     .encrypt(rsaPublicKey);
   ```

3. Pass the encrypted object (`jwe`) to your server. Include the `jwe` object when you make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request.

   **Payments request with JWE-encrypted card details**

   ```json
   {
      ...
      "paymentMethod": {
        "type": "scheme",
        "encryptedCard": jwe
      }
      ...
   }
   ```

## See also

* [PCI DSS compliance guide](/development-resources/pci-dss-compliance-guide)
* [Card Component](/payment-methods/cards/web-component)
* [API only with encrypted card data](/payment-methods/cards/custom-card-integration)
