Introduction

This documentation aims to provide all the information you need to work with our API.

Getting Started

Authenticating requests

All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Replace {YOUR_AUTH_KEY} in "Bearer {YOUR_AUTH_KEY}" with the generated access token in the Reauthenticate Token endpoint.

Signing of request payload

Before connecting to our Paywho API system, it will be necessary for us to do an exchange of public keys to digitally sign our payload.

PAYWHO PUBLIC KEY:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwWXFOFgqBhDqoeCA6KPO
JS1UJGe3FJmmV4QZPN+/gZDETKPnNOiKjyxQmBOmgpAOZkwHHONOzbnqLJj/AAak
RWndlLJ0X8/TiiNtFsyXe7c7pE3eIdZW1ecBLqCCaf/P9ywrCYPkH8agUbvu7XKy
n3I3PbpcKE1L5a2fecgDzp2/4X0R41jL2q+fFtMwrcD7d+WfxmmpqgtNcdH2vGxD
Vs5iPWtdE0LY9EdMIchOd1F9QFVOhCxoMdSiyWIyk1WsGcoE8fAqOU0kTE35jPgT
03LRKwQ/PopGLsGpE57bmIb5a5Sr7q7B/u2S3revqToFLOQU+cvgNa0Bfx5kkwD5
twIDAQAB
-----END PUBLIC KEY-----

Paywho uses the Ron Rivest, Adi Shamir and Leonard Adleman (RSA.) encryption standard to digitally sign and verify payloads mutually. In particular, the signature standard that is required is SHA-1 PKCS1 mode, 2048 bits.
Our public key is given on the right, we would require you to provide your public key following the above encryption standard. Here are some links to help you with the generation and the verification of your public and private keys (.pem).

Online: https://travistidwell.com/jsencrypt/demo/
Command Line: https://www.scottbrady91.com/openssl/creating-rsa-keys-using-openssl

You can verify your base64 encoded signature here: https://8gwifi.org/RSAFunctionality?rsasignverifyfunctions=rsasignverifyfunctions&keysize=2048

Sign your payload by following these steps

  1. Generate your private and public.
  2. Set the RSA signing algorithm to SHA-1 (PKCS1).
  3. When signing a request, the generation of the signature follows the following general steps.
    a. JSON encode/stringify the payload of the request.

    • i. For POST requests, the payload is the request body. The JSON encoded output should look like:
      '{"transferType":3,"payoutMethod":1,"payoutCurrency":"CNY"}'.
    • ii. For GET requests, the payload is the JSON representation of the query parameters. For example,
      a request to get the exchange rate would look like "https://corporate-staging.paywho.com/api/get_exchange_rate? transferType=3&payoutMethod=1&payoutCurrency=CNY". The payload JSON encoded would be '{"transferType":"3","payoutMethod":"1","payoutCurrency":"CNY"}'.
    • iii. For GET requests, do take note that the conversion of query parameters to a JSON payload (for signing) translates all values to strings. Even numeric values will be placed in quotation marks.
    • iv. For GET requests that does not have any query parameters, such as api/get_available_countries, the JSON encoded payload used to sign the request will be '[]'.
    • v. All white spaces at the front and back of the values in the body of the requests are to be trimmed. ("senderFirstName"=>" David " should be trimmed to "senderFirstName"=>"David").

    b. Sign the JSON encoded payload with your private key.
    c. Base64 encode the signed payload (This is your signature).

  4. Add the signature to the request headers with the key 'x-signature'.

HTTPS Request Example:

"body" => Payload
"headers" => [
  "Content-Type" => "application/json",
  "Authorization" => "Bearer " + Bearer Token,
  "x-signature" => Base 64 encoded Signature of Json Encoded Payload
]

The sample body of the correct payload to be sent to our system can be referred on the right

Special Note on Chinese characters:
When Chinese characters are being used in the request body, the Chinese characters needs to be converted to its unicode form when you JSON encode/stringify. For example, this
{"receiverNativeFirstName":"珊金娃"}
Will be converted to this
{"receiverNativeFirstName":"\u73ca\u91d1\u5a03"} You can double check the conversion using the following site: ChineseConverter.com - Resources for learning Mandarin Chinese

Verifying Signature

If you encounter the issue, Signature not verified, when calling our API endpoints, the Corporate Web Portal provides a tool to check for the issues with your request payload or your generated x-signature. Please follow these steps to verify your signature:

  1. Login to the Corporate Web Portal at https://corporate.paywho.com [LIVE] or https://staging-corporate.paywho.com [UAT].
  2. Click on "Developers", followed by "API Integration" on the menu on the left.
  3. Fill in the Request Payload and X-Signature in the Paywho system.
  4. Click the submit button and you will see if there are any issues with your request payload or your generated x-signature.

Configuring your public key

The Corporate Web Portal allows you to upload the public key used in signing requests directly without the need for assistance from our team. Please follow these steps to successfully upload/change the public key for request signing:

  1. Login to the Corporate Web Portal at https://corporate.paywho.com [LIVE] or https://staging-corporate.paywho.com [UAT].
  2. Click on "Developers", followed by "API Integration" on the menu on the left.
  3. Upload a valid public key in the Paywho system.
  4. Upon receiving a successful upload confirmation, your new key will be active. You can change your public key as frequently as required.

Webhook calls

Once the transaction is completed or rejected (due to compliance hit or other operational reasons), in our system, we will send updates to your system via a webhook call. Do provide us your URL for our system to call.

If transaction is Compliance Approved, Pending Payout, Pending Payout Partner Compliance Check, Completed or Rejected in our system, we will send you the following responses on the right

Example response status for Compliance Approved:

{
  "transactionReference": "DUMMYTXN0001",
  "sender_full_name": "John Smith",
  "beneficiary_full_name": "Zhou Tang Tang",
  "payout_amount": "4000 CNY",
  "fx_rate": "6.82316",
  "fees": "1 USD",
  "collected_amount": "587.24 USD",
  "status": "Processing",
  "compliance_status": "Compliance Approved",
  "error": null,
  "error_code": null
}

