Getting Started

Getting Started


Below section introduce how to connect with HSBC Omni Collect environment. This section includes:

How to Connect

API Connectivity refers to all measures and their components that establish a connection between HSBC, the API Provider, and Merchant, the API Consumer.

  Definition Components
API Authentication HTTP BASIC Authentication • Omni Authorization Key
User Identification A Merchant Profile • Merchant ID
• Merchant Profile
Connection Security HTTPS Connection (TLS 1.2) and Network Whitelisting • SSL Certificate
• Network Whitelist
Message Security Digital Signing and Data Encryption • A pair of Private Key & Public Key Certificate (PKI Model)
• JWS Key ID
• JWE Key ID

API Gateway URL

API Gateway URL must be included before each API endpoint to make API calls.

Production
https://ws-api-platform.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1
Sandbox
https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1

API Authentication

Username & Password
Purpose All APIs are authorized using Basic Authorization
Components Username + Password
Where to get it? Delivered by HSBC via secure email during the onboarding procedure
Implementation In HTTP header: Authorization: Basic [Base64-encoded Credential]

User Identification

Merchant Profile & Merchant ID
Purpose Merchant Profile contains all necessary information from a Merchant in order to enable payment service. Merchant ID is used for Merchant identification in each API call.
Components Merchant Profile Merchant ID
Where to get it? Set up by HSBC team after collect information from Merchant Delivered by HSBC via secure email during onboarding procedure

Connection Security

SSL Certificate & Network Whitelist
Purpose Request HSBC API over HTTPS connection (TLS 1.2) Accept Callback API request over HTTPS connection (TLS 1.2)
Components Public SSL Certificate issued by HSBC Merchant's web server or domain whose HTTPS connection is enabled Network Whitelist on HSBC system
Where to get it? Downloaded automatically by Browsers or API Tools, if any problem found, please contact HSBC nil nil
Implementation nil nil Merchant's domain URL will be configured in HSBC's network whitelist by HSBC team

Message Security - Data Encryption and Signing

In addition to the Transport Layer Security, HSBC adopts additional security - Data Encryption on the message being passed across the session. This serves as a type of locked briefcase containing the data (the API message) within the HTTPS "tunnel". In other words, the communication has double protection.

 

DID YOU KNOW?
Javascript Object Signing and Encryption (JOSE™), is a framework that secures information transferred between parties. To achieve this, the JOSE framework provides a collection of specifications, including JSON Web Signature (JWS™) and JSON Web Encryption (JWE™).

 

HSBC uses JWS to sign message payloads, and JWE to encrypt the signed message. These are created by using the Private Key & Public Key Certificate (PKI Model).

 

Private Key & Public Key Certificate (PKI Model)
Purpose • Digitally sign a API request message
• Decrypt a API response message
• Encrypt the signed API request message
• Verify a signed API response message
Components Private Key issued by Merchant Public Key Certificate issued by HSBC
Where to get it? Created by any Public Key Infrastructure (PKI) toolkits, such as Keytool™ and OpenSSL™.  Exchanged with HSBC with the Public Key Certificate issued by the Merchant
Implementation Please see the technical detail attached

 

NOTE:
Technically, an X.509 certificate can serve as a SSL Certificate as well as a Public Key Certificate for Data Encryption. However, for segregation of certificate usage, HSBC recommends that the Merchant uses a different X.509 Certificate for Data Encryption. Moreover, the Public Key Certificate does not have to be CA-signed. However, if the Merchant decides to enhance security, a CA-Signed Certificate is acceptable.

 

 


keyID of JWS™ & JWE™
Purpose The unique identifier to bind Merchant's Private Key in order to create a JWS object - a signed Message Payload The unique identifier to bind HSBC's Public Key Certificate in order to create a JWE object - an encrypted JWS object
Components keyID of JWS™ keyID of JWE™
Where to get it? Mutual agreed between Merchant and HSBC Mutual agreed between Merchant and HSBC
Implementation • In HTTP header:
x-hsbc-msg-encrypt-id: [Merchant ID]+[JWS ID]+[JWE ID]

 

NOTE:
For security purposes, HSBC's Public Key Certificate and its associated keyID is renewed every year and a Certificate Renewal process is triggered. More detail is covered in the section Key Renewal.

 


How to Sign and Encrypt an Outgoing Message

Every message sent to HSBC must be signed and encrypted. From the Merchant's perspective, an Outgoing Message means:

  • the Request Message of a Service API, or
  • the Respond Message of a Callback API.

