> For the complete documentation index, see [llms.txt](https://prepaidify.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://prepaidify.gitbook.io/docs/physical-card/api-integration.md).

# 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.prepaidify.com>

Production Environment: <https://physicalcard-api.prepaidify.com>

## Document Description

### 1. Overview

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

### 2. Common Interface Parameters

| Field Name     | Variable Name | Required | Type   | Base64 Encoding | Description                                                          |
| -------------- | ------------- | -------- | ------ | --------------- | -------------------------------------------------------------------- |
| Partner ID     | agentId       | Y        | string | N               | Partner ID assigned by the institution                               |
| Request String | reqData       | Y        | string | N               | Request RSA encrypted data, encoded after encryption with URLEncoder |
| Language       | language      | N        | string | N               | zh, en                                                               |
| Signature      | signature     | Y        | string | N               | MD5 signature string                                                 |

### 3. Common Interface Response

| Field Name           | Variable Name | Required | Type   | Base64 Encoding | Description                  |
| -------------------- | ------------- | -------- | ------ | --------------- | ---------------------------- |
| Response Code        | respCode      | Y        | string | N               | 00: Success, Others: Failure |
| Response Description | respMsg       | N        | string | N               | Exists in case of failure    |
| Request String       | respData      | N        | string | N               | Response 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')
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://prepaidify.gitbook.io/docs/physical-card/api-integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