Example response status for Pending Payout:

{
  "transactionReference": "DUMMYTXN0001",
  "sender_full_name": "John Smith",
  "beneficiary_full_name": "Zhou Tang Tang",
  "payout_amount": "4000 CNY",
  "fx_rate": "6.82316",
  "fees": "1 USD",
  "collected_amount": "587.24 USD",
  "status": "Pending Payout",
  "compliance_status": "Compliance Approved",
  "error": null,
  "error_code": null
}

Example response status for Pending Payout Partner Compliance Check:

{
  "transactionReference": "DUMMYTXN0001",
  "sender_full_name": "John Smith",
  "beneficiary_full_name": "Zhou Tang Tang",
  "payout_amount": "4000 CNY",
  "fx_rate": "6.82316",
  "fees": "1 USD",
  "collected_amount": "587.24 USD",
  "status": "Pending Payout Partner Compliance Check",
  "compliance_status": "Compliance Approved",
  "error": null,
  "error_code": null
}

Example response status for Completed:

{
  "transactionReference": "DUMMYTXN0001",
  "sender_full_name": "John Smith",
  "beneficiary_full_name": "Zhou Tang Tang",
  "payout_amount": "4000 CNY",
  "fx_rate": "6.82316",
  "fees": "1 USD",
  "collected_amount": "587.24 USD",
  "status": "Completed",
  "compliance_status": "Compliance Approved",
  "error": null,
  "error_code": null
}

Example response status for Rejected:

{
  "transactionReference": "DUMMYTXN0001",
  "sender_full_name": "John Smith",
  "beneficiary_full_name": "Zhou Tang Tang",
  "payout_amount": "4000 CNY",
  "fx_rate": "6.82316",
  "fees": "1 USD",
  "collected_amount": "587.24 USD",
  "status": "Rejected",
  "compliance_status": "Compliance Rejected",
  "error": "The account number is wrong.",
  "error_code": "99-01"
}

Example response status for RFI requests:

{
  "transactionReference": "DUMMYTXN0001",
  "sender_full_name": "John Smith",
  "beneficiary_full_name": "Zhou Tang Tang",
  "payout_amount": "4000 CNY",
  "fx_rate": "6.82316",
  "fees": "1 USD",
  "collected_amount": "587.24 USD",
  "status": "Pending Payout",
  "compliance_status": "Compliance Approved",
  "error": null,
  "error_code": null,
  "rfi_requests": [
    {
        "remmitance_transaction_rfi_id": 1,
        "customer_type":"receiver",
        "name": "IC - Front"
    },
    {
        "remittance_transaction_rfi_id": 2,
        "customer_type": "receiver",
        "name": "IC - Back"
    }
  ]
}

Example response status for RFI requests with generated link:

{
  "transactionReference": "DUMMYTXN0001",
  "sender_full_name": "John Smith",
  "beneficiary_full_name": "Zhou Tang Tang",
  "payout_amount": "4000 CNY",
  "fx_rate": "6.82316",
  "fees": "1 USD",
  "collected_amount": "587.24 USD",
  "status": "Pending Payout",
  "compliance_status": "Compliance Approved",
  "error": null,
  "error_code": null,
  "rfi_request_url": "https://staging-corporate.paywho.com/rfi/generated-page?id=cd4ef386-3f96-4e47-88a5-26f55ff2db48"
}

Example response status for RFI request rejected reason:

{
  "transactionReference": "DUMMYTXN0001",
  "sender_full_name": "John Smith",
  "beneficiary_full_name": "Zhou Tang Tang",
  "payout_amount": "4000 CNY",
  "fx_rate": "6.82316",
  "fees": "1 USD",
  "collected_amount": "587.24 USD",
  "status": "Pending Payout",
  "compliance_status": "Compliance Approved",
  "error": null,
  "error_code": null,
  "rfi_rejected": {
    "remittance_transaction_rfi_id": 553,
    "customer_type": "sender",
    "name": "Passport",
    "reason": "Attachment is blurry. Unable to verify details"
  }
}

Response sent back to our system

We require a response from your system after our system has done a webhook call to yours, in the following requirements

  1. It must be a POST request
  2. Return a 2xx status code
  3. Response within 3 seconds If these requirements are not done, the webhook call will be considered a fail.

In the case where the webhook call to your system failed

Our Paywho system will resend a webhook call twice, after 10 seconds and 100 seconds respectively.

Manually resend webhook call

You can manually resend a webhook call via corporate web portal https://staging-corporate.paywho.com

On the corporate web portal page, go to Developers > Webhooks in the side menu

Click "Resend" button

Resend Webhook Screenshot

Transfer Types and Payout Methods

Our system supports the following transfer types and payout methods
Transfer Types

Payout Methods

Error Codes & Statuses

Error Codes

Prefix Category
01 General
02 Technical
03 Paywho Compliance
04 Configurations
05 Banking information
06 Invalid Fields
07 Payout Bank
99 Other
Code Message
01-01 Transaction has been cancelled as per client's request.
02-01 Paywho is unable to process the transaction due to technical difficulties.
02-02 The payout bank is currently experiencing technical difficulties in processing transactions.
05-01 Account verification error. The banking information of the recipient is not valid
05-02 Receiver account is frozen and unable to receive funds.
05-03 The payee bank card is a class II or III personal bank settlement account, which exceeds the daily limit. Please get in touch with the customer to try again tomorrow or change to another bank card or payee and then try again.
05-04 The account number is invalid.
06-01 Receiver is not the director or shareholder of the company.
06-02 The commodity description is insufficient.
06-03 The receiver's website link provided is incorrect.
06-04 The website does not list the commodity
07-01 Monthly transaction limit of 5 times has been reached.
07-02 The bank has blacklisted the sender and receiver transactions.
07-03 The ID card number used is not accepted. Only the director/shareholder's China National ID Number is accepted.
07-04 Sender has been blacklisted by the payout bank.
99-01 Any other messages not in the above list.