To help you understand how to construct a Signed and Encrypted Message, let's take demo code below as an example.

NOTE:
These codes are for demonstration only - it's not plug and play. There are some dependencies in the demonstration code. You can refer to Demo code description to know about it
Code example - JAVA
    
    import com.nimbusds.jose.*;
    import com.nimbusds.jose.crypto.RSADecrypter;
    import com.nimbusds.jose.crypto.RSAEncrypter;
    import com.nimbusds.jose.crypto.RSASSASigner;
    import com.nimbusds.jose.crypto.RSASSAVerifier;
    
    import java.security.PrivateKey;
    import java.security.interfaces.RSAPublicKey;
    
    public static String signAndEncryptRequestPayload(String requestPayloadStr) throws Exception {
        /** Get Keys */
        // Get merchant private Key
        PrivateKey merchantPrivateKey = KeyProvider.getMerchantPrivateKey();
        // Get HSBC public Key
        RSAPublicKey HSBCPubicKey = KeyProvider.getHSBCPublicCert();
    
        /** Sign the request payload by merchant's private key (JWS) */
        // Build JWS payload
        Payload jwspayload = new Payload(requestPayloadStr);
        // Add JWS headers
        JWSHeader jwsheader = new JWSHeader.Builder(
            JWSAlgorithm.RS256
        ).keyID(
            //Put your own Key ID value, "0001" is just an example
            "0001"
        ).build();
        // Build JWS Object
        JWSObject jwsObject = new JWSObject(jwsheader, jwspayload);
        // Sign the JWS using merchant's private key
        JWSSigner signer = new RSASSASigner(merchantPrivateKey);
        jwsObject.sign(signer);
    
        /** Encrypt the request payload by hsbc public key (JWE) */
        // Build JWE payload
        Payload jwepayload = new Payload(jwsObject.serialize());
        // Add JWE headers
        JWEHeader jweheader = new JWEHeader.Builder(
                JWEAlgorithm.RSA_OAEP_256,
                EncryptionMethod.A128GCM
        ).keyID(
            //Put the HSBC Key ID value, "0006" is just an example
            "0006"
        ).build();
        // Build JWE Object
        JWEObject jweObject = new JWEObject(jweheader, jwepayload);
        // Encrypt the JWE using HSBC public Key
        JWEEncrypter encrypter = new RSAEncrypter(HSBCPubicKey);
        jweObject.encrypt(encrypter);
        String requestPayload = jweObject.serialize();
    
        /** Complete and return the request payload */
        return requestPayload;
    }
    
    
Code example - PHP
    
    use Jose\Component\Core\AlgorithmManager;
    use Jose\Component\Encryption\Algorithm\ContentEncryption\A128GCM;
    use Jose\Component\Encryption\Algorithm\KeyEncryption\RSAOAEP256;
    use Jose\Component\Encryption\Compression\CompressionMethodManager;
    use Jose\Component\Encryption\Compression\Deflate;
    use Jose\Component\Encryption\JWEBuilder;
    use Jose\Component\Encryption\JWEDecrypter;
    use Jose\Component\Encryption\Serializer\CompactSerializer as JweCompactSerializer;
    use Jose\Component\Encryption\Serializer\JWESerializerManager;
    use Jose\Component\Signature\Algorithm\RS256;
    use Jose\Component\Signature\JWSBuilder;
    use Jose\Component\Signature\JWSVerifier;
    use Jose\Component\Signature\Serializer\CompactSerializer as JwsCompactSerializer;
    
    public static function signAndEncruptRequestPayload(
        string $payload
    ): string {
        /** Get Keys */
        // Get merchant private Key
        $merchantPrivateKey = KeyProvider::getMerchantPrivateKey();
        // Get HSBC public Key
        $hsbcPublicCert = KeyProvider::getHSBCPublicCert();
    
        /** Sign the request payload by merchant's private key (JWS) */
        $jwsAlgorithmManager = new AlgorithmManager([new RS256()]);
        $jwsBuilder = new JWSBuilder($jwsAlgorithmManager);
        $jws = $jwsBuilder
            ->create()
            ->withPayload($payload)
            ->addSignature($merchantPrivateKey, [
                'alg' => 'RS256',
                'kid' => '0001', //Put your own Key ID value, "0001" is just an example
            ])
            ->build();
        $jwsSerializer = new JwsCompactSerializer();
        $jwsString = $jwsSerializer->serialize($jws, 0);
        //  -----   Build JWS Object    -----    END    -----
    
        /** Encrypt the request payload by hsbc public key (JWE) */
        $jweKeyEncryptionAlgorithmManager = new AlgorithmManager([
            new RSAOAEP256(),
        ]);
        $jweContentEncryptionAlgorithmManager = new AlgorithmManager([
            new A128GCM(),
        ]);
        $compressionMethodManager = new CompressionMethodManager([
            new Deflate(),
        ]);
        $jweBuilder = new JWEBuilder(
            $jweKeyEncryptionAlgorithmManager,
            $jweContentEncryptionAlgorithmManager,
            $compressionMethodManager
        );
        $jwe = $jweBuilder
            ->create()
            ->withPayload($jwsString)
            ->withSharedProtectedHeader([
                'alg' => 'RSA-OAEP-256',
                'enc' => 'A128GCM',
                'kid' => '0006', //Put the HSBC Key ID value, "0006" is just an example
            ])
            ->addRecipient($hsbcPublicCert)
            ->build();
        $jweSerializer = new JweCompactSerializer();
        $jweString = $jweSerializer->serialize($jwe, 0);
    
        /** Complete and return the request payload */
        return $jweString;
    }
    
    
