Credit Card Number (PCI DSS) Protection Endpoint


METHOD: POST
ENDPOINT: https://dev.qupass.in/api/ccn

Description

The Credit Card Number endpoint enables the protection and unprotection of payment card identifiers while preserving their numeric data type and structural semantics.

The returned token consists exclusively of decimal digits (0–9), ensuring compatibility with systems that expect numeric-only identifiers, while allowing for an expanded length to accommodate secure, high-entropy token generation.

By maintaining the same encoding space — specifically the decimal digit domain — the endpoint ensures that protected values remain syntactically valid within numeric processing pipelines, even though the original fixed-length constraints (e.g., 16 digits depending on card type) are not retained.

This approach enables strong protection guarantees without disrupting storage compatibility, input validation logic that relies on numeric character sets, or downstream data handling workflows.

Examples

  • Input: 4539 1488 0343 6467 (Numeric)
    • QuFold_Token: 497946249 763432447 047334895 245702506346
      • ✅ Character set preserved (Numeric block)
      • ✅ Encoding compatibility is maintained
    • FPE: 1703 8460 2554 8666
      • ✅ Length and Character set preserved (Numeric block)
      • ✅ Encoding compatibility is maintained


Request Payload


  • HEADER PARAMETERS
    • x-api-key (required) Provides access to one or more functions in the API Playground.
    • Authorization (required) The JWT token issued upon successful authentication.
    • qu-token (required) QU token that you revceive at the time of login.

  • PAYLOAD DETAILS
    • id (required) Integer identifier for the request.
    • operation (required) Specifies the protection operation. Available: [protect | unprotect].
    • data (required) Array of values to be transformed.
    • options:
      • method - Transformation method; Available: [tokenise | fpe | mask | redact | passthrough].
        • Defaults to tokenise
      • scope - User-defined context string; differentiates tokens across applications or datasets. (e.g., app1, azure+app1).
        • Defaults to no-scope
      • noise - Adds controlled randomness.
        • Defaults to 0, ensures deterministic tokenization within scope
        • Non-zero values produce possible distinct tokens for the repeated inputs