Statuses

Name Description
Pending Payout The transaction request has forwarded to the payout partner.
Completed Funds have been disbursed to the receiver.
Rejected The transaction could not be serviced.
Processing Our system is processing the transaction.
Pending Payout Partner Compliance Check The transaction is awaiting compliance clearance in payout partner's system.
Compliance Pending There is a compliance hit to the transaction and our compliance officers are in the midst of resolving it.
Compliance Approved Transaction has passed Paywho’s compliance checks.
Compliance Rejected The transaction has failed Paywho’s compliance and due diligence checks. Details about the reason can be found in the Error Codes table above.

Request for Information (RFI) files

These are the rfi fields you would use in request body under the fields customer_type and field_name in the api/rfi-file/upload endpoint.

Note: IC refers to Identification Card.

RFI File Fields

Customer Type Field Name
sender IC
sender Work Permit
sender Passport
sender Invoice
sender Source of Funds
sender Relationship Proof
sender Screenshot of shop/Biz Cert
sender Authorization letter
sender Certificate of Incorporation
sender Registered Business Profile (from local registrar)
sender Business License from Regulatory Body
sender Valid Government ID (of company directors / authorized representative)
receiver IC
receiver Work Permit
receiver Passport
receiver Invoice
receiver Source of Funds
receiver Authorization letter
receiver Certificate of Incorporation
receiver Registered Business Profile (from local registrar)
receiver Business License from Regulatory Body
receiver Valid Government ID (of company directors / authorized representative)

Transaction Flow Diagram

This diagram shows how remittance transactions are being processed when received in our API system.

View Full Image in New Tab

Transaction Flow Diagram

Endpoints

Reauthenticate Token

Get the access token for authentication

Example request:
curl --request POST \
    "http://localhost/paywho-api-system/public/api/reauthenticate_token" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"username\": null,
    \"password\": null
}"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/reauthenticate_token"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "username": null,
    "password": null
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'http://localhost/paywho-api-system/public/api/reauthenticate_token',
    [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'username' => null,
            'password' => null,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/reauthenticate_token'
payload = {
    "username": null,
    "password": null
}
headers = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Retrieved Token Successfully",
    "data": {
        "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiN2JjNmVkNDUxZTYyNmY0MzRjMDgyMTE2NGE2MmM5MDQzYWNkYzQ1ODlkMWQ4M2JiYTc4NzU5MjYxMTY2MzYxZDQyY2EzZjUxMjYwMmVhOWYiLCJpYXQiOjE2ODY4MDMzMDkuNjkzMTY1MDYzODU4MDMyMjI2NTYyNSwibmJmIjoxNjg2ODAzMzA5LjY5MzE2Njk3MTIwNjY2NTAzOTA2MjUsImV4cCI6MTY4NzQwODEwOS42ODY2NTI4OTg3ODg0NTIxNDg0Mzc1LCJzdWIiOiIyMyIsInNjb3BlcyI6W119.iPiu4dt7-nbXNSyJn5NGjfmVWFJXV-nYm-xWMEvjGiAyPkLgjocSbV9wE0E2Ji1Lq8Xch6BI8-FLsOQItlEBgr8dOvvbRNGn5tx5WTru7TSxqWQpmOppFfUmICvZUpC8w-UJ5tgRpDAMEIU44iGMl9PWfIpQXQRGW0Z5Qd9g-vLFaIIsO-7q-UjpOqnIckrBdTczjAu3MANVHnDxbot7J6bW0YdbfnYrJV5lspAciOcdvAmOGvoYWEsGot0qM_unoBPAl9Ewsr66LtRsj9b_-doObQhwK4DpkYyASeEQvZNwgqn_pDwxKs0__fLRWlUSMhIuXNWjQBdWR3lXorkh6mWmXZkk1evYg9yWMyiINhA01WUKuyy27yK0OTS_xMl4CZdTi50FIJuLXKpRHu00jdktWqjTnnadVT40zFgFxLKaiSzdRifuHIIy-nlvWk74baLNcDYl9hgZa7dFS_771gawKfdDl2HcqyoLe4ZGTP-IdIpfy1ZpsmTvB2jPnQL1iuGCtahSpx40Er1dUkmwbQjNst3WJ6lFwcM_w9RDEj9RF3YHLZp-DuXjZwp5RlNxiAfJF0uKJfbwhv_nR4BUnMJ0Kmj0Jbrs-EoW1Avlrg4GaLXnK8FUhzoM_rWe5xRi7TG8qeeaEunxcj6OaH96ukxatFTGLKKYA4FGQILLZzM"
    }
}
 

Example response (400):


{
    "status": "failed",
    "error": "Failed to get authorized token",
    "error_messages": "Incorrect User Credentials",
    "data": null
}
 

Request      

POST api/reauthenticate_token

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

username   string   
password   string   

Upload Remittance Transaction RFI File

requires authentication

Uploads a file required in the remittance transaction

Example request:
curl --request POST \
    "http://localhost/paywho-api-system/public/api/rfi-file/upload" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "customer_type=sender/receiver" \
    --form "field_name=IC" \
    --form "transaction_reference=CHN_C2C_ROUTING_NEW_08" \
    --form "file=@/private/var/folders/zs/28y9n8r51j343np891k8phcw0000gn/T/phpp9gY9O" 