Code example - NodeJS
    
    const jose = require('jose');
    
    exports.signAndEncryptRequestPayload = async (requestPayloadStr) => {
        requestPayloadStr = JSON.stringify(requestPayloadStr);
    
        /** Get Keys */
        // Get merchant private Key
        const merchantPrivateKey = await KeyProvider.getMerchantPrivateKey();
        // Get HSBC public Key
        const hsbcPublicKey = await KeyProvider.getHSBCPublicCert();
    
        /** Sign the request payload by merchant's private key (JWS) */
        const signedMessage = await new jose.CompactSign(new TextEncoder().encode(requestPayloadStr))
            .setProtectedHeader({
                kid: '0001', //Put your own Key ID value, "0001" is just an example
                alg: 'RS256'
            })
            .sign(merchantPrivateKey);
    
        /** Encrypt the request payload by hsbc public key (JWE) */
        const encryptMessage = await new jose.CompactEncrypt(new TextEncoder().encode(signedMessage))
            .setProtectedHeader({
                kid: '0006', //Put the HSBC Key ID value, "0006" is just an example
                enc: 'A128GCM',
                alg: 'RSA-OAEP-256'
            })
            .encrypt(hsbcPublicKey);
    
        return encryptMessage;
    };
    
    
Code example - C#
    
    using Jose;
    using System.Security.Cryptography;
    
    public static string SignAndEncryptRequestPayload(string requestPayloadStr)
    {
        /** Get Keys */
        // Get merchant private Key
        RSA merchantPrivateKey = KeyProvider.GetMerchantPrivateKey();
        // Get HSBC public Key
        RSA hsbcPublicCert = KeyProvider.GetHsbcPublicCert();
    
        /** Sign the request payload by merchant's private key (JWS) */
        Dictionary jwsHeadrs = new Dictionary()
            {
                { 
                    "kid",
                    "0001" //Put your own Key ID value, "0001" is just an example
                },
            };
        string jwsString = Jose.JWT.Encode(
            requestPayloadStr, 
            merchantPrivateKey, 
            Jose.JwsAlgorithm.RS256, 
            extraHeaders: jwsHeadrs
        );
    
        /** Encrypt the request payload by hsbc public key (JWE) */
        Dictionary jweHeaders = new Dictionary()
            {
                { 
                    "kid", 
                    "0006"  //Put the HSBC Key ID value, "0006" is just an example
                }
            };
        string jweString = Jose.JWT.Encode(
            jwsString, 
            hsbcPublicCert, 
            JweAlgorithm.RSA_OAEP_256, 
            JweEncryption.A128GCM, 
            extraHeaders: jweHeaders
        );
        return jweString;
    }
    ,>,>,>,>
    
  1. Prepare your JWS Payload, that is, the API request payload.
  2. Create the JWS Header. The algorithm used to sign the message body is RS256. JWS keyID is the version of merchant private key. It is usually 0001 when you first integrate. It will only change when key renewal.
  3. Sign the payload message by Merchant's private key and build the JWS serialization string.
  4. Create the JWE Header. The algorithm used to encrypt the message body is A128GCM while the algorithm used to encrypt the encryption key is RSA_OAEP_256. JWE keyID is 0006. It will change with the renewal of HSBC certificate.
  5. Encrypt the JWS serialization string by HSBC's public certificate and build the JWE serialization string.