Sample Request


    curl --location 'https://dev.qupass.in/api/ccn' \
    --header 'x-api-key: <API_Key>' \
    --header 'Authorization: <JWT_TOKEN>' \
    --header 'qu-token: <QU_TOKEN>' \
    --header 'Content-Type: application/json' \
    --data '{
      "id": 1,
      "operation": "protect",
      "data": [
          "4539 1488 0343 6467",
          "4485 2756 9823 1029",
          "4716 3344 5566 7788"
      ],
      "options": {
        "method": "tokenise",
        "scope": "App1"
      }
    }'
    package main

    import ( 
      "io" 
      "fmt"
      "strings" 
      "net/http" 
      )
      
    func main() { 
      API_Key := "<API_Key>"
      JWT_Token := "<JWT_TOKEN>"
      QU_Token := "<QU_TOKEN>"
      
      url := "https://dev.qupass.in/api/ccn"
      data := strings.NewReader(`{ 
          "id":1,
          "operation": "protect", 
          "data": [
            "4539 1488 0343 6467",
            "4485 2756 9823 1029",
            "4716 3344 5566 7788"
          ],
          "options": {
            "method": "tokenise",
            "scope": "App1"
          } 
      }`)

      req, err := http.NewRequest("POST", url, data)
      if err != nil {
        fmt.Println(err)
        return
      }

      req.Header.Set("x-api-key", API_Key)
      req.Header.Set("Authorization", JWT_Token)
      req.Header.Set("qu-token", QU_Token)
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
        fmt.Println(err)
        return
      }
      defer resp.Body.Close()

      body, err := io.ReadAll(resp.Body)
      if err != nil {
        fmt.Println(err)
        return
      }

      fmt.Println(string(body))
    }
    import java.net.HttpURLConnection;
    import java.net.URI;
    import java.net.URL;
    import java.io.OutputStream;
    import java.io.InputStreamReader;
    import java.io.BufferedReader;
    import java.nio.charset.StandardCharsets;

    public class APIRequest {
        public static void main(String[] args) {
            try {
                String API_Key = "<API_Key>";
                String JWT_Token = "<JWT_TOKEN>";
                String QU_Token = "<QU_TOKEN>";

                URI uri = new URI("https://dev.qupass.in/api/ccn");

                String data = "{"
                        + "\"id\": 1,"
                        + "\"operation\": \"protect\","
                        + "\"data\": ["
                        + "\"4539 1488 0343 6467\","
                        + "\"4485 2756 9823 1029\","
                        + "\"4716 3344 5566 7788\""
                        + "],"
                        + "\"options\": {"
                        + "\"method\": \"tokenise\","
                        + "\"scope\": \"App1\""
                        + "}"
                        + "}";

                URL url = uri.toURL();
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();

                conn.setRequestMethod("POST");
                conn.setRequestProperty("x-api-key", API_Key);
                conn.setRequestProperty("Authorization", JWT_Token);
                conn.setRequestProperty("qu-token", QU_Token);
                conn.setRequestProperty("Content-Type", "application/json");
                conn.setDoOutput(true);

                // Send request body
                try (OutputStream os = conn.getOutputStream()) {
                    byte[] input = data.getBytes(StandardCharsets.UTF_8);
                    os.write(input, 0, input.length);
                }

                int statusCode = conn.getResponseCode();

                BufferedReader br;
                if (statusCode >= 200 && statusCode < 300) {
                    br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
                } else {
                    br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8));
                }

                StringBuilder response = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    response.append(line.trim());
                }

                System.out.println(response.toString());

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    const API_Key = "<API_Key>";
    const JWT_Token = "<JWT_TOKEN>";
    const QU_Token = "<QU_TOKEN>";

    const url = "https://dev.qupass.in/api/ccn";

    const data = {
      id: 1,
      operation: "protect",
      data: [
        "4539 1488 0343 6467",
        "4485 2756 9823 1029",
        "4716 3344 5566 7788"
      ],
      options: {
        method: "tokenise",
        scope: "App1"
      }
    };

    fetch(url, {
      method: "POST",
      headers: {
        "x-api-key": API_Key,
        "Authorization": JWT_Token,
        "qu-token": QU_Token,
        "Content-Type": "application/json"
      },
      body: JSON.stringify(data)
    })
      .then(async (response) => {
        const text = await response.text(); // raw response like Python's response.text
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${text}`);
        }
        console.log(text);
      })
      .catch((error) => {
        console.error("Error:", error.message);
      });
    <?php

    $API_Key = "<API_Key>";
    $JWT_Token = "<JWT_TOKEN>";
    $QU_Token = "<QU_TOKEN>";

    $url = "https://dev.qupass.in/api/ccn";

    $headers = [
        "x-api-key: $API_Key",
        "Authorization: $JWT_Token",
        "qu-token: $QU_Token",
        "Content-Type: application/json"
    ];

    $data = [
        "id" => 1,
        "operation" => "protect",
        "data" => [
            "4539 1488 0343 6467",
            "4485 2756 9823 1029",
            "4716 3344 5566 7788"
        ],
        "options" => [
            "method" => "tokenise",
            "scope" => "App1"
        ]
    ];

    $ch = curl_init($url);

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        echo 'Error:' . curl_error($ch);
    } else {
        echo $response;
    }

    curl_close($ch);
    ?>
    import requests
    import json

    API_Key = "<API_Key>"
    JWT_Token = "<JWT_TOKEN>"
    QU_Token = "<QU_TOKEN>"

    url = 'https://dev.qupass.in/api/ccn'
    headers = {
      'x-api-key': API_Key,
      'Authorization': JWT_Token,
      'qu-token': QU_Token,
      'Content-Type': 'application/json'
    }

    data = {
      "id": 1,
      "operation": "protect",
      "data": [
        "4234 5678 9123",
        "4234 5678 9124",
        "5234 5678 9123"
      ],
      "options": {
        "method": "tokenise",
        "scope": "App1"
      }
    }

    response = requests.post(url, headers=headers, data=json.dumps(data))
    print(response.text)


Sample Data Payload and Output


PROTECTION SCENARIOS:

InputOutput
  {
    "operation": "protect",
    "data": [
        "4539 1488 0343 6467",
        "4539 1488 0343 6467",
        "4485 2756 9823 1029",
        "4716 3344 5566 7788"
    ],
    "method": "*" // [tokenise, fpe, .,]
  }
    {
      "operation": "protect",  
      "result": [
          "497946249 763432447 047334895 245702506346",
          "497946249 763432447 047334895 245702506346",
          "457390255 029950752 552744964 28500945844",
          "728524493 444604842 355799752 764330849795"
      ],
      "method": "tokenise"
    }
    {
      "operation": "protect",  
      "result": [
          "856240743927 007725339892 274695595422 584660772294",
          "856240743927 007725339892 274695595422 584660772294",
          "82895796438 04504786376 94564067758 72050385670945",
          "33389223766 23557229600 24859980405 26062945042092"
      ],
      "method": "tokenise",
      "scope": "App1" //SCOPE
    }
    {
      "operation": "protect",  
      "result": [
          "0253355800 6775090759 3724380300 67734345355",
          "8674390596 7052968937 0760490827 48348656265",
          "046848028 603680229 337422446 876592523482",
          "8524900258 3083325289 0982442368 0335033247"
      ],
      "method": "tokenise",
      "noise": "2" //NOISE
    }
    {
      "operation": "protect",  
      "result": [
          "944549355935 573892025370 268329238604 0505304438522",
          "385556304677 758405005844 336486978336 0643377492952",
          "568252880775 709648352778 208579898553 0339298274095",
          "674929500324 480530483496 484855837963 7543789274096"
      ],
      "method": "tokenise",
      "scope": "App1", //SCOPE
      "noise": "2" //NOISE
    }
    {
      "operation": "protect",  
      "result": [
          "1703 8460 2554 8666",
          "1703 8460 2554 8666",
          "9814 0416 2939 3674",
          "4555 4779 0971 4880"
      ],
      "method": "fpe" // FPE
    }

UNPROTECTION SCENARIOS:

InputOutput
  {
    "operation": "unprotect",
    "data": [
        "497946249 763432447 047334895 245702506346",
        "497946249 763432447 047334895 245702506346",
        "457390255 029950752 552744964 28500945844",
        "728524493 444604842 355799752 764330849795"
    ],
    "method": "tokenise"
  }
    {
      "operation": "unprotect",  
      "result": [
          "4539 1488 0343 6467",
          "4539 1488 0343 6467",
          "4485 2756 9823 1029",
          "4716 3344 5566 7788"
      ]
    }
  {
    "operation": "unprotect",
    "data": [
        "3523239483 7947594550 8907477247",
        "3523239483 747594550 8907477247", //INVALID
        "7588300965 5228844046 6574255785",
        "285302375 258369464 53955372557"
    ],
    "method": "tokenise"
  }
    {
      "operation": "unprotect",  
      "result": [
          "4234 5678 9123",
          "3523239483 747594550 8907477247", //INVALID
          "4234 5678 9124",
          "5234 5678 9123"
      ],
      "discrepancy": {
        "invalid_token": [ //INVALID
          1 // INDEX
        ]
      }
    }
  {
    "operation": "unprotect",
    "data": [
        "3523239483 7947594550 8907477247",
        "3523239483 7947594550 8907477247",
        "7588300965 5228844046 6574255785",
        "285302375 258369464 53955372557"
    ],
    "scope":"App2", //INVALID
    "method": "tokenise"
  }
    {
      "operation": "unprotect",  
      "result": [
          "3523239483 7947594550 8907477247",
          "3523239483 7947594550 8907477247",
          "7588300965 5228844046 6574255785",
          "285302375 258369464 53955372557"
      ],
      "discrepancy": {
        "invalid_scope": [ //INVALID
          0, //INDEX
          1,
          2,
          3
        ]
      }
    }
  {
    "operation": "unprotect",
    "data": [
        "1703 8460 2554 8666",
        "1703 8460 2554 8666",
        "9814 0416 2939 3674",
        "4555 4779 0971 4880"
    ],
    "method": "fpe"
  }
    {
      "operation": "unprotect",  
      "result": [
          "4539 1488 0343 6467",
          "4539 1488 0343 6467",
          "4485 2756 9823 1029",
          "4716 3344 5566 7788"
      ]
    }