const url = new URL(
    "http://localhost/paywho-api-system/public/api/rfi-file/upload"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('customer_type', 'sender/receiver');
body.append('field_name', 'IC');
body.append('transaction_reference', 'CHN_C2C_ROUTING_NEW_08');
body.append('file', document.querySelector('input[name="file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'http://localhost/paywho-api-system/public/api/rfi-file/upload',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'customer_type',
                'contents' => 'sender/receiver'
            ],
            [
                'name' => 'field_name',
                'contents' => 'IC'
            ],
            [
                'name' => 'transaction_reference',
                'contents' => 'CHN_C2C_ROUTING_NEW_08'
            ],
            [
                'name' => 'file',
                'contents' => fopen('/private/var/folders/zs/28y9n8r51j343np891k8phcw0000gn/T/phpp9gY9O', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/rfi-file/upload'
files = {
  'file': open('/private/var/folders/zs/28y9n8r51j343np891k8phcw0000gn/T/phpp9gY9O', 'rb')
}
payload = {
    "customer_type": "sender\/receiver",
    "field_name": "IC",
    "transaction_reference": "CHN_C2C_ROUTING_NEW_08"
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'multipart/form-data',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, files=files, data=payload)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Uploaded RFI file successfully",
    "data": ""
}
 

Example response (400):


{
    "status": "failed",
    "error": "Error occurred when validating user request",
    "error_messages": {
        "transaction_reference": [
            "The transaction_reference is required."
        ]
    },
    "data": null
}
 

Request      

POST api/rfi-file/upload

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

customer_type   string   

The customer type. Please refer to 'Request for Information (RFI) files' section for the values accepted Example: sender/receiver

field_name   string   

The field name. Please refer to 'Request for Information (RFI) files' section for the values accepted Example: IC

file   file   

The file uploaded Example: /private/var/folders/zs/28y9n8r51j343np891k8phcw0000gn/T/phpp9gY9O

transaction_reference   string   

The transaction reference id Example: CHN_C2C_ROUTING_NEW_08

Transaction status

requires authentication

Get the status of the transaction

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/get_transaction_status?transactionReference=" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/get_transaction_status"
);

const params = {
    "transactionReference": "",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/get_transaction_status',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'transactionReference' => '',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/get_transaction_status'
params = {
  'transactionReference': '',
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Retrieved transaction status successfully",
    "data": {
        "transactionReference": "B2B_BANK_TRSF_SGPTESTING323",
        "sender_full_name": "JANG JANG CORPORATE",
        "beneficiary_full_name": "EMPTY OBJECT CORPORATE",
        "payout_amount": "10 SGD",
        "fx_rate": "0.997000",
        "fees": "1 SGD",
        "collected_amount": "0.00 SGD",
        "status": "Processing",
        "compliance_status": "Compliance Pending",
        "error": null,
        "error_code": null
    }
}
 

Example response (200):


{
    "status": "success",
    "message": "Retrieved transaction status successfully",
    "data": {
        "transactionReference": "B2B_BANK_TRSF_SGPTESTING323",
        "sender_full_name": "JANG JANG CORPORATE",
        "beneficiary_full_name": "EMPTY OBJECT CORPORATE",
        "payout_amount": "10 SGD",
        "fx_rate": "0.997000",
        "fees": "1 SGD",
        "collected_amount": "0.00 SGD",
        "status": "Rejected",
        "compliance_status": "Compliance Rejected",
        "error": "The account number is wrong.",
        "error_code": "99-01"
    }
}
 

Example response (400):


{
    "status": "failed",
    "error": "Failed to retrieve transaction status",
    "error_messages": "Failed to retrieve transactions",
    "data": null
}
 

Request      

GET api/get_transaction_status

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

transactionReference   string   

Available Countries

requires authentication

Get a list of Countries available for transaction

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/get_available_countries" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/get_available_countries"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/get_available_countries',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/get_available_countries'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Retrieved available countries successfully",
    "data": [
        {
            "country": "CHN",
            "payoutMethod": {
                "id": 2,
                "description": "Unionpay Transfer"
            },
            "transferType": {
                "id": 3,
                "description": "C2C"
            }
        }
    ]
}
 

Example response (400):


{
    "status": "failed",
    "error": "Failed to retrieve available countries",
    "error_messages": "Error",
    "data": null
}
 

Request      

GET api/get_available_countries

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Check Your Wallet Balance

requires authentication

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/check_wallet_balance" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/check_wallet_balance"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/check_wallet_balance',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/check_wallet_balance'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Retrieved wallet balance successfully",
    "data": [
        {
            "balance": 9933.5426279,
            "currency": "SGD",
            "active": "1"
        }
    ]
}
 

Example response (400):


{
    "status": "failed",
    "error": "Failed to retrieve wallet balance",
    "error_messages": "Error",
    "data": null
}
 

Request      

GET api/check_wallet_balance

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

All Transactions

requires authentication

Get the list of all Transactions

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/get_all_transactions?startDate=1728630588&endDate=1728634836&itemsPerPage=20&page=1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/get_all_transactions"
);