You are now ready to call the API with the Signed and Encrypted Message.


How to Decrypt a Message and Verify Signature of an Incoming Message

Every message sent from HSBC must be decrypted and verified. From the Merchant's perspective, an Incoming Message means:

  • the Respond Message of a Service API, or
  • the Request Message of a Callback API.

Let's look into the following example to see how to decrypt a response message from HSBC:

Code example - JAVA
    
    import com.nimbusds.jose.*;
    import com.nimbusds.jose.crypto.RSADecrypter;
    import com.nimbusds.jose.crypto.RSAEncrypter;
    import com.nimbusds.jose.crypto.RSASSASigner;
    import com.nimbusds.jose.crypto.RSASSAVerifier;
    
    import java.security.PrivateKey;
    import java.security.interfaces.RSAPublicKey;
    
    public static String decryptAndVerifyResponsePayload(String responsePayloadStr) throws Exception {
        /** Get Keys */
        // Get merchant private Key
        PrivateKey merchantPrivateKey = KeyProvider.getMerchantPrivateKey();
        // Get HSBC public Key
        RSAPublicKey HSBCPubicKey = KeyProvider.getHSBCPublicCert();
    
        /** Decrypt response payload by merchant's private key (JWE) */
        // Parse JWE Object
        JWEObject jweObject = JWEObject.parse(responsePayloadStr);
        // Decrypt JWE object using merchant's private key
        JWEDecrypter decrypter = new RSADecrypter(merchantPrivateKey);
        jweObject.decrypt(decrypter);
        // Get the JWE payload from JWE object
        String jwepayload = jweObject.getPayload().toString();
    
        /** Verify the signature of response payload by hsbc public key (JWS) */
        // Parse JWS Object from JWE payload
        JWSObject jwsObject = JWSObject.parse(jwepayload);
        // Verify HSBC signature using HSBC public Key
        boolean isSignatureValid = jwsObject.verify(new RSASSAVerifier(HSBCPubicKey));
        if (!isSignatureValid) {
            // you can do some logic here if the result is negative
            // throw new Exception("Invalid signature of response message");
        }
        // Get the response payload from JWS object
        String responsePayload = jwsObject.getPayload().toString();
    
        /** Complete and return the request payload */
        return responsePayload;
    }
    
    
Code example - PHP
    
    use Jose\Component\Core\AlgorithmManager;
    use Jose\Component\Encryption\Algorithm\ContentEncryption\A128GCM;
    use Jose\Component\Encryption\Algorithm\KeyEncryption\RSAOAEP256;
    use Jose\Component\Encryption\Compression\CompressionMethodManager;
    use Jose\Component\Encryption\Compression\Deflate;
    use Jose\Component\Encryption\JWEBuilder;
    use Jose\Component\Encryption\JWEDecrypter;
    use Jose\Component\Encryption\Serializer\CompactSerializer as JweCompactSerializer;
    use Jose\Component\Encryption\Serializer\JWESerializerManager;
    use Jose\Component\Signature\Algorithm\RS256;
    use Jose\Component\Signature\JWSBuilder;
    use Jose\Component\Signature\JWSVerifier;
    use Jose\Component\Signature\Serializer\CompactSerializer as JwsCompactSerializer;
    
    public static function decryptAndVerifyResponsePayload(
        string $payload
    ): string {
        /** Get Keys */
        // Get merchant private Key
        $merchantPrivateKey = KeyProvider::getMerchantPrivateKey();
        // Get HSBC public Key
        $hsbcPublicCert = KeyProvider::getHSBCPublicCert();
    
        /** Decrypt response payload by merchant's private key (JWE) */
        $jweKeyEncryptionAlgorithmManager = new AlgorithmManager([
            new RSAOAEP256(),
        ]);
        $jweContentEncryptionAlgorithmManager = new AlgorithmManager([
            new A128GCM(),
        ]);
        $compressionMethodManager = new CompressionMethodManager([
            new Deflate(),
        ]);
        $jweDecrypter = new JWEDecrypter(
            $jweKeyEncryptionAlgorithmManager,
            $jweContentEncryptionAlgorithmManager,
            $compressionMethodManager
        );
        $jweSerializerManager = new JWESerializerManager([
            new JweCompactSerializer(),
        ]);
        $jweObject = $jweSerializerManager->unserialize($payload);
        $jweDecrypter->decryptUsingKey($jweObject, $merchantPrivateKey, 0);
        $jweDecyptedPayload = $jweObject->getPayload();
    
        /** Verify the signature of response payload by hsbc public key (JWS) */
        $jwsAlgorithmManager = new AlgorithmManager([new RS256()]);
        $jwsVerifier = new JWSVerifier($jwsAlgorithmManager);
        $jwsSerializer = new JwsCompactSerializer();
        $jwsObject = $jwsSerializer->unserialize($jweDecyptedPayload);
        // the $isVeified indicates whether the signature is valid
        $isVerified = $jwsVerifier->verifyWithKey(
            $jwsObject,
            $hsbcPublicCert,
            0
        );
        $jwsPayload = $jwsObject->getPayload();
    
        /** Complete and return the request payload */
        return $jwsPayload;
    }
    
    
