Skip to content

    Token PAN to Funding PAN Resolution

    Detokenization API to resolve Funding PAN (FPAN) from Token PAN (TPAN/DPAN). The Token PAN is provided inside encryptedData (JWE) and the FPAN is returned inside encryptedData (JWE).

    Authentication

    Before you can use the Token PAN to Funding PAN Resolution API, your application must complete the on-boarding process.

    You will receive two sets of credentials:

    • Sandbox credentials (for test transactions)
    • Production credentials (for live transactions)

    Each set consists of a Client ID and a Client Secret. The Client Secret is confidential and must not be shared.

    To invoke this API you must obtain an OAuth 2.0 access token and send it in the HTTP Authorization header as a Bearer token.

    Important: The OAuth2 Token/Revoke endpoints are exposed by the Authorization Server (separate host) and are documented here for convenience. They are not part of the Resource Server paths in this OpenAPI document.

    OAuth 2.0

    OAuth 2.0 is the industry-standard protocol for authorization. See: RFC 6749.

    This API supports OAuth 2.0 with the confidential client type. A confidential client can keep its credentials secret when interacting with the Authorization Server.

    OAuth 2.0 defines four roles:

    1. Resource owner: Entity capable of granting access to a protected resource.
    2. Resource server: Server hosting protected resources, accepting requests using access tokens.
    3. Client: An application requesting protected resources on behalf of the resource owner.
    4. Authorization server: The server issuing access tokens to the client after successful authentication/authorization.

    At a high level, the flow is:

    1. Get an access token from the Authorization Server.
    2. Use the access token to call this API (the Resource Server).

    OAuth 2.0 uses an "authorization grant" to represent the authorization used to obtain an access token. This API supports the Client Credentials grant type.

    Authorization Server

    Token Endpoint

    POST /token

    With the Client Credentials grant type, the client requests an access token using only its own credentials. The access token returned for this API is of type Bearer.

    Clients should request the minimal necessary scope and lifetime. The Authorization Server may issue an access token with fewer rights than requested.

    Generate an access token (Client Credentials grant):

    1. Obtain a valid client_id and client_secret.
    2. Combine them as client_id:client_secret and Base64-encode the result.
    3. Call the Token Endpoint. Example:
    # NOTE: Only use -k in sandbox/test environments if TLS verification cannot be performed.
    curl -k -d "grant_type=client_credentials" \
      -H "Authorization: Basic <Base64 encoded client_id:client_secret>" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      https://api-gateway2.nets.eu/token
    

    Example response (access token may be opaque, not necessarily a JWT):

    {
      "token_type": "Bearer",
      "expires_in": 2061,
      "access_token": "ca19a540f544777860e44e75f605d927"
    }
    

    Note: Per RFC 6749, the Client Credentials grant type does not issue refresh tokens.

    Revoke Endpoint

    POST /revoke

    In case of credential theft or a security incident, revoke an access token using the Revoke Endpoint.

    Parameters

    • token (required): The token to revoke.
    • Basic Authorization header (required): Authorization: Basic <Base64 encoded client_id:client_secret>
    • token_type_hint (optional): Use access_token for Client Credentials. If omitted, the server searches multiple token spaces and revocation may take longer.

    Example:

    curl -X POST \
      https://api-gateway2.nets.eu/revoke \
      -H "Authorization: Basic <Base64 encoded client_id:client_secret>" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "token=<token_to_be_revoked>&token_type_hint=access_token"
    

    JWE using RSA-OAEP-256 and A256GCM

    The general approach for encrypting data using JWE with RSA key management and AES-GCM content encryption is as follows:

    • Use the Compact Serialization format, where the five elements are separated by a "." (period).
    • All JWE parts in compact form are Base64URL-encoded.
    • Use a hybrid encryption scheme:
      • Generate a random Content Encryption Key (CEK) (symmetric key).
      • Encrypt (wrap) the CEK with the recipient's RSA public key using RSA-OAEP-256.
      • Encrypt the plaintext using the CEK with A256GCM (AES-256-GCM).
    • Use alg = RSA-OAEP-256 to encrypt the CEK.
    • Use enc = A256GCM to encrypt the plaintext:
      • IV (Initialization Vector) size MUST be 96 bits (12 bytes).
      • Authentication Tag size MUST be 128 bits (16 bytes).
    • The Authentication Tag is NOT an HMAC. It is the AES-GCM authentication tag produced by the AEAD encryption operation.
    • AAD (Additional Authenticated Data) is NOT the raw header JSON. For JWE Compact Serialization, AAD is:
      • the ASCII bytes of the Base64URL-encoded protected header
      • i.e., AAD = ASCII( BASE64URL( UTF8(ProtectedHeaderJSON) ) )
    • All string-to-byte and byte-to-string conversions use UTF-8.

    NOTE: Refer to RFC 7516 (JWE) and RFC 7518 (JWA) for the complete specifications.

    JWE Protected Header

    Header Sample

    {
      "alg": "RSA-OAEP-256",
      "kid": "7ZEIVC16DGRDQKWZEE3X11LeJMDhyqQu8Q1ctnp4bylyQJCsw",
      "enc": "A256GCM"
    }
    

    Header Fields

    TagRequiredTypeDescription
    algRequiredEnumAlgorithm used to encrypt (wrap) the randomly generated CEK using the recipient's public key.
    kidRequired*StringKey Identifier for selecting the correct public key. In this specification, kid MUST reference the certificate's Subject Key Identifier (SKI) of the RSA public key certificate used for CEK encryption.
    encRequiredEnumContent encryption algorithm used by the CEK to encrypt the plaintext payload.

    *Whether kid is required is a profile decision. If you mandate key selection via certificate SKI, treat it as required for interoperability.

    kid representation (SKI)

    • kid MUST be derived from the certificate Subject Key Identifier (SKI) extension of the recipient's certificate.
    • The exact string encoding must be consistent across producer/consumer (common choices are Base64URL of the raw SKI bytes or hex). This document assumes a Base64URL-safe string representation.

    JWE Compact Serialization Output

    The resulting JWE is a single string composed of five Base64URL-encoded parts:

    BASE64URL(ProtectedHeader) || '.' ||
    BASE64URL(EncryptedKey)    || '.' ||
    BASE64URL(IV)              || '.' ||
    BASE64URL(Ciphertext)      || '.' ||
    BASE64URL(Tag)
    

    Where:

    • ProtectedHeader: UTF-8 JSON header, Base64URL-encoded.
    • EncryptedKey: CEK encrypted with RSA-OAEP-256, Base64URL-encoded.
    • IV: 96-bit IV for AES-GCM payload encryption, Base64URL-encoded.
    • Ciphertext: AES-GCM ciphertext output, Base64URL-encoded.
    • Tag: 128-bit AES-GCM authentication tag, Base64URL-encoded.

    General Steps for Data Encryption (RFC-aligned)

    Apply JWE to plaintext data by following these steps:

    1. Obtain the recipient's RSA 2048-bit (or stronger) public key from the certificate.
    2. Construct the JWE Protected Header JSON:
      • alg = "RSA-OAEP-256"
      • enc = "A256GCM"
      • kid = <certificate Subject Key Identifier (SKI)>
    3. Serialize the protected header as UTF-8 bytes and Base64URL-encode it:
      • E-HEADER = BASE64URL( UTF8(ProtectedHeaderJSON) )
    4. Compute AAD exactly as required for compact serialization:
      • AAD = ASCII( E-HEADER )
    5. Generate a random CEK of 256 bits (32 bytes) for A256GCM.
    6. Encrypt the CEK using the recipient's RSA public key with RSA-OAEP-256:
      • EncryptedKeyBytes = RSA-OAEP-256( PublicKey, CEK )
      • E-ENCRYPTED-KEY = BASE64URL(EncryptedKeyBytes)
    7. Generate a random IV of 96 bits (12 bytes) for AES-GCM payload encryption:
      • E-IV = BASE64URL(IVBytes)
    8. Encrypt the plaintext using AES-256-GCM with inputs (CEK, IVBytes, AAD):
      • Output is (CiphertextBytes, TagBytes)
      • TagBytes MUST be 16 bytes (128 bits)
    9. Base64URL-encode payload outputs:
      • E-CIPHERTEXT = BASE64URL(CiphertextBytes)
      • E-TAG = BASE64URL(TagBytes)
    10. Build the final JWE Compact Serialization string:
    E-HEADER || '.' || E-ENCRYPTED-KEY || '.' || E-IV || '.' || E-CIPHERTEXT || '.' || E-TAG
    

    API Specification

    Content types

    Requests must be JSON:

    • Content-Type: application/json

    Clients SHOULD request JSON responses:

    • Accept: application/json

    Responses are JSON:

    • Content-Type: application/json

    Scroll down for code samples, example requests and responses.
    Select a language for code samples from the tabs or the mobile navigation menu.

    Scheme DeTokenization - Inbound

    Inbound API from authorized clients (e.g., 3DS) to LCM

    Resolve FPAN (Funding PAN) from TPAN (Token PAN)

    POST /token/fpan-resolution

    Resolves Funding PAN (FPAN) from a Token PAN (TPAN/DPAN).

    The request payload contains tokenInfo.encryptedData as a JWE Compact Serialization string. After decryption, the expected JSON contains:

    • tokenPan (string, PAN digits)
    • tokenExpiry (string, MMYYYY)

    The response returns encryptedData as a JWE Compact Serialization string. After decryption, the expected JSON contains:

    • fpan (string, PAN digits)
    • fpanExpiry (string, MMYYYY)

    Parameters

    • Authorizationstringrequired

      Bearer access token (opaque string) obtained via OAuth 2.0 Client Credentials.

    • X-Request-IDstring (uuid)required

      Client-generated request identifier for end-to-end traceability.

    • X-3DS-Server-Transaction-IDstring (uuid)required

      3DS Server Transaction ID (end-to-end identifier) in UUID textual representation as specified by RFC 9562.

    Resolve FPAN (Funding PAN) from TPAN (Token PAN)

    var client = new RestClient("https://api-gateway2.nets.eu/token/fpan-resolution");
    var request = new RestRequest(Method.POST);
    request.AddHeader("content-type", "application/json");
    request.AddHeader("X-Request-ID", "SOME_STRING_VALUE");
    request.AddHeader("X-3DS-Server-Transaction-ID", "SOME_STRING_VALUE");
    request.AddHeader("Authorization", "Bearer REPLACE_BEARER_TOKEN");
    request.AddParameter("application/json", "{\"REPLACE_REQUEST_BODY\":\"REPLACE_REQUEST_BODY\"}", ParameterType.RequestBody);
    IRestResponse response = client.Execute(request);

    Request body

    • tokenInfoobjectrequired

      Token identification. The Token PAN SHOULD be provided in encryptedData.

      • encryptedDatastringrequired

        Encrypted payload (JWE Compact Serialization) containing token PAN and token expiry. Example decrypted JSON: { "tokenPan": "4123456789012345", "tokenExpiry": "062029" } (tokenExpiry is MMYYYY)

        example: eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiN1pFSVZDMTZER1JEUUtXWkVFM1gxMUxlSk1EaHlxUXU4UTFjdG5wNGJ5bHlRSkNzdyJ9.ZW5jcnlwdGVkQ0VL.aXZEYXRhMTIz.dG9rZW5QYW5DaXBoZXJ0ZXh0.dGFnVmFsdWUxMjM0NTY

    Request body

    {
        "tokenInfo": {
            "encryptedData": "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiN1pFSVZDMTZER1JEUUtXWkVFM1gxMUxlSk1EaHlxUXU4UTFjdG5wNGJ5bHlRSkNzdyJ9.ZW5jcnlwdGVkQ0VL.aXZEYXRhMTIz.dG9rZW5QYW5DaXBoZXJ0ZXh0.dGFnVmFsdWUxMjM0NTY"
        }
    }

    Responses

    • 200OKoptional
      • encryptedDatastringrequired

        Encrypted payload (JWE) containing FPAN and expiry (MMYYYY).

        example: eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiN1pFSVZDMTZER1JEUUtXWkVFM1gxMUxlSk1EaHlxUXU4UTFjdG5wNGJ5bHlRSkNzdyJ9.ZW5jcnlwdGVkQ0VL.aXZEYXRhMTIz.ZnBhbkNpcGhlcnRleHQ.dGFnVmFsdWUxMjM0NTY
    • 400Bad Requestoptional
      • errorCodestringrequiredexample: MTS-1616
    • 401Unauthorizedoptional
    • 403Forbiddenoptional
    • 404Not Foundoptional
    {
        "encryptedData": "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiN1pFSVZDMTZER1JEUUtXWkVFM1gxMUxlSk1EaHlxUXU4UTFjdG5wNGJ5bHlRSkNzdyJ9.ZW5jcnlwdGVkQ0VL.aXZEYXRhMTIz.ZnBhbkNpcGhlcnRleHQ.dGFnVmFsdWUxMjM0NTY"
    }