const params = {
    "startDate": "1728630588",
    "endDate": "1728634836",
    "itemsPerPage": "20",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/get_all_transactions',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'startDate' => '1728630588',
            'endDate' => '1728634836',
            'itemsPerPage' => '20',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/get_all_transactions'
params = {
  'startDate': '1728630588',
  'endDate': '1728634836',
  'itemsPerPage': '20',
  'page': '1',
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Retrieved all transactions successfully",
    "data": [
        {
            "transactionReference": "C2B_BANK_TRSF_SGPTESTING03",
            "system_id": "PW1767846425297692",
            "data": "{\"senderFirstName\":\"JANG\",\"senderLastName\":\"HYUK\",\"senderCountry\":\"GBR\",\"senderAddress\":\"SOMEWHERE IN JANG STREET 103\",\"senderCity\":\"SOMEWHERE IN JANG STREET 103\",\"senderZipCode\":\"123222\",\"senderCorporateCity\":\"JANG CITY\",\"senderCorporateZipCode\":12345,\"senderDateOfBirth\":\"2000-01-01\",\"senderNationality\":\"GBR\",\"senderIdType\":\"1\",\"senderIdNumber\":\"A12345\",\"senderIdIssueCountry\":\"GBR\",\"senderOccupation\":\"4\",\"receiverCorporateName\":\"EMPTY OBJECT CORPORATE\",\"receiverCorporateBankAccountNumber\":\"8976789\",\"receiverCorporateId\":\"EO123\",\"receiverCorporateBankId\":\"SG_ANZ\",\"receiverCorporateBankBranchCode\":\"014\",\"receiverCorporateZipCode\":\"12345\",\"receiverCorporateAddress\":\"GASOLINE ASIA ST 84\",\"receiverCorporateCity\":\"GAS GAS\",\"receiverCorporateMobile\":\"34567890\",\"receiverCorporateType\":4,\"receiverCorporateStructure\":2,\"receiverFirstName\":\"MR PLANK\",\"transferAmount\":100,\"transactionReference\":\"C2B_BANK_TRSF_SGPTESTING03\",\"senderSourceOfFund\":2,\"purposeOfRemittance\":1,\"transferType\":3,\"payoutMethod\":1,\"payoutCurrency\":\"SGD\",\"corridor_access\":27}",
            "status": "Processing"
        }
    ]
}
 

Example response (400):


{
    "status": "failed",
    "error": "Failed to retrieve all transactions",
    "error_messages": "Error",
    "data": null
}
 

Request      

GET api/get_all_transactions

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

startDate   integer  optional  

Default will be set to the starting point of unix timestamps which corresponds to 1970-01-01 00:00:00 (UTC) Example: 1728630588

endDate   string  optional  

integer|gte:startDateTime Default will be set to the current date and time Example: 1728634836

itemsPerPage   integer  optional  

Default will be 20 Example: 20

page   integer  optional  

Default will be 1 Example: 1

Refresh Token

requires authentication

Get a new access token

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/refresh_token" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/refresh_token"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/refresh_token',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/refresh_token'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Refreshed token successfully",
    "data": {
        "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiNGUyOTA2MjkzMTRiMGYzNWVjZTY2YjdkY2JmZWVhMTlhMGViODI0ZDRmZTdlOGE2MTg4NmI0NWNjODE4ZjBiOTcwMWM3OTk5NGMwY2EzNGYiLCJpYXQiOjE2ODY4MDQxMjUuMDQ1Mzk2MDg5NTUzODMzMDA3ODEyNSwibmJmIjoxNjg2ODA0MTI1LjA0NTM5ODk1MDU3Njc4MjIyNjU2MjUsImV4cCI6MTY4NzQwODkyNS4wNDE1ODA5MTU0NTEwNDk4MDQ2ODc1LCJzdWIiOiIyMyIsInNjb3BlcyI6W119.DNKPKqrOLN7FQADGICLI4MsWMTMo_7eyw8r9__NcORhZ7RixTDgk0Q9Euu_KQ7FIWhd80FDDSlrRWnbdV6IoW8zlwxpP4DVLDX67YM-lWaiU7GEqaD7-vsX6n6OstFfh7qC5HCA8nly2VAvwJLcTB1NDE3amZifFZUhSc6z-zjHFJ7BycovWEFRY2wDIt4uDltCeSHYVEnoB6jf7T0vX7g9n_udiilkI9Wj-x2WdOI11sKTrIVzBzUunLPY01WKyjnIVIqNPsWjU-KwqVkmq6KG5zB1HwSN5yJVYVv77fVpXc-cen9vpXCafs--E1QVLvtHVihorX4nbbf6txcjSUfPaotdOZvLbyg6cxt70YE1s9v2szLF4LoaRCylxduEDoNxoIaJp1Brc1ns_HU9Fogy3pnUcm23oFcCLewKbBWLP9vM4P0rK0PSN8jMTHMDM0bkE_P4l-Qd5b_xSJcBmjJh6k7SGVsfY18hjFZwa0z82iOWgbFyzrpKUNkc8xOXldfvBKuuXfvj-1l2nTPkxrK9s-BBft2WKgAcEm1J0236IYKUEaFzpzPyziqbQoM50CJOvnzkVPX0r6m9vNBajXW5PSXX8JS0c7Ez5e-DAtJLAmGLIR0hXjRXJCLwxMhJgpd1kBFl3UrTU8pzyhb4RCs6ongt0f9NnG_y6yX9HfqE"
    }
}
 

Example response (400):


{
    "status": "failed",
    "error": "System Error while refreshing token",
    "error_messages": "Error",
    "data": null
}
 

Request      

GET api/refresh_token

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Get Fields For Country

requires authentication

Get required fields for country

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/get_fields_for_country?transferType=3&payoutMethod=1&payoutCurrency=SGD" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/get_fields_for_country"
);

const params = {
    "transferType": "3",
    "payoutMethod": "1",
    "payoutCurrency": "SGD",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/get_fields_for_country',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'transferType' => '3',
            'payoutMethod' => '1',
            'payoutCurrency' => 'SGD',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/get_fields_for_country'
params = {
  'transferType': '3',
  'payoutMethod': '1',
  'payoutCurrency': 'SGD',
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
 "status": "success",
 "message": "Retrieved all fields successfully",
 "data": [
    {
        "field_name": "senderAddress",
        "field_type": "input",
        "fixed_field_value": null,
        "field_validation": "required|regex:/^[A-Za-z0-9 .,-]+$/",
        "field_description": "Provide sender's personal or residential details as applicable"
    },
    {
        "field_name": "senderCity",
        "field_type": "input",
        "fixed_field_value": null,
        "field_validation": "required|regex:/^[A-Za-z0-9 .,-]+$/",
        "field_description": "Provide sender's personal or residential details as applicable"
    },
 ]
}
 

Example response (400):


{
    "status": "failed",
    "error": "Error occurred when validating user request",
    "error_messages": "Failed to retrieve list of country details",
    "data": null
}
 

Request      

GET api/get_fields_for_country

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

transferType   string   

string|in:1,2,3,4 1=B2B, 2=B2C, 3=C2C, 4=C2B Example: 3

payoutMethod   string   

string|in:1,2,3,4,5 1=Bank Transfer, 2=Unionpay Transfer, 3=Cash Pickup, 4=Home Delivery, 5=Alipay Example: 1

payoutCurrency   string   

string|min:3|max:3 follow the ISO 4127 standard Example: SGD

Get Exchange Rate

requires authentication

Retrieves the exchange rates of a corridor

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/get_exchange_rate?transferType=3&payoutMethod=1&payoutCurrency=SGD" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/get_exchange_rate"
);