Code example - NodeJS
    
    const jose = require('jose');
    
    exports.decryptAndVerifyResponsePayload = async (responsePayloadStr) => {
        /** Get Keys */
        // Get merchant private Key
        const merchantPrivateKey = await KeyProvider.getMerchantPrivateKey();
        // Get HSBC public Key
        const hsbcPublicKey = await KeyProvider.getHSBCPublicCert();
    
        /** Decrypt response payload by merchant's private key (JWE) */
        const decryptedMessageObject = await jose.compactDecrypt(responsePayloadStr, merchantPrivateKey);
        const decryptedMessage = new TextDecoder().decode(decryptedMessageObject.plaintext);
    
        /** Verify the signature of response payload by hsbc public key (JWS) */
        const signedMessageObject = await jose.compactVerify(decryptedMessage, hsbcPublicKey);
        const signedMessage = new TextDecoder().decode(signedMessageObject.payload);
    
        return signedMessage;
    };
    
    
Code example - C#
    
    using Jose;
    using System.Security.Cryptography;
    
    public static string DecryptAndVerifyResponsePayload(string responsePayloadStr)
    {
        /** Get Keys */
        // Get merchant private Key
        RSA merchantPrivateKey = KeyProvider.GetMerchantPrivateKey();
        // Get HSBC public Key
        RSA hsbcPublicCert = KeyProvider.GetHsbcPublicCert();
    
        /** Decrypt response payload by merchant's private key (JWE) */
        string decryptedJwePayloadString = JWT.Decode(responsePayloadStr, merchantPrivateKey);
    
        /** Verify the signature of response payload by hsbc public key (JWS) */
        string responsePayload = JWT.Decode(decryptedJwePayloadString, hsbcPublicCert);
    
        return responsePayload;
    }
    
    
  1. Parse the HSBC Signed and Encrypted Message to Encrypted JWE Object.
  2. Decrypt the Encrypted JWE Object by Merchant's private key and get the JWE payload from Encrypted JWE Object.
  3. Parse the JWE payload to Signed JWS Object.
  4. Verify the signature of the Signed JWS Object byHSBC's public certificate
  5. Get the Signed Message from the decrypted JWE Object.

You are now able to extract the plain JSON message, you can parse it to an object depends on your program language.


Demo code description

Some dependencies are used in the demo code above to build JWS and JWE. The dependencies are as follows:

NOTE:
Please note the url above does not belong to HSBC, use it on your own discretion. By clicking the url or website, it means you accept these terms and conditions.

Meanwhile, a KeyProvider class is used in the demo code above to provide merchant private key and HSBC public key. The codes for KeyProvider are as below:

JAVA - KeyProvider.java
    
    import org.apache.commons.codec.binary.Base64;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    
    public class KeyProvider {
        public static PrivateKey getMerchantPrivateKey() throws Exception {
            PrivateKey privateKey = null;
            try (
                    InputStream inputStream = 
                        "${Merchant private key file path}";
            ) {
                byte[] keyStrBytes = new byte[inputStream.available()];
                inputStream.read(keyStrBytes);
                String privateKeyPEM = new String(keyStrBytes)
                        .replace("-----BEGIN PRIVATE KEY-----", "")
                        .replaceAll(System.lineSeparator(), "")
                        .replace("-----END PRIVATE KEY-----", "");
                byte[] encoded = Base64.decodeBase64(privateKeyPEM);
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
                privateKey = keyFactory.generatePrivate(keySpec);
            } catch (IOException ioException) {
                throw ioException;
            }
            return privateKey;
        }
    
        public static RSAPublicKey getHSBCPublicCert() throws Exception {
            RSAPublicKey rsaPublicKey = null;
            try (
                    InputStream inputStream = 
                        "${HSBC public certificate file path}";
            ) {
                CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
                X509Certificate x509Certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);
                rsaPublicKey = (RSAPublicKey) x509Certificate.getPublicKey();
            } catch (Exception e) {
                throw e;
            }
            return rsaPublicKey;
        }
    }
    
    
