# 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: 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:

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

The question should be specific, self-contained, and written in natural language.
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.