const params = {
    "transferType": "3",
    "payoutMethod": "1",
    "payoutCurrency": "SGD",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/get_exchange_rate',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'transferType' => '3',
            'payoutMethod' => '1',
            'payoutCurrency' => 'SGD',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/get_exchange_rate'
params = {
  'transferType': '3',
  'payoutMethod': '1',
  'payoutCurrency': 'SGD',
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Retrieved exchange rate successfully",
    "data": {
        "rate": "5.238141",
        "currency_pair": "SGD:CNY"
    }
}
 

Example response (400):


{
    "status": "failed",
    "error": "Error occurred when validating user request",
    "error_messages": {
        "transferType": [
            "The selected transfer type is invalid."
        ]
    },
    "data": null
}
 

Request      

GET api/get_exchange_rate

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

transferType   string   

string|in:1,2,3,4 1=B2B, 2=B2C, 3=C2C, 4=C2B Example: 3

payoutMethod   string   

string|in:1,2,3,4,5 1=Bank Transfer, 2=Unionpay Transfer, 3=Cash Pickup, 4=Home Delivery 5=Alipay Example: 1

payoutCurrency   string   

string|min:3|max:3 follow the ISO 4217 standard Example: SGD

Send Transaction

requires authentication

Initiate a transaction after filling up the below fields.

Note :

  1. Body parameters is using SG corridor as an example.
  2. Call ‘get_fields_for_country’ endpoint to retrieve the fields required for the corridor you’re sending to.
  3. transferAmount must be in 2 d.p
Example request:
curl --request POST \
    "http://localhost/paywho-api-system/public/api/send_transaction" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"senderFirstName\": \"Harry\",
    \"senderLastName\": \"Maguire\",
    \"senderCountry\": \"GBR\",
    \"senderAddress\": \"Oxford Street\",
    \"senderCity\": \"London\",
    \"senderZipCode\": \"W1D 1BS\",
    \"senderCorporateCity\": \"London\",
    \"senderCorporateZipCode\": \"34512\",
    \"senderDateOfBirth\": \"2000-01-01\",
    \"senderNationality\": \"GBR\",
    \"senderIdType\": \"1\",
    \"senderIdNumber\": \"234543\",
    \"senderIdIssueCountry\": \"GBR\",
    \"senderOccupation\": \"4\",
    \"receiverCorporateName\": \"Nestle Pvt Ltd\",
    \"receiverCorporateBankAccountNumber\": \"8976789\",
    \"receiverCorporateId\": \"EO123\",
    \"receiverCorporateBankId\": \"SG_ANZ\",
    \"receiverCorporateBankBranchCode\": \"014\",
    \"receiverCorporateZipCode\": \"23881\",
    \"receiverCorporateAddress\": \"437 Orchard Road,\",
    \"receiverCorporateCity\": \"singapore\",
    \"receiverCorporateMobile\": \"34567890\",
    \"receiverCorporateType\": \"4\",
    \"receiverCorporateStructure\": \"2\",
    \"receiverFirstName\": \"MR Chang\",
    \"receiverLastName\": \"Hung\",
    \"transferAmount\": \"99.00\",
    \"transactionReference\": \"C2B_BANK_TRSF_SGP_TESTING_0121\",
    \"senderSourceOfFund\": \"2\",
    \"purposeOfRemittance\": \"1\",
    \"transferType\": \"3\",
    \"payoutMethod\": \"1\",
    \"payoutCurrency\": \"SGD\"
}"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/send_transaction"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "senderFirstName": "Harry",
    "senderLastName": "Maguire",
    "senderCountry": "GBR",
    "senderAddress": "Oxford Street",
    "senderCity": "London",
    "senderZipCode": "W1D 1BS",
    "senderCorporateCity": "London",
    "senderCorporateZipCode": "34512",
    "senderDateOfBirth": "2000-01-01",
    "senderNationality": "GBR",
    "senderIdType": "1",
    "senderIdNumber": "234543",
    "senderIdIssueCountry": "GBR",
    "senderOccupation": "4",
    "receiverCorporateName": "Nestle Pvt Ltd",
    "receiverCorporateBankAccountNumber": "8976789",
    "receiverCorporateId": "EO123",
    "receiverCorporateBankId": "SG_ANZ",
    "receiverCorporateBankBranchCode": "014",
    "receiverCorporateZipCode": "23881",
    "receiverCorporateAddress": "437 Orchard Road,",
    "receiverCorporateCity": "singapore",
    "receiverCorporateMobile": "34567890",
    "receiverCorporateType": "4",
    "receiverCorporateStructure": "2",
    "receiverFirstName": "MR Chang",
    "receiverLastName": "Hung",
    "transferAmount": "99.00",
    "transactionReference": "C2B_BANK_TRSF_SGP_TESTING_0121",
    "senderSourceOfFund": "2",
    "purposeOfRemittance": "1",
    "transferType": "3",
    "payoutMethod": "1",
    "payoutCurrency": "SGD"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'http://localhost/paywho-api-system/public/api/send_transaction',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => [
            'senderFirstName' => 'Harry',
            'senderLastName' => 'Maguire',
            'senderCountry' => 'GBR',
            'senderAddress' => 'Oxford Street',
            'senderCity' => 'London',
            'senderZipCode' => 'W1D 1BS',
            'senderCorporateCity' => 'London',
            'senderCorporateZipCode' => '34512',
            'senderDateOfBirth' => '2000-01-01',
            'senderNationality' => 'GBR',
            'senderIdType' => '1',
            'senderIdNumber' => '234543',
            'senderIdIssueCountry' => 'GBR',
            'senderOccupation' => '4',
            'receiverCorporateName' => 'Nestle Pvt Ltd',
            'receiverCorporateBankAccountNumber' => '8976789',
            'receiverCorporateId' => 'EO123',
            'receiverCorporateBankId' => 'SG_ANZ',
            'receiverCorporateBankBranchCode' => '014',
            'receiverCorporateZipCode' => '23881',
            'receiverCorporateAddress' => '437 Orchard Road,',
            'receiverCorporateCity' => 'singapore',
            'receiverCorporateMobile' => '34567890',
            'receiverCorporateType' => '4',
            'receiverCorporateStructure' => '2',
            'receiverFirstName' => 'MR Chang',
            'receiverLastName' => 'Hung',
            'transferAmount' => '99.00',
            'transactionReference' => 'C2B_BANK_TRSF_SGP_TESTING_0121',
            'senderSourceOfFund' => '2',
            'purposeOfRemittance' => '1',
            'transferType' => '3',
            'payoutMethod' => '1',
            'payoutCurrency' => 'SGD',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/send_transaction'
payload = {
    "senderFirstName": "Harry",
    "senderLastName": "Maguire",
    "senderCountry": "GBR",
    "senderAddress": "Oxford Street",
    "senderCity": "London",
    "senderZipCode": "W1D 1BS",
    "senderCorporateCity": "London",
    "senderCorporateZipCode": "34512",
    "senderDateOfBirth": "2000-01-01",
    "senderNationality": "GBR",
    "senderIdType": "1",
    "senderIdNumber": "234543",
    "senderIdIssueCountry": "GBR",
    "senderOccupation": "4",
    "receiverCorporateName": "Nestle Pvt Ltd",
    "receiverCorporateBankAccountNumber": "8976789",
    "receiverCorporateId": "EO123",
    "receiverCorporateBankId": "SG_ANZ",
    "receiverCorporateBankBranchCode": "014",
    "receiverCorporateZipCode": "23881",
    "receiverCorporateAddress": "437 Orchard Road,",
    "receiverCorporateCity": "singapore",
    "receiverCorporateMobile": "34567890",
    "receiverCorporateType": "4",
    "receiverCorporateStructure": "2",
    "receiverFirstName": "MR Chang",
    "receiverLastName": "Hung",
    "transferAmount": "99.00",
    "transactionReference": "C2B_BANK_TRSF_SGP_TESTING_0121",
    "senderSourceOfFund": "2",
    "purposeOfRemittance": "1",
    "transferType": "3",
    "payoutMethod": "1",
    "payoutCurrency": "SGD"
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, json=payload)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Transaction sent successfully",
    "data": {
        "message": "Processing Transaction. ",
        "transactionReference": "C2B_BANK_TRSF_SdssdsGP_TESTING_0121",
        "system_id": "PW1768660907084700",
        "approximate_fees": {
            "SGD_payout_amount": "10.00 SGD",
            "SGD:SGD": "0.997000",
            "SGD_collected_amount": "10.03 SGD",
            "SGD_collected_fees": "1.00 SGD",
            "SGD_total_collected_amount": "11.03 SGD"
        },
        "before_balance": "9977.66 SGD",
        "after_balance": "9966.63 SGD"
    }
}
 