PHP - KeyProvider.php
    
    use Jose\Component\Core\JWK;
    use Jose\Component\KeyManagement\JWKFactory;
    
    class KeyProvider
    {
        public static function getMerchantPrivateKey(): JWK
        {
            return JWKFactory::createFromKeyFile(
                "${Merchant private key file path}"
            );
        }
    
        public static function getHSBCPublicCert(): JWK
        {
            return JWKFactory::createFromCertificateFile(
                "${HSBC public certificate file path}"
            );
        }
    }
    
    
NodeJS - KeyProvider.js
    
    const fs = require('fs');
    const path = require('path');
    const jose = require('jose');
    
    const HsbcOmniCollectApiConstant = require('./HsbcOmniCollectApiConstant');
    
    exports.getMerchantPrivateKey = async () => {
        const privateKeyStr = fs.readFileSync(
            '${Merchant private key file path}'
        ).toString();
        const merchantPrivateKey = jose.importPKCS8(privateKeyStr);
        return merchantPrivateKey;
    };
    
    exports.getHSBCPublicCert = async () => {
        const publicKeyStr = fs.readFileSync(
            '${HSBC public certificate file path}'
        ).toString();
        const hsbcPublicKey = jose.importX509(publicKeyStr);
        return hsbcPublicKey;
    };
    
    
C# - KeyProvider.cs
    
    using System.Security.Cryptography;
    
    {
        class KeyProvider
        {
    
            public static RSA GetMerchantPrivateKey()
            {
                string keyStr = File.ReadAllText("${Merchant private key file path}");
                RSA merchantPrivateKey = RSA.Create();
                merchantPrivateKey.ImportFromPem(keyStr);
                return merchantPrivateKey;
            }
    
            public static RSA GetHsbcPublicCert()
            {
                RSA hsbcPuvlicCert = new X509Certificate2("${HSBC public certificate file path}")
                    .GetRSAPublicKey();
                return hsbcPuvlicCert;
            }
        }
    
    }
    
    

Sample projects

Here are some sample projects for your reference on how to integrate encryption/decryption and signing/signature verification.


Summary

Components \ Steps Message Signing Message Encryption Message Decryption >Verify Signature
JWS Object Signing Algorithm:
RS256
     
JWE Object   JWE Algorithm:
RSA_OAEP_256

Encryption Method:
A128GCM
   
KeyID 0001 0006    
Merchant's Private Key Used as Signer   Used as Decrypter  
HSBC's Public Key   Used as Encrypter   Used as Verifier

 

Return to top

 

How to Make an API Request

 

How to Make an API Request


An API request can be submitted without Message Encryption, in case you want to:

  • learn about the basic API Call;
  • test API connectivity before spending substantial development effort on Message Encryption.

Data encryption is a required data security imposed by HSBC standards. The Merchant has to invoke the encryption logic before moving to Production and must be fully tested during the testing phase.

 


Make Your API Request with Plain Messages

NOTE:

In the Sandbox Environment you can skip message encryption. However, this is for testing purpose only.

Submit an example API request using cURL™
cURL™ is a simple command-line tool that enables you to make any HTTP request. Merchant can choose any other GUI tool such as Postman™ and SoapUI™.

Step 1. Run this command on your platform:


POST
curl -X POST "https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mcau-ea-merchantservices-proxy/v1/{resource_endpoint}" \
-H "message_encrypt: false" \
-H "Authorization:Basic OGI5MTVhNGY1YjUwNDdmMDkxZjIxMGUyMjMyYjVjZWQ6SHNiY0A0MzIx" \
-H "x-HSBC-msg-encrypt-id: 42298549900001+0001+0002" \
-H "Content-Type: application/json" \
-d "{ \"txnRef\": \"20220927181945131\", \"merId\": \"42298549900001\"}"

