SubAccount for B2C Clients

Please read the B2C Subaccount Onboarding product guide and review this page before continuing to the endpoints.

In this page, you will be guided to:

  1. Set you X-Signature that will be use in request header
  2. Generate a Public and Private Key pair that you will submit via this API.
  3. Decrypting the Client Key and Client Secret you receive from Create Subaccount API and Regenerate API Key API

🔐 1. Authentication: X-Signature Header

To ensure secure API communication, each request must include a custom header: X-Signature. This signature ensures the integrity and authenticity of your requests using HMAC-SHA512 and client_secret.

Signature Format

You must construct a colon-separated string in the following format:

<HTTP_METHOD>:<REQUEST_PATH>:<ACCESS_TOKEN>:<TIMESTAMP>

Parameter Definitions

ParameterDescription
HTTP_METHODThe HTTP method in UPPERCASE (e.g., POST, GET, DELETE)
REQUEST_PATHThe relative API path (e.g., /v2/payments/general/b2c/sub-accounts, /v2/payments/general/b2c/sub-accounts/{sub_account_code}/regenerate-api-key)
ACCESS_TOKENYour public access token, generated via this endpoint
TIMESTAMPThe request timestamp in ISO 8601 format (e.g., 2025-05-28T09:17:19.738+07:00)

Signature Generation Steps

  1. Construct the Raw String
    Example:
POST:/v2/payments/general/b2c/sub-accounts:eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxODQ4IiwiY29sb3VyIjoiI2UwMjlmNSIsInJvbGUiOlsiVVNFUiJdLCJuYW1lIjoiUFQgUWFtaUF3ZXNvbWUgTWFpbiIsImlzcyI6IlBUIFFhbWlBd2Vzb21lIE1haW4iLCJleHAiOjE3NDg4NTMxMzIsImlhdCI6MTc0ODg1MjgzMiwianRpIjoiYjk3OTg5NGMtZjY1Mi00MGE0LThkNzctNTljZDRjZGNkMzY4IiwidHMiOjE3NDg4NTI4MzIwMzJ9.MQQ9fc2dJgQQqgJuBsekPr066qAFVWUaZm2VmF9fvBw:2025-05-28T09:17:19.738+07:00
  1. Generate HMAC-SHA512 Hash
    1. Use your client_secret as the key
    2. Sign the raw string using HMAC-SHA512
  2. Base64 Encode the Hash
    Base64-encode the result of the hash to generate the final X-Signature value

Go Implementation example

import (  
    "crypto/hmac"  
    "crypto/sha512"  
    "encoding/base64"  
)
func generateHMAC(message, secret string) string {  
    key := \[]byte(secret)  
    h := hmac.New(sha512.New, key)  
    h.Write(\[]byte(message))  
    return base64.StdEncoding.EncodeToString(h.Sum(nil))  
}

🔒

Note on Security

Always use HTTPS for all API requests. Ensure that your client_secret is securely stored and never exposed on the client-side (e.g., in browser apps or mobile apps).



2. Generate a Public and Private Key pair in your device

To generate a public and private key pair, you will need to open your device terminal and follow these steps:

  1. Generate Private Key
    Generate a 2048-bit RSA private key:
    openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
  2. Extract Public Key
    Extract the corresponding public key from the private key:
    openssl rsa -pubout -in private_key.pem -out public_key.pem

Your private key will be saved in private_key.pem and your public key will be saved in public_key.pem. You need to submit your public_key.pem through our [B2C Client] Setup Public Key API.

🚧

Always keep you Private Key in a safe and secure place.

3. Decrypting the Client Key and Client Secret You Receive from Brick

You can use this code snippet in Go language to decrypt the client key and client secret you receive, using the Private Key you generate on the previous step.

package main
import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"os"
)
// DecryptWithPrivateKey decrypts a base64-encoded ciphertext using a private RSA key.
func DecryptWithPrivateKey(base64Cipher string, privateKeyPath string) (string, error) {
	// Read private key file
	privPEM, err := os.ReadFile(privateKeyPath)
	if err != nil {
		return "", err
	}
	// Decode PEM block
	block, _ := pem.Decode(privPEM)
	if block == nil || block.Type != "RSA PRIVATE KEY" {
		return "", errors.New("invalid private key PEM")
	}
	// Parse private key
	privKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return "", err
	}
	// Decode base64 input
	ciphertext, err := base64.StdEncoding.DecodeString(base64Cipher)
	if err != nil {
		return "", err
	}
	// Decrypt
	plaintext, err := rsa.DecryptPKCS1v15(nil, privKey, ciphertext)
	if err != nil {
		return "", err
	}
	return string(plaintext), nil
}