Example response (400):


{
    "status": "failed",
    "error": "Failed to send transaction",
    "error_messages": "Duplicate transaction reference exists. Please use a different reference ID.",
    "data": null
}
 

Request      

POST api/send_transaction

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

senderFirstName   string   

Example: Harry

senderLastName   string   

Example: Maguire

senderCountry   string|alpha_three_code   

follow the ISO 3166 standard Example: GBR

senderAddress   string   

Example: Oxford Street

senderCity   string   

Example: London

senderZipCode   string   

Example: W1D 1BS

senderCorporateCity   string   

Example: London

senderCorporateZipCode   string   

Example: 34512

senderDateOfBirth   string   

format-YYYY-MM-DD Example: 2000-01-01

senderNationality   string|alpha_three_code   

follow the ISO 3166 standard Example: GBR

senderIdType   string|in:1,2,3,4   

1=Cashless Retailers, 2=Online Small Retailers, 3=Restaurants, Cafes and Supermarkets, 4=Importers/Exporters Example: 1

senderIdNumber   string   

Example: 234543

senderIdIssueCountry   string|alpha_three_code   

follow the ISO 3166 standard Example: GBR

senderOccupation   string|in:1,2,3,4,5,6,7,8,9   

1=PMET, 2=Blue Collared Staff, 3=Sales/Marketing Staff, 4=IT/Cyber Security Staff, 5=Student, 6=Engineer, 7=Customer Service, 8=Business Owner, 9=Retired Example: 4

receiverCorporateName   string   

Example: Nestle Pvt Ltd

receiverCorporateBankAccountNumber   string   

Example: 8976789

receiverCorporateId   string   

Example: EO123

receiverCorporateBankId   string   

Example: SG_ANZ

receiverCorporateBankBranchCode   string   

Example: 014

receiverCorporateZipCode   string   

Example: 23881

receiverCorporateAddress   string   

Example: 437 Orchard Road,

receiverCorporateCity   string   

Example: singapore

receiverCorporateMobile   string   

Example: 34567890

receiverCorporateType   string|in:1,2,3,4   

1=Cashless Retailers, 2=Online Small Retailers, 3=Restaurants, Cafes and Supermarkets, 4=Importers/Exporters Example: 4

receiverCorporateStructure   string|in:1,2,3,4,5   

1=Private/Public Limited Company, 2=Charity Organisation, 3=Trust, 4=Company registered in Tax Haven, 5=Company with PEP Ownership Example: 2

receiverFirstName   string   

Example: MR Chang

receiverLastName   string   

Example: Hung

transferAmount   string   

Example: 99.00

transactionReference   string   

Example: C2B_BANK_TRSF_SGP_TESTING_0121

senderSourceOfFund   string|in:1,2,3,4,5,6   

1=Salary, 2=Insurance Premiums, 3=Savings, 4=Investment Returns, 5=Sale of Property, 6=Business Proceeds Example: 2

purposeOfRemittance   string   

1=Family Maintenance, 2=Savings, 3=Repatriation of Salary, 4=Purchase of Property, 5=Purchase of Goods/Services, 6=Medical Bills, 7=Tuition Bill, 8=Rental Bills, 9=Other Bills, 10=Investment, 11=Tax Payment, 12=Insurance Payment, 13=Loan Payment Example: 1

transferType   string|in:1,2,3,4   

1=B2B, 2=B2C, 3=C2C, 4=C2B Example: 3

payoutMethod   string|in:1,2,3,4,5   

1=Bank Transfer, 2=Unionpay Transfer, 3=Cash Pickup, 4=Home Delivery, 5=Alipay Example: 1

payoutCurrency   string|min:3|max:3   

follow the ISO 4217 standard Example: SGD

List Of Banks

requires authentication

Get a list of available Banks

Note: This endpoint can be used to fill in the bankId required in ‘send_transaction’ endpoint.

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/get_list_of_banks?transferType=3&payoutMethod=1&payoutCurrency=SGD" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/get_list_of_banks"
);

const params = {
    "transferType": "3",
    "payoutMethod": "1",
    "payoutCurrency": "SGD",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/get_list_of_banks',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'query' => [
            'transferType' => '3',
            'payoutMethod' => '1',
            'payoutCurrency' => 'SGD',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/get_list_of_banks'
params = {
  'transferType': '3',
  'payoutMethod': '1',
  'payoutCurrency': 'SGD',
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers, params=params)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Retrieved bank list for country successfully",
    "data": []
}
 

Example response (400):


{
    "status": "failed",
    "error": "Error occurred when validating user request",
    "error_messages": "Failed to retrieve list of country details",
    "data": null
}
 

Request      

GET api/get_list_of_banks

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

transferType   string   

string|in:1,2,3,4 1=B2B, 2=B2C, 3=C2C, 4=C2B Example: 3

payoutMethod   string   

string|in:1,2,3,4,5 1=Bank Transfer, 2=Unionpay Transfer, 3=Cash Pickup, 4=Home Delivery, 5=Alipay Example: 1

payoutCurrency   string   

string|min:3|max:3 follow the ISO 4217 standard Example: SGD

Get Bulk Exchange Rates

requires authentication

Retrieves the exchange rates of all corridors

Example request:
curl --request GET \
    --get "http://localhost/paywho-api-system/public/api/fx-rates" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "http://localhost/paywho-api-system/public/api/fx-rates"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->get(
    'http://localhost/paywho-api-system/public/api/fx-rates',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/fx-rates'
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'application/json',
  'Accept': 'application/json'
}

response = requests.request('GET', url, headers=headers)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Retrieved exchange rate successfully",
    "data": [
        {
            "country_alpha_3_code": "IND",
            "currency_pair": "SGD:INR",
            "fx_rate": "60.55925656",
            "payout_method": "Bank Transfer",
            "transfer_type": "B2C"
        },
        {
            "country_alpha_3_code": "IND",
            "currency_pair": "SGD:INR",
            "fx_rate": "60.43777360",
            "payout_method": "Bank Transfer",
            "transfer_type": "C2B"
        }
    ]
}
 

Example response (400):


{
    "status": "failed",
    "error": "Failed to retrieve exchange rate",
    "error_messages": "Failed to retrieve wallet",
    "data": null
}
 

Request      

GET api/fx-rates

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: application/json

Accept      

Example: application/json

Topup Wallet

requires authentication

Initiate a fund topup request.

Example request:
curl --request POST \
    "http://localhost/paywho-api-system/public/api/wallet_topup_request" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: multipart/form-data" \
    --header "Accept: application/json" \
    --form "amount=100.00" \
    --form "file=@/private/var/folders/zs/28y9n8r51j343np891k8phcw0000gn/T/phpYOKjaC" 
const url = new URL(
    "http://localhost/paywho-api-system/public/api/wallet_topup_request"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('amount', '100.00');
body.append('file', document.querySelector('input[name="file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$response = $client->post(
    'http://localhost/paywho-api-system/public/api/wallet_topup_request',
    [
        'headers' => [
            'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
            'Content-Type' => 'multipart/form-data',
            'Accept' => 'application/json',
        ],
        'multipart' => [
            [
                'name' => 'amount',
                'contents' => '100.00'
            ],
            [
                'name' => 'file',
                'contents' => fopen('/private/var/folders/zs/28y9n8r51j343np891k8phcw0000gn/T/phpYOKjaC', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json

url = 'http://localhost/paywho-api-system/public/api/wallet_topup_request'
files = {
  'file': open('/private/var/folders/zs/28y9n8r51j343np891k8phcw0000gn/T/phpYOKjaC', 'rb')
}
payload = {
    "amount": "100.00"
}
headers = {
  'Authorization': 'Bearer {YOUR_AUTH_KEY}',
  'Content-Type': 'multipart/form-data',
  'Accept': 'application/json'
}

response = requests.request('POST', url, headers=headers, files=files, data=payload)
response.json()

Example response (200):


{
    "status": "success",
    "message": "Request for funds top up sent successfully.",
    "data": true
}
 

Example response (400):


{
    "status": "failed",
    "error": "Failed to topping up",
    "error_messages": "Error",
    "data": null
}
 

Request      

POST api/wallet_topup_request

Headers

Authorization      

Example: Bearer {YOUR_AUTH_KEY}

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

amount   regex:/^[0-9]+(\.[0-9]{1,2})?$/|gt:0   

Example: 100.00

file   file   

The file uploaded Example: /private/var/folders/zs/28y9n8r51j343np891k8phcw0000gn/T/phpYOKjaC