GET
curl -X GET "https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mcau-ea-merchantservices-proxy/v1/{resource_endpoint}" \
-H "message_encrypt: false" \
-H "Authorization:Basic OGI5MTVhNGY1YjUwNDdmMDkxZjIxMGUyMjMyYjVjZWQ6SHNiY0A0MzIx" \
-H "x-HSBC-msg-encrypt-id: 42298549900001+0001+0002" \
-H "Content-Type: application/json" 
  1. Submit the GET request to the API URL endpoint.
  2. Set the secret header message_encrypt: false to indicate this API request is without message encryption. This header is only applicable in Sandbox environment.
  3. Put the Basic Authorization in HTTP header Authorization.
  4. Put the Profile ID in HTTP header x-HSBC-profileid.
  5. Put the Merchant ID, the JWS ID and the JWE ID in HTTP header x-HSBC-msg-encrypt-id respectively.
  6. Set Content-Type to JSON format.

Step 2. Receive the response message in plain json format.

 


Making API Request with Message Encryption

Step 1. Run this cURL™ command on your platform:


POST
curl -X POST "https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mcau-ea-merchantservices-proxy/v1/{resource_endpoint}" \
-H "Authorization:Basic OGI5MTVhNGY1YjUwNDdmMDkxZjIxMGUyMjMyYjVjZWQ6SHNiY0A0MzIx" \
-H "x-HSBC-msg-encrypt-id: 42298549900001+0001+0002" \
-H "Content-Type: application/json" \
-d "eyJraWQiOiIwMDAxIiwiZW5jIjoiQTEyOEdDTSIsImFsZyI6IlJTQS1PQUVQLTI1NiJ9.W4nobHoVXUMOXGM5I-WGPZt8sj-hsd_sRujMHFbv80M72K4l..."

GET
curl -X GET "https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mcau-ea-merchantservices-proxy/v1/{resource_endpoint}" \
-H "Authorization:Basic OGI5MTVhNGY1YjUwNDdmMDkxZjIxMGUyMjMyYjVjZWQ6SHNiY0A0MzIx" \
-H "x-HSBC-msg-encrypt-id: 42298549900001+0001+0002" \
-H "Content-Type: application/json"  
  1. Submit the POST request to the API URL endpoint. Any {id} adhered in the URL must be encrypted.
  2. Put the Basic Authorization in HTTP header Authorization.
  3. Put the Profile ID in HTTP header x-HSBC-profileid.
  4. Put the Merchant ID, the JWS ID and the JWE ID in HTTP header x-HSBC-msg-encrypt-id respectively.
  5. Set the Content-Type to JSON format.
  6. The Encrypted Message Payload.
NOTE:

Data Encryption invokes compulsory prerequisites, such as JOSE library and program coding, please make sure the section on Message Security has been gone through thoroughly.

Step 2. For a successful request (HTTP Status Code 200), an encrypted response message is returned, otherwise, a plain json with failure message is returned.


FAQ

SSL Connection Questions

Where can I find the HSBC SSL server certificates?

The Merchant developer can export SSL server certificates installed in your browser. To achieve this, visit the domain of the corresponding API endpoint in your browser. For example, to get the SSL certificate of sandbox environment, use the domain name https://ws-api-platform-pprd.business.hsbc.co.hk/

However, in production, we provide a certificate and require TLS 1.2 implementation.

Message Encryption Questions

What certificates do I need to work with Message Encryption in HSBC's sandbox and production environments?

A self-sign certificate is acceptable. However, if the Merchant decides to enhance security, a CA-Signed Certificate is also acceptable.

Javascript Object Signing and Encryption (JOSE) Framework Questions

Where can I get more information about JOSE Framework?

If you want to fully understand the framework, you can read here for more details.

Please note these urls or websites do not belong to HSBC, use them at your own discretion. By clicking these urls or websites signifies you accept these terms and conditions.

Where can I download JOSE libraries for development?

For your reference, you may find the following JOSE libraries of different programming languages.

Please note these urls or websites do not belong to HSBC, use them at your own discretion. By clicking these urls or websites signifies you accept these terms and conditions.

 

Return to top

 

Response Code Explanation

Response Code Explanation


In Omni Collect solution, Omni Collect cooperates with local payment service provider to team up together to provide comprehensive payment capabilities to Merchant. Omni Collect stands between Merchant and payment service provider, any API request will go through Omni Collect first then reach out to payment service provider. Hence there are two types of response code:

  1. Omni Collect response code
  2. Payment service provider response code

The purpose of Omni Collect response code is to help Merchant to find out root cause of error and contact the correct stakeholders to resolve. Some error may due to the violation of Omni Collect logic, some error may due to the violation of payment service provider logic. If this error is returned by payment service provider, Merchant need to contact them using the contact detail in tri-party agreement.


Omni Collect Response Code

  • api_gateway_error means the API request is rejected by Omni Collect
  • payment_gateway_error means the API request has successfully passed in Omni Collect, but is rejected by payment service provider.

 

HTTP Response Code Behavior of Omni Collect Behavior of Payment Service Provider HSBC System Code HSBC System Message
200
OK - Everything worked as expected.
Working as expected. Working as expected. n/a n/a
400
Bad Request - The request was unacceptable.
Working as expected, but some logic is violated in Omni Collect.

API request does not reach to payment service provider.

encryption_error The encryption key or the encrypted message is invalid.
Working as expected, but some logic is violated in Omni Collect. API request does not reach to payment service provider. signature_error The signing key or the digital signature is invalid.
Working as expected, but some logic is violated in Omni Collect. API request does not reach to payment service provider. signature_expired The digital signature has expired.
Working as expected, but some logic is violated in Omni Collect. API request does not reach to payment service provider. location_invalid The location defined in the HTTP header is invalid or not supported.
Working as expected, but some logic is violated in Omni Collect. API request does not reach to payment service provider. merchant_profile_invalid The merchant ID is invalid.
Working as expected, but some logic is violated in Omni Collect. API request does not reach to payment service provider. schema_error *Display auto-generated message from JSON schema
Working as expected, but some logic is violated in Omni Collect. API request does not reach to payment service provider. resource_unavailable This resource is unavailable for the chosen payment model.
Working as expected, but some logic is violated in Omni Collect. API request does not reach to payment service provider. unexpected_error The request contains unexpected error, please contact HSBC support team for further investigation.
401
Unauthorized - Client ID / Sercet is missing or invalid.

Working as expected, but some logic is violated in Omni Collect.

API request does not reach to payment service provider. n/a n/a
402
Request Failed - The parameters were valid but the request failed.

*(Error occurs at Omni Collect)

Working as expected, but some logic is violated in Omni Collect.

API request does not reach to payment service provider. *Details are defined in each field mapping pages *Details are defined in each field mapping pages
402
Request Failed - The parameters were valid but the request failed.

*(Error occurs at PSP)

Working as expected.

Working as expected, but some logic is violated in payment service provider. *Defined in PSP's documentation *Defined in PSP's documentation
404
Not Found - The requested resource does not exist

Working as expected, but some logic is violated in Omni Collect.

 

Scenario #1:
• The payment model does not support payment cancellation, but the user submits POST /payment/{id}/cancel

Scenario #2:
• The user input a wrong resource endpoint, such as POST /payment/refund

API request does not reach to payment service provider. n/a n/a
500
HSBC System Error
Omni Collect system down. API request does not reach to payment service provider. n/a n/a
599
Payment Gateway System Error

Working as expected.

Payment service provider system down. payment_gateway_system_error A system error is encountered in Payment Gateway, please contact Payment Gateway support team for further investigation.

Payment Service Provider Response Code

The response code of payment service provider is provided by each of payment service provider. Hence HSBC provides below table list for users to check the API specification of payment service provider. Some payment service providers do not provide online API specification. Please refer to payment service provider when signing tri-party agreement. 

Country Payment Service Provider Response Code Explanation
Australia Fiserv Authorisation Response Codes (fiserv.dev)
Australia Azupay Please refer to the response message as Azupay does not provide response code.
Bangladesh SSLCOMMERZ Integrate API | Developers | SSLCOMMERZ
India PayU https://devguide.payu.in/api/miscellaneous/error-codes/
India RazorPay https://razorpay.com/docs/api/x/error-codes?search-string=error
Indonesia Jokul https://jokul.doku.com/docs/docs/jokul-direct/credit-card/section/list-of-error-code-h2h
Japan Sony Payment  
Korea KPN Authorisation Response Codes (fiserv.dev)
Malaysia eGHL  
Philippines Razer https://github.com/RazerMS/Documentation-RazerMS_API_Spec/blob/main/%5Bofficial%20API%5D%20Razer%20API%20Spec%20for%20Merchant%20(v13.49).pdf
Singapore Fiserv Authorisation Response Codes (fiserv.dev)
Thailand 2C2P https://developer.2c2p.com/docs/reference-response-code-guide
United Kingdom GlobalPay

Hosted Payment Page

https://developer.globalpay.com/responses

Open Banking

https://developer.globalpay.com/ecommerce/open-banking-guide#api

Vietnam Payoo  
Vietnam Viettel  

 

Return to top

We invite you to explore each category to gain a thorough understanding of our API connectivity. As always, our HSBC team is ready to support you should you have any questions or require further assistance. 

 

Return to top