API Integration

Description

  • The physical card API provides access to the underlying capabilities of the bank.
  • Merchants need to handle token deposits themselves.

Environment Information

Test Environment: https://test-physicalcard-api.alchemypay.org

Production Environment: https://physicalcard-api.alchemypay.org

Document Description

1. Overview

This document provides explanations for third-party integration interfaces. Target audience: technical developers.

2. Common Interface Parameters

Field NameVariable NameRequiredTypeBase64 EncodingDescription
Partner IDagentIdYstringNPartner ID assigned by the institution
Request StringreqDataYstringNRequest RSA encrypted data, encoded after encryption with URLEncoder
LanguagelanguageNstringNzh, en
SignaturesignatureYstringNMD5 signature string

3. Common Interface Response

Field NameVariable NameRequiredTypeBase64 EncodingDescription
Response CoderespCodeYstringN00: Success, Others: Failure
Response DescriptionrespMsgNstringNExists in case of failure
Request StringrespDataNstringNResponse RSA encrypted data

4. Interface Invocation Details

Interfaces typically include three request parameters: agentId, reqData, signature.

Signature Generation Rule

Convert the body to a JSON string + md5Key, then encrypt it using MD5.

For example:

str = {"name":"xxx","age":"18"}123453333
md5(str)

repData Generation Rule

Similarly, convert the body to a JSON string, then encrypt it using an RSA public key to obtain an encrypted string, and then base64 encode it.

For example:

def encrypt(message: str, pub_key: str) -> str | None:
    try:
        pubkey = rsa.PublicKey.load_pkcs1_openssl_pem(pub_key.encode())
        message_bytes = message.encode()
        chunks = [message_bytes[i:i + CHUNK_SIZE] for i in range(0, len(message_bytes), CHUNK_SIZE)]
        crypto = b"".join([rsa.encrypt(chunk, pubkey) for chunk in chunks])
        return base64.b64encode(crypto).decode()
    except Exception as e:
        print(f"Error encrypting message: {e}")
        return None

Example of Usage

Note that the format should be application/x-www-form-urlencoded instead of application/json.

curl -X POST https://test.xxx.com/api/mastercard/holderQuery.html \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "agentId=888666000100201&reqData=2%2FCgBnwbtXQRR2XVmLu9uOiBCfjnd1pwq59LtPhufF6VtjbKcArfHE9Cqff575EFbIEBanPKlXbilnJj2Gz4AnEs1BOZOUEO85UIcD7YBBXdt1BC3vX8hzWXrsnPbC1ZW4589r7B40h0lL9NAOjs%2BJaDIN3nmpdqvFHJ4hF1rb0%3D&signature=e5c3ca8eba4de85f44262f8d34ac21ee"

Response Example

Normally, all interface data needs to be decrypted using an RSA private key when receiving data from the server.

{"respCode":"00","respMsg":"","respData":"nnTq5O+k89BsneEN1+SUKxj6PlNSsBzeF29IeEkNQjWrRATjW+dtYPONKFO9YfG5dlLg1qZH5PBRbEWB44Q9wmvT5PLoJNdM5Uk1zhhLQ0sJA186BSiwxwMYty0wgWgC6lsY4QQzuNR/aAsr8DxLR7vsTxaPB3m5qAzO8i7D/Xu22OX52CxxDeNizXwg1+0iyKU6S5AOEKCkF52iJY8OucVOt2sq9q1aX2wBijG12ZWyuh6iVHMtJxrxEOTYpp1h481ixBvt809hte2J26mn0hbWPW8v14X/LsS+5Mf5/0CcHm72tZ+EELyeDGI4TeZQeTw3Yf97KZfQ83cO15Ggzg=="}

Example of Decryption:

def decrypt(encrypted_data: str, private_key: str) -> str:
    private_key_bytes = private_key.encode('utf-8')
    encrypted_data = base64.b64decode(encrypted_data)

    # Deserialize the private key from PEM format
    private_key_obj = serialization.load_pem_private_key(private_key_bytes, password=None, backend=default_backend())

    # Determine the appropriate chunk size based on the private key size
    key_size_bytes = private_key_obj.key_size // 8  # Convert bits to bytes
    decrypted_data = b""

    # Decrypt the data in chunks based on the key size
    for offset in range(0, len(encrypted_data), key_size_bytes):
        chunk = encrypted_data[offset:offset + key_size_bytes]
        decrypted_chunk = private_key_obj.decrypt(chunk, padding.PKCS1v15())
        decrypted_data += decrypted_chunk

    return decrypted_data.decode('utf-8')