Getting Started
GETTING STARTED
This section provides all the technical information you need to start accessing and using the Omni Collect – Single API. It includes detailed instructions on how to authenticate API requests, protect API data, work with base URLs across different environments, handle errors, and understand API versioning. The following sub-sections will guide you through each of these essential topics:
- API Base URL: Find the base URLs for accessing different environments of our API.
- API Authentication: Learn how to authenticate your requests to ensure secure access to our API.
- Securing API Communication: Understand how to protect your data with encryption and digital signatures.
- Making an API Call: After setting up all the prerequisites mentioned in the previous sections, it's time to guide you through executing an API call with actual examples.
API BASE URL
The API Base URL is the root endpoint where all API requests are directed. Depending on the environment you're working in, you'll use either the Live or Sandbox URL.
Live Environment
For live transactions and real customer data, use the following Live URL:
https://ws-api-platform.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1
Sandbox Environment
For testing and development purposes, use the Sandbox environment. This environment simulates real-world transactions without affecting actual customer data.
https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1
Using this Base URL
When making API requests, append the specific endpoint path to the appropriate base URL. For example, making a request to the Create an Order endpoint in the Live environment, your full URL would look like this:
POST https://ws-api-platform.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1/orders
API AUTHENTICATION
Overview
The Omni Collect – Single API uses BASIC Authentication to secure access. Omni Collect requires that each API request includes the client's credentials - the Omni Authorization Key.

How BASIC Authentication Works
- Authorization Header: Include your Omni Authorization Key in the
Authorization
HTTP header of every API request.HTTP HeaderAuthorization: Basic <Omni Authorization Key>
- Server Verification: The API gateway decodes and verifies the credentials. If valid, the request is processed; if not, an authentication error is returned.
SECURING API COMMUNICATION
Overview
Every call to Omni Collect has two layers working together:
- HTTP layer: the request is authenticated with Basic Auth (the details have been covered in API Authentication).
- Payload layer: the request payload is protected with a sign-then-encrypt pattern, and the response payload is protected with a decrypt-then-verify pattern.
We implement both patterns using JOSE, an IETF family of standards for signing and encrypting JSON-based messages. Below we explain the JOSE pieces we use:
- JWS (JSON Web Signature) — A standard for adding a digital signature to JSON content. You create the signature with your private key so the receiver can cryptographically confirm who sent it and that it hasn’t been altered.
- JWE (JSON Web Encryption) — A standard for encrypting content. In our flow, the already-signed JWS is encrypted to the recipient’s public key, so only the recipient (Omni Collect) holding the matching private key can open it.
- Private key — A mathematical key kept secret by the holder. It is used to create digital signatures (for JWS) and to decrypt messages that were encrypted using the corresponding public key (for JWE).
- Public key — A mathematical key you can share. Others use it to verify signatures created with your private key (JWS) and to encrypt messages so that only you (with the matching private key) can decrypt them (JWE).

End-to-End Flow
You’ve already seen the core building blocks—JWS/JWE and public/private keys. Now we’ll put them together in a single, end-to-end exchange between your system and Omni Collect. The sequence diagram that follows walks through each step of the sign-then-encrypt pattern on requests and the decrypt-then-verify pattern on responses, showing how these components interact at every stage.
You won’t need to implement these primitives by hand—our sample code handles signing, encryption, decryption, and signature verification. Still, understanding the flow is essential for configuring keys and certificates, interpreting headers and troubleshooting issues during integration or in production.
Use the diagram as your mental model; the next section introduces the sample code examples you can apply directly.

Sample Code
The sample codes eliminate the need to implement JOSE signing and encryption from scratch. We currently provide sample codes for Java, PHP, Node.js, and C#. If your preferred language isn’t listed, please contact our Implementation Team for assistance.
import org.apache.commons.codec.binary.Base64; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; 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 { /** * Loads the merchant RSA private key from a PKCS#8 PEM file on disk. * * Expected input format (PKCS#8): * -----BEGIN PRIVATE KEY----- * BASE64... * -----END PRIVATE KEY----- * * Notes: * - Strips the PEM armor, Base64-decodes the body, and constructs a PrivateKey via PKCS8EncodedKeySpec. * - If your key is in PKCS#1 (BEGIN RSA PRIVATE KEY), convert it to PKCS#8 before use. * - Ensure secure file permissions (readable only by the application account). */ public static PrivateKey getMerchantPrivateKey() throws Exception { // Read entire PEM file into memory (UTF-8 text with header/footer lines) byte[] pemBytes; try (InputStream in = Files.newInputStream(Path.of("${MERCHANT_PRIVATE_KEY_PEM_PATH}"))) { pemBytes = in.readAllBytes(); } catch (IOException e) { throw e; // Surface I/O errors (file missing, permission denied, etc.) } // Remove PEM armor and whitespace; leave only Base64 payload String pem = new String(pemBytes) .replace("-----BEGIN PRIVATE KEY-----", "") .replace("-----END PRIVATE KEY-----", "") .replaceAll("\\s", ""); // Decode Base64 → DER (PKCS#8) byte[] der = Base64.decodeBase64(pem); // Build RSA PrivateKey from PKCS#8 bytes KeyFactory kf = KeyFactory.getInstance("RSA"); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(der); return kf.generatePrivate(spec); } /** * Loads the HSBC (recipient) RSA public key from an X.509 certificate file. * * Accepted formats: * - PEM: -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- * - DER: raw X.509 bytes * * What this does: * - Parses the certificate (no trust chain validation here) and extracts the embedded RSA public key * for JWS verification / JWE encryption. */ public static RSAPublicKey getHSBCPublicCert() throws Exception { X509Certificate cert; // Read certificate file (PEM or DER). CertificateFactory handles both. try (InputStream in = Files.newInputStream(Path.of("${HSBC_PUBLIC_CERT_PATH}"))) { CertificateFactory cf = CertificateFactory.getInstance("X.509"); cert = (X509Certificate) cf.generateCertificate(in); } // Extract and return the RSA public key contained in the certificate return (RSAPublicKey) cert.getPublicKey(); } }
import com.nimbusds.jose.*; import com.nimbusds.jose.crypto.RSAEncrypter; // encrypt JWE import com.nimbusds.jose.crypto.RSASSASigner; // sign JWS import java.security.PrivateKey; import java.security.interfaces.RSAPublicKey; public static String signAndEncryptRequestPayload(String requestPayloadStr) throws Exception { // #0: Load keys used in signing/encryption PrivateKey merchantPrivateKey = KeyProvider.getMerchantPrivateKey(); RSAPublicKey HSBCPublicKey = KeyProvider.getHSBCPublicCert(); // #1: Create the JSON request body (provided by caller as requestPayloadStr) // #2: Create JWS (sign the JSON payload) // #2.1 Build JWS payload from request JSON Payload jwsPayload = new Payload(requestPayloadStr); // #2.2 JWS header: alg=RS256, kid=<merchant signing key id> JWSHeader jwsHeader = new JWSHeader.Builder(JWSAlgorithm.RS256) .keyID("0001") .build(); // #2.3 Sign with merchant private key JWSObject jwsObject = new JWSObject(jwsHeader, jwsPayload); JWSSigner jwsSigner = new RSASSASigner(merchantPrivateKey); jwsObject.sign(jwsSigner); String compactJWS = jwsObject.serialize(); // #3: Create JWE (encrypt the JWS) // #3.1 JWE payload is the compact JWS Payload jwePayload = new Payload(compactJWS); // #3.2 JWE header: alg=RSA-OAEP-256, enc=A128GCM, kid=<recipient key id> JWEHeader jweHeader = new JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128GCM) .keyID("0006") .build(); // #3.3 Encrypt with recipient public key JWEObject jweObject = new JWEObject(jweHeader, jwePayload); JWEEncrypter encrypter = new RSAEncrypter(HSBCPublicKey); jweObject.encrypt(encrypter); String compactJWE = jweObject.serialize(); // #4: Send request — return compact JWE to use as HTTP body return compactJWE; }
import com.nimbusds.jose.*; import com.nimbusds.jose.crypto.RSADecrypter; // decrypt JWE import com.nimbusds.jose.crypto.RSASSAVerifier; // verify JWS import java.security.PrivateKey; import java.security.interfaces.RSAPublicKey; public static String decryptAndVerifyResponsePayload(String responsePayloadStr) throws Exception { // #0: Load keys used in decryption/verification PrivateKey merchantPrivateKey = KeyProvider.getMerchantPrivateKey(); RSAPublicKey HSBCPublicKey = KeyProvider.getHSBCPublicCert(); // #6: Receive the compact JWE string (provided as responsePayloadStr) // #7: Decrypt JWE with merchant private key // #7.1 Parse compact JWE to JWEObject JWEObject jweObject = JWEObject.parse(responsePayloadStr); // #7.2 Decrypt using merchant private key JWEDecrypter decrypter = new RSADecrypter(merchantPrivateKey); jweObject.decrypt(decrypter); // #7.3 Extract inner compact JWS String compactJWS = jweObject.getPayload().toString(); // #8: Verify JWS with HSBC public key // #8.1 Parse compact JWS to JWSObject JWSObject jwsObject = JWSObject.parse(compactJWS); // #8.2 Verify signature boolean isSignatureValid = jwsObject.verify(new RSASSAVerifier(HSBCPublicKey)); // (optional) assert validity, throw if needed // #9: Extract clear-text JSON payload and return String payload = jwsObject.getPayload().toString(); return payload; }
use Jose\Component\Core\JWK; use Jose\Component\KeyManagement\JWKFactory; class KeyProvider { /** * Returns the merchant private key as a JWK. * * Expected input: * - A PKCS#8 PEM private key file on disk (e.g., "-----BEGIN PRIVATE KEY----- ..."). * * What this does: * - Reads the PEM file and converts it into a JWK object compatible with the JOSE library. * * Security notes: * - Store the key outside your web root with restrictive file permissions. * - Consider environment-specific injection (env var or secrets manager) for the path. */ public static function getMerchantPrivateKey(): JWK { return JWKFactory::createFromKeyFile( '${Merchant private key file path}' ); } /** * Returns the recipient (HSBC) public key as a JWK, loaded from an X.509 certificate. * * Accepted formats: * - PEM certificate ("-----BEGIN CERTIFICATE----- ...") or DER-encoded certificate file. * * What this does: * - Parses the certificate and extracts the public key material as a JWK for JWS verification / JWE encryption. * * Note: * - This loads the key material only; it does not perform trust chain validation. * If you require CA validation, do so separately during TLS or certificate pinning. */ public static function getHSBCPublicCert(): JWK { return JWKFactory::createFromCertificateFile( '${HSBC public certificate file path}' ); } }
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\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\Serializer\CompactSerializer as JwsCompactSerializer; public static function signAndEncryptRequestPayload(string $payload): string { // #0: Load keys used in signing/encryption $merchantPrivateKey = KeyProvider::getMerchantPrivateKey(); $hsbcPublicCert = KeyProvider::getHSBCPublicCert(); // #1: Create the JSON request body (provided by caller as $payload) // #2: Create JWS (sign the JSON payload) // #2.1 Build JWS payload from request JSON $jwsAlgorithmManager = new AlgorithmManager([new RS256()]); $jwsBuilder = new JWSBuilder($jwsAlgorithmManager); // #2.2 JWS header: alg=RS256, kid=<merchant signing key id> $jws = $jwsBuilder ->create() ->withPayload($payload) ->addSignature($merchantPrivateKey, [ 'alg' => 'RS256', 'kid' => '0001', ]) ->build(); // #2.3 Serialize compact JWS $jwsSerializer = new JwsCompactSerializer(); $compactJWS = $jwsSerializer->serialize($jws, 0); // #3: Create JWE (encrypt the JWS) // #3.1 JWE payload is the compact JWS $jweKeyAlgMgr = new AlgorithmManager([new RSAOAEP256()]); $jweContentAlgMgr = new AlgorithmManager([new A128GCM()]); $compressionMgr = new CompressionMethodManager([new Deflate()]); $jweBuilder = new JWEBuilder($jweKeyAlgMgr, $jweContentAlgMgr, $compressionMgr); // #3.2 JWE header: alg=RSA-OAEP-256, enc=A128GCM, kid=<recipient key id> // #3.3 Encrypt with recipient public key and serialize compact JWE $jwe = $jweBuilder ->create() ->withPayload($compactJWS) ->withSharedProtectedHeader([ 'alg' => 'RSA-OAEP-256', 'enc' => 'A128GCM', 'kid' => '0006', ]) ->addRecipient($hsbcPublicCert) ->build(); $jweSerializer = new JweCompactSerializer(); $compactJWE = $jweSerializer->serialize($jwe, 0); // #4: Send request — return compact JWE to use as HTTP body return $compactJWE; }
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\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\JWSVerifier; use Jose\Component\Signature\Serializer\CompactSerializer as JwsCompactSerializer; public static function decryptAndVerifyResponsePayload(string $payload): string { // #0: Load keys used in decryption/verification $merchantPrivateKey = KeyProvider::getMerchantPrivateKey(); $hsbcPublicCert = KeyProvider::getHSBCPublicCert(); // #6: Receive the compact JWE string (provided as $payload) // #7: Decrypt JWE with merchant private key // #7.1 Set up algorithms and compression managers $jweKeyAlgMgr = new AlgorithmManager([new RSAOAEP256()]); $jweContentAlgMgr = new AlgorithmManager([new A128GCM()]); $compressionMgr = new CompressionMethodManager([new Deflate()]); // #7.2 Create decrypter and unserialize the compact JWE $jweDecrypter = new JWEDecrypter($jweKeyAlgMgr, $jweContentAlgMgr, $compressionMgr); $jweSerializerMgr = new JWESerializerManager([new JweCompactSerializer()]); $jweObject = $jweSerializerMgr->unserialize($payload); // #7.3 Decrypt and extract the inner compact JWS $jweDecrypter->decryptUsingKey($jweObject, $merchantPrivateKey, 0); $compactJWS = $jweObject->getPayload(); // #8: Verify JWS with HSBC public key // #8.1 Set up RS256 verifier and unserialize compact JWS $jwsAlgMgr = new AlgorithmManager([new RS256()]); $jwsVerifier = new JWSVerifier($jwsAlgMgr); $jwsSerializer = new JwsCompactSerializer(); $jwsObject = $jwsSerializer->unserialize($compactJWS); // #8.2 Verify signature (optionally assert $isVerified) $isVerified = $jwsVerifier->verifyWithKey($jwsObject, $hsbcPublicCert, 0); // #9: Extract clear-text JSON payload and return $cleartextPayload = $jwsObject->getPayload(); return $cleartextPayload; }
const fs = require('fs'); const jose = require('jose'); /** * Returns the merchant RSA private key imported from a PKCS#8 PEM file. * * Expected input format (PKCS#8): * -----BEGIN PRIVATE KEY----- * BASE64... * -----END PRIVATE KEY----- * * What this does: * - Reads the PEM from disk and imports it as a key usable by `jose` * for RS256 signing and RSA-OAEP-256 key management (when applicable). * * Security notes: * - Keep the key file outside the web root and lock down file permissions. * - Consider injecting the path via environment variables or a secrets manager. */ exports.getMerchantPrivateKey = async () => { const pem = fs.readFileSync('${Merchant private key file path}', 'utf8'); // Import as an RS256-capable key (required by jose for algorithm binding) return await jose.importPKCS8(pem, 'RS256'); }; /** * Returns the recipient (HSBC) RSA public key imported from an X.509 certificate. * * Accepted formats: * - PEM certificate: -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- * - (If you store DER, convert to PEM before import or use a DER reader.) * * What this does: * - Parses the certificate and imports the embedded RSA public key for: * - JWS verification (RS256) * - JWE RSA key management (e.g., RSA-OAEP-256) * * Note: * - This import does not validate a trust chain; handle CA validation separately if required. */ exports.getHSBCPublicCert = async () => { const certPem = fs.readFileSync('${HSBC public certificate file path}', 'utf8'); // Bind to RS256 so the key is usable for verification with jose return await jose.importX509(certPem, 'RS256'); };
const jose = require('jose'); exports.signAndEncryptRequestPayload = async (requestPayloadStr) => { // #0: Load keys used in signing/encryption const merchantPrivateKey = await KeyProvider.getMerchantPrivateKey(); const hsbcPublicKey = await KeyProvider.getHSBCPublicCert(); // #1: Create the JSON request body (provided by caller as requestPayloadStr) requestPayloadStr = JSON.stringify(requestPayloadStr); // #2: Create JWS (sign the JSON payload) // #2.1 Build JWS payload from request JSON and set header alg=RS256, kid=<merchant signing key id> const signedMessage = await new jose.CompactSign(new TextEncoder().encode(requestPayloadStr)) .setProtectedHeader({ alg: 'RS256', kid: '0001' }) .sign(merchantPrivateKey); // #3: Create JWE (encrypt the JWS) // #3.1 JWE payload is the compact JWS; header alg=RSA-OAEP-256, enc=A128GCM, kid=<recipient key id> const encryptMessage = await new jose.CompactEncrypt(new TextEncoder().encode(signedMessage)) .setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A128GCM', kid: '0006' }) .encrypt(hsbcPublicKey); // #4: Send request — return compact JWE to use as HTTP body return encryptMessage; };
const jose = require('jose'); exports.decryptAndVerifyResponsePayload = async (responsePayloadStr) => { // #0: Load keys used in decryption/verification const merchantPrivateKey = await KeyProvider.getMerchantPrivateKey(); const hsbcPublicKey = await KeyProvider.getHSBCPublicCert(); // #6: Receive the compact JWE string (provided as responsePayloadStr) // #7: Decrypt JWE with merchant private key // #7.1 Decrypt and extract inner compact JWS const decrypted = await jose.compactDecrypt(responsePayloadStr, merchantPrivateKey); const compactJWS = new TextDecoder().decode(decrypted.plaintext); // #8: Verify JWS with HSBC public key // #8.1 Verify signature and extract clear-text JSON payload const verified = await jose.compactVerify(compactJWS, hsbcPublicKey); const payload = new TextDecoder().decode(verified.payload); // #9: Return verified JSON payload return payload; };
using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; class KeyProvider { // Loads the merchant RSA private key from a PKCS#8 PEM file. // // Expected format (PKCS#8): // -----BEGIN PRIVATE KEY----- // BASE64... // -----END PRIVATE KEY----- // // Notes: // - If your key is PKCS#1 (BEGIN RSA PRIVATE KEY), convert it to PKCS#8 before use. // - Keep the key outside the web root and restrict file permissions. public static RSA GetMerchantPrivateKey() { string pem = File.ReadAllText("${Merchant private key file path}"); RSA merchantPrivateKey = RSA.Create(); merchantPrivateKey.ImportFromPem(pem); return merchantPrivateKey; } // Loads the recipient (HSBC) RSA public key from an X.509 certificate file. // // Accepted formats: // - PEM certificate (BEGIN CERTIFICATE ... END CERTIFICATE) or DER-encoded .cer/.crt // // What this does: // - Reads the certificate and extracts the embedded RSA public key for JWS verification / JWE encryption. // - Does not perform trust-chain validation; handle that separately if required. public static RSA GetHsbcPublicCert() { using var cert = new X509Certificate2("${HSBC public certificate file path}"); RSA? hsbcPublicCert = cert.GetRSAPublicKey(); if (hsbcPublicCert == null) { throw new CryptographicException("Certificate does not contain an RSA public key."); } return hsbcPublicCert; } }
using Jose; using System.Security.Cryptography; using System.Collections.Generic; public static string SignAndEncryptRequestPayload(string requestPayloadStr) { // #0: Load keys used in signing/encryption RSA merchantPrivateKey = KeyProvider.GetMerchantPrivateKey(); RSA hsbcPublicCert = KeyProvider.GetHsbcPublicCert(); // #1: Create the JSON request body (provided by caller as requestPayloadStr) // #2: Create JWS (sign the JSON payload) // #2.1 Build JWS headers and sign with merchant private key var jwsHeaders = new Dictionary<string, object> { { "kid", "0001" } // merchant signing key id }; string compactJWS = JWT.Encode( requestPayloadStr, merchantPrivateKey, JwsAlgorithm.RS256, extraHeaders: jwsHeaders ); // #3: Create JWE (encrypt the JWS) // #3.1 JWE payload is the compact JWS; header kid=<recipient key id> var jweHeaders = new Dictionary<string, object> { { "kid", "0006" } // recipient public key id }; string compactJWE = JWT.Encode( compactJWS, hsbcPublicCert, JweAlgorithm.RSA_OAEP_256, JweEncryption.A128GCM, extraHeaders: jweHeaders ); // #4: Send request — return compact JWE to use as HTTP body return compactJWE; }
using Jose; using System.Security.Cryptography; public static string DecryptAndVerifyResponsePayload(string responsePayloadStr) { // #0: Load keys used in decryption/verification RSA merchantPrivateKey = KeyProvider.GetMerchantPrivateKey(); RSA hsbcPublicCert = KeyProvider.GetHsbcPublicCert(); // #6: Receive the compact JWE string (provided as responsePayloadStr) // #7: Decrypt JWE with merchant private key // #7.1 Decrypt and extract inner compact JWS string compactJWS = JWT.Decode(responsePayloadStr, merchantPrivateKey); // #8: Verify JWS with HSBC public key // #8.1 Verify signature and extract clear-text JSON payload string payload = JWT.Decode(compactJWS, hsbcPublicCert); // #9: Return verified JSON payload return payload; }
MAKING AN API CALL
Overview
With the API base URL set, Basic Authentication applied, and message encryption and digital signatures enabled, you’re ready to make an API call.
HTTP Headers
For every API call, ensure the following headers are included:
HTTP Headers | Descriptions | Example Values |
---|---|---|
Authorization | Include your Omni Authorization Key in the Authorization HTTP header. |
Authorization: Basic YXBpdXNlcjpzZWN1cmVwYXNzd29yZA== |
x-hsbc-msg-encrypt-id | This header concatenates your registered market location, merchant ID, and the key IDs (kid) for JWS and JWE using plus (+) separators, in the format [Location]+[MerchantID]+[JWS_kid]+[JWE_kid] . Our API gateway uses this value to perform additional validation.
In the Sandbox Environment: You have find your Merhcnat ID in the Dev Hub.
![]() In the Live Environment: Our Production Implementation Team will guide you through the go-live migration process.
|
x-hsbc-msg-encrypt-id: uk+HSBCOmniCollectTest+0001+0006 |
message_encrypt | The header’s value is boolean. When set to false , payload encryption and digital signature are skipped, and both requests and responses are sent as plain JSON.
This header is available only in the Sandbox environment for testing or troubleshooting. In the Live environment, payload encryption and digital signatures are mandatory for all API requests.
|
message_encrypt: false |
Content-Type | Set content-type to application/json |
content-type: application/json |
Request for a POST operation
This section demonstrates how to send a POST request in two variants: with Message Encryption & Signing and without. The without path is available only in the sandbox for troubleshooting and is not permitted in production. When Encryption & Signing are enabled, only the request payload is encrypted and signed; the endpoint, query parameters, and headers remain in the clear.
curl -X POST 'https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1/order' \ -H 'Authorization: Basic YXBpdXNlcjpzZWN1cmVwYXNzd29yZA==' \ -H 'x-hsbc-msg-encrypt-id: uk+HSBCOmniCollectTest+0001+0006' \ -H 'message_encrypt: false' \ -H 'content-type: application/json' \ --data-binary '{ "id": "order-1234", "amount": 3000, "currency": "gbp", "description": "3 bottels of Vitamin C", "checkout_model": { "uk_gp_hosted_checkout": { "url_setting": { "return_page": "https%3A%2F%2Fwww.example.com%2Freturn"...truncated... '
When using encryption and signing, the original JSON payload will be transformed into a JWE Token. Replace the request payload with the JWE Token (a.k.a. JWT) in the following format:
eyJraWQiOiJrZXlfMjZiMWE...truncated...h7Q.VIWO_tB1Ey9oVWPf_q10Q
The POST request would then look like this:
curl -X POST 'https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1/order' \ -H 'Authorization: Basic YXBpdXNlcjpzZWN1cmVwYXNzd29yZA==' \ -H 'x-hsbc-msg-encrypt-id: uk+HSBCOmniCollectTest+0001+0006' \ -H 'content-type: application/json' \ --data-binary 'eyJraWQiOiJrZXlfMjZiMWE...truncated...h7Q.VIWO_tB1Ey9oVWPf_q10Q'
Request for a GET operation
We also provide two variants—encrypted/signed and a sandbox-only plain version for a GET request. For GET, there is no request body. When Encryption & Signing are enabled, only the resource identifier in the path (e.g., /resources/{id}
) is encrypted and signed before being placed in the URL. All other elements—endpoint, headers, and any non-sensitive query parameters—remain unchanged.
curl -X GET 'https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1/order/order-1234/payments?page=1' \ -H 'Authorization: Basic YXBpdXNlcjpzZWN1cmVwYXNzd29yZA==' \ -H 'x-hsbc-msg-encrypt-id: uk+HSBCOmniCollectTest+0001+0006' \ -H 'message_encrypt: false' \ -H 'content-type: application/json'
For a GET request, the path parameter needs to be encrypted and signed. For example, if you’re retrieving any record(s) from ID order-1234
, you would encrypt and sign the string order-1234
to generate a JWE Token.
eyJraWQiOiJrZX...truncated...9oVWPf_q10Q
The GET request would then look like this:
curl -X GET 'https://ws-api-platform-pprd.business.hsbc.com.hk/glcm-mobilecoll-mccon-ea-merchantservices-proxy/v1/order/eyJraWQiOiJrZX...truncated...9oVWPf_q10Q/payments?page=1' \ -H 'Authorization: Basic YXBpdXNlcjpzZWN1cmVwYXNzd29yZA==' \ -H 'x-hsbc-msg-encrypt-id: uk+HSBCOmniCollectTest+0001+0006' \ -H 'content-type: application/json'
Response Handling
With Encryption & Signing enabled, responses are encrypted and require decryption/verification; when disabled, responses are plain JSON. Error responses (HTTP status codes 4xx/5xx) are always plain JSON across all environments.
{ "id": "order-1234", "entity": "order", "status": "created", "created": 1676370303, "amount": 3000, "currency": "gbp", ...truncated... }
{ "type": "api_gateway_error", "code": "schema_error", "message": "required field 'description' is missing.", "time": 1661517573 }
The response is encrypted and signed by Omni Collect, and is returned as a JWE Token in the following format:
eyJraWQiOiJrZX...truncated...9oVWPf_q10Q
To read the response, you will need to decrypt and verify the signature as described in the Securing API Communications section.