ShieldConex WebSockets API

Overview

WebSockets API offers real-time market data updates. WebSockets is a bidirectional protocol offering fastest real-time data, helping you build real-time applications. The public message types presented below do not require authentication. Private-data messages can be subscribed on a separate authenticated endpoint.

📘

Key Points

  • All messages sent and received via WebSockets are encoded in JSON format.
  • Our Websockets endpoint is designed for server to server communications. It should never be used on a frontend client. For convenience, we have included Python backend code examples to get you started on your WebSocket connection.
  • We recommend that you send a heartbeat message at least once every 5 seconds in order to keep the connection alive and ensure that the service is responding.

Connection Details

In order to utilize ShieldConex's WebSocket interface, you have to connect to one of the following environment URLs.

You are required to send a Basic Authentication header in the initial connection to our websocket endpoint.

Environment NameWebSocket Connection URL
Staging Environmentwss://secure-staging-ws.shieldconex.com
Certification/Testing Environmentwss://secure-cert-ws.shieldconex.com
Production Environmentwss://secure-ws.shieldconex.com

Request Message Structure

Request JSON messages have the following properties:

PropertyRequiredTypeLengthDescription
traceIdYesString0-255traceId is a unique id that is sent in the response message. The merchant can use this value to match outgoing messages with incoming messages.
We recommend that the merchant use a GUID to avoid collisions.
actionYesEnumeration-This property represents the action that the merchant wants to perform.
Enumerations include:
heartbeat
partner-validate
template-validate
tokenization-tokenize
tokenization-read
tokenization-detokenize
payloadYesJSON-The message payload contains the body of the message for the specific action.
Refer to the examples below for request and response samples.

Response Message Structure

Response JSON messages have the following properties:

PropertyDescription
traceIdThe unique traceId that was sent in the request message.
actionIndicates the action that was performed.
messageIdA unique value generated by the system for the transaction. This value can be used on the portal to track an individual message/transaction.
successIndicates if the system was able to process the message.
payloadAn object with the result of the action performed. For failure it will contain an errorCode and message property that maps to the same action on the REST endpoints.

Sample Messages

{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "tokenization-tokenize",
    "payload": {
        "templateRef": "8e1580b8-12ea-4804-acaa-f9c922d124e6",
        "omit": false,
        "reference": "09420c55af7b",
        "values": [{
            "name": "scx_token_card_number",
            "value": "4444333322221111"
        }]
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "tokenization-tokenize",
    "messageId": "1201911201201321031626749",
    "success": true,
    "payload": {
        "bfid": "djE6MTIwMTkxMTIwMTIwMTMyMTAzMTYyNjc0OXwxYjIxNGU1MjQ4NDgxYjFlOTRmNjRhZTg5YWU0Njg3ZXx8",
        "values": [{
            "name": "scx_token_card_number",
            "value": "4444336487341111"
        }]
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "tokenization-tokenize",
    "messageId": "1201911201201321031626749",
    "success" : false,
    "payload": {
        "errorCode": 1202,
        "message": "Template not found"
    }
}

Sample Code

With your respective ShieldConex environment and template configuration, you can use the following Python WebSocket code in order to test all of the requests and responses included in this guide.

📘

Note

Also see Heartbeat Implementation Example.

import asyncio
import websockets

import json
import uuid
import secrets

ENV_URL = "wss://secure-cert-ws.shieldconex.com"
BASE_64_KEY = "YOUR_BASE64_ENCODED_KEY"

def generate_hex_reference(length: int = 12) -> str:
    if length <= 0:
        raise ValueError("length must be positive")
    return secrets.token_hex((length + 1) // 2)[:length]

async def scx_action():
    headers = {"Authorization": f"Basic {BASE_64_KEY}"}

    trace_id_guid = str(uuid.uuid4())

    req = {
            "traceId": trace_id_guid,
            "action": "tokenization-tokenize",
            "payload": {
                "templateRef": "438ac8afecdd8035a21c126ee1fe6c19",
                "omit": False,
                "store": True,
                # User-generated reference for tracking purposes
                "reference": generate_hex_reference(),
                "values": [
                    {"name":"card_number","value":"4444333322221112"},
                    {"name":"card_exp","value":"1225"},
                    {"name":"card_cvv","value":"1234"}

                    ]
                }
            }

    async with websockets.connect(ENV_URL, extra_headers=headers) as websocket:
        # Send a message to the server
        print('Sending:', json.dumps(req))
        await websocket.send(json.dumps(req))
        # Receive a message from the server
        response = await websocket.recv()
        print("Received from SCX WebSocket")
        print(json.dumps(json.loads(response), indent=4))


if __name__ == "__main__":
    asyncio.run(scx_action())

Actions

Our WebSocket interface supports the following actions:

Heartbeat

At any point after the initial WebSocket handshake, the merchant can choose to send a PING (heartbeat message) to the server. If the connection to the server is still active and the heartbeat message is received, the server returns a PONG.

To ensure that the merchant is still connected to the WebSocket, use the following action:

{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e48",
    "action": "heartbeat"
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e48",
    "action": "heartbeat",
    "messageId": "1202203181024092211390455",
    "success": true,
    "payload": {
        "timestamp": 1647599049551
    }
}

📘

Note

We recommend that you send a heartbeat message at least once every 5 seconds in order to keep the connection alive and ensure that the service is responding.

Heartbeat Server-Side Implementation

To demonstrate heartbeat implementation in practice, we included the following Python implementation in order to keep the connection alive and ensure that the service is responding, as pointed out above.

📘

Note

According to your server code and specification, it is recommended that you implement your own heartbeat interval so that it runs in the background of your server ahead of sending an actual ShieldConex action such as tokenization, detokenization, or token reading.

import asyncio
import websockets

import json
import uuid
import secrets

ENV_URL = "wss://secure-cert-ws.shieldconex.com"
BASE_64_KEY = "YOUR_BASE64_ENCODED_KEY"

CONNECTED_TO_WEBSOCKET = False

def generate_hex_reference(length: int = 12) -> str:
    if length <= 0:
        raise ValueError("length must be positive")
    return secrets.token_hex((length + 1) // 2)[:length]

async def heartbeat_check():
    global CONNECTED_TO_WEBSOCKET

    headers = {"Authorization": f"Basic {BASE_64_KEY}"}

    async with websockets.connect(ENV_URL, extra_headers=headers) as websocket:
        while True:
            try:
                trace_id_guid = str(uuid.uuid4())
                heartbeat_req = {
                        "traceId": trace_id_guid,
                        "action": "heartbeat"
                        }

                # Send a PING request
                await websocket.send(json.dumps(heartbeat_req))

                # Wait for the PONG response
                message = await websocket.recv()
                print(f"Received: {message}")
                CONNECTED_TO_WEBSOCKET = True
            except websockets.exceptions.ConnectionClosedOK:
                print("Connection closed normally.")
                CONNECTED_TO_WEBSOCKET = False
                break
            except websockets.exceptions.ConnectionClosedError as e:
                print(f"Connection closed with error: {e}")
                CONNECTED_TO_WEBSOCKET = False
                break
            await asyncio.sleep(5) # Send a heartbeat message at least once every 5 seconds

async def simulate_scx_action():
    global CONNECTED_TO_WEBSOCKET

    # Needed for simulating this ShieldConex action.
    # This is NOT needed, nor is it practical in the real-world application.
    await asyncio.sleep(6)

    if not CONNECTED_TO_WEBSOCKET:
        print("WebSocket connection is closed")
        return


    headers = {"Authorization": f"Basic {BASE_64_KEY}"}

    trace_id_guid = str(uuid.uuid4())

    req = {
            "traceId": trace_id_guid,
            "action": "tokenization-tokenize",
            "payload": {
                "templateRef": "438ac8afecdd8035a21c126ee1fe6c19",
                "omit": True,
                "store": True,
                # User-generated reference for tracking purposes
                "reference": generate_hex_reference(),
                "values": [
                    {"name":"card_number","value":"4444333322221112"},
                    {"name":"card_exp","value":"1225"},
                    {"name":"card_cvv","value":"1234"}

                    ]
                }
            }

    async with websockets.connect(ENV_URL, extra_headers=headers) as websocket:
        # Send a message to the server
        print('Sending:', json.dumps(req))
        await websocket.send(json.dumps(req))
        # Receive a message from the server
        response = await websocket.recv()
        print("Received from SCX WebSocket")
        print(json.dumps(json.loads(response), indent=4))

async def main():
    heartbeat = asyncio.create_task(heartbeat_check())

    await simulate_scx_action()
    await heartbeat

if __name__ == "__main__":
    asyncio.run(main())

Partner Validate

This API call can be used by the Partner to test connectivity to the ShieldConex platform.

Upon proper authentication, a "success" is returned. This can be used by the Partner as an application "ping".

The payload object contains the following field:

PropertyRequiredTypeLengthDescription
referenceNoString1-255Request Reference. This is a reference value that Developers can use to track API requests and responses. It is solely for tracking purposes.
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e48",
    "action": "partner-validate",
    "payload": {
        "reference": "myref"
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "partner-validate",
    "messageId": "1201911201201321031626749",
    "success" : true
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "partner-validate",
    "messageId": "1201911201201321031626749",
    "success" : false
}

Template Validate

This activity would be performed to validate that ShieldConex recognises a partner's template. This can be used by the Partner to ensure the template being referenced is in the ShieldConex system and provisioned correctly.

The payload object is composed of the following fields:

PropertyRequiredTypeLengthDescription
referenceNoString1-255Request Reference. This is a reference value that Developers can use to track API requests and responses. It is solely for tracking purposes.
templateRefYesString1-255The template ref is a unique ID that specifies the template to be validated
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e47",
    "action": "template-validate",
    "payload": {
        "reference": "myref",
        "templateRef": "152a4e3f7f31f0a746388adbae1b47f5"
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "template-validate",
    "messageId": "1201911201201321031626749",
    "success" : true
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "template-validate",
    "messageId": "1201911201201321031626749",
    "success" : false
}

Tokenize

This action gives the merchant the ability to tokenize data.

The payload object is composed of the following fields:

PropertyRequiredDefaultTypeLengthDescription
templateRefYes-String1-255Short for Template Reference. This is the unique alphanumeric string that is used to identify a template.
The templateRef is created within ShieldConex Manager and can be found within the template details page of any template within ShieldConex Manager.
For more on template configuration and how to set it up, refer to Shieldconex® | Templates.
omitNofalseBoolean-If set to true, the tokens are not returned in the response and must be collected via a subsequent tokenization-read request.
When set to true, the store is also practically required to be set to true.
storeNofalseBoolean-This field is typically used in combination with omit set to true as it stores the Bluefin Identifier for later reuse via subsequent tokenization-read requests.
It can also be used with omit set to false where we both get the tokens in response and can reuse the bfid for consequent tokenization reads.
If set to false, any tokenization read call with returned bfid receives an error message indicating that the bfid is not found.
Note that this property has no bearing on tokenization detokenize as long as the tokenized values are retrieved.
referenceNo-String1-255Request Reference. This is a reference value that Developers can use to track API requests and responses. It is solely for tracking purposes.
valuesYes--JSON array containing the field names (and desired values) matching the fields configured inside of the template being referenced with templateRef.
{
    "action": "tokenization-tokenize",
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e47",
    "payload": {
        "templateRef": "152a4e3f7f31f0a746388adbae1b47f5",
        "omit": false,
        "store": true,
        "reference": "myref",
        "values": [{
            "name": "scx_token_card_number",
            "value": "4444333322221111"
        }]
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "tokenization-tokenize",
    "messageId": "1201911201201321031626749",
    "success" : true,
    "payload": {
        "bfid": "djE6MTIwMTkxMTIwMTIwMTMyMTAzMTYyNjc0OXwxYjIxNGU1MjQ4NDgxYjFlOTRmNjRhZTg5YWU0Njg3ZXx8",
        "values": [{
            "name": "scx_token_card_number",
            "value": "4444336487341111"
        }]
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e49",
    "action": "tokenization-tokenize",
    "messageId": "1201911201201321031626749",
    "success" : false,
    "payload": {
        "errorCode": 1202,
        "message": "Template not found"
    }
}

Tokenization Read

This action is intended to be used to read data that was entered into a ShieldConex iFrame element (this cannot be used for API only transactions).

The BFID that is created during a tokenization request is used to recall the data that was used is that request's payload. The response values would be tokenized. This activity can only be performed once per BFID.

🚧

Note

When applying tokenization via ShieldConex WebSocket API as shown above, the store field must be set to true in order to read your Bluefin token.

Otherwise, we receive an error message indicating that the bfid is not found.

When it comes to ShieldConex REST API, compare the usage and behavior of the omit flag here.

Additionally, the token can be read/detokenized until it expires if specified in your template configuration.

The payload object is composed of the following fields:

PropertyRequiredTypeLengthDescription
bfidYesString30-150The BFID, or Bluefin ID, is the value that is created when a tokenization request is made (i.e., it is the value retrieved from an iFrame transaction, or a /tokenization/tokenize request). The BFID refers to that specific tokenization request and is necessary for tokenization and detokenization.
referenceNoString1-255Request Reference. This is a reference value that Developers can use to track API requests and responses. It is solely for tracking purposes.
{
    "action": "tokenization-read",
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e46",
    "payload": {
        "reference": "my_ref",
        "bfid": "djE6MTIwMTkxMTIwMTIwMTMyMTAzMTYyNjc0OXwxYjIxNGU1MjQ4NDgxYjFlOTRmNjRhZTg5YWU0Njg3ZXx8"
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e46",
    "action": "tokenization-read",
    "messageId": "1201911201201321031626749",
    "success" : true,  
    "payload": {
        "bfid": "djE6MTIwMTkxMTIwMTIwMTMyMTAzMTYyNjc0OXwxYjIxNGU1MjQ4NDgxYjFlOTRmNjRhZTg5YWU0Njg3ZXx8",
        "values": [{
            "name": "scx_token_card_number",
            "value": "4444336487341111"
        }]
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e46",
    "action": "tokenization-read",
    "messageId": "1201911201201321031626749",
    "success" : false,
    "payload": {
        "errorCode": 1203,
        "message": "Not found"
    }
}

Detokenize

This action provides the ability to detokenize data.

The payload object is composed of the following fields:

PropertyRequiredTypeLengthDescription
bfidYesString30-150The BFID, or Bluefin ID, is the value that is created when a tokenization request is made (i.e., it is the value retrieved from an iFrame transaction, or a /tokenization/tokenize request).
The BFID refers to that specific tokenization request and is required for tokenization read and detokenization.
referenceNoString1-255Request Reference: this is a reference value that Developers can use to track API requests and responses. It is solely for tracking purposes.
valuesYes--JSON array containing the field names (with the corresponding tokenized values) matching the fields configured inside of the template being referenced with the respective templateRef.
{
    "action": "tokenization-detokenize",
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e45",
    "payload": {
        "reference": "my_ref",
        "bfid": "djE6MTIwMTkxMTIwMTIwMTMyMTAzMTYyNjc0OXwxYjIxNGU1MjQ4NDgxYjFlOTRmNjRhZTg5YWU0Njg3ZXx8",
        "values": [
            {
                "name": "scx_token_card_number",
                "value": "4444336487341111"
            }
        ]
    }
}
{
    "traceId": "b12be111-51a3-4b2e-b0bd-f79cb30f6e45",
    "action": "tokenization-detokenize",
    "messageId": "1201911201201321031626749",
    "succes" : true,
    "payload": {
        "values": [{
            "name": "scx_token_card_number",
            "value": "4444333322221111"
        }]
    }
}