Introduction
API reference for FPX Exchange server.
This application uses;
♦ Asia/Kuala_Lumpur
as the timezone for transaction-related parameters such as transaction_date_time
.
♦ UTC
as the application timezone for timestamp-related parameters such as created_at
, updated_at
and deleted_at
.
♦ MYR
as the currency.
You are required to specify Accept
header like below;
Accept : application/json
You may perform testing by using standard application software like Postman
and Insomnia
.
As a quick test, just open your web browser and head to https://exchange.kineticpay.my/test/
You may refer that source code for better understanding.
We have standardized most of the error response with these two (3) parameters;
1) fpx_main_response
2) fpx_exchange_response
3) fpx_exchange_script
(shown only when you set FPX_EXCHANGE_DEBUG=true
in .env
file)
fpx_main_response
is the error message from FPX Main server while fpx_exchange_response
is the error message from this application.
fpx_exchange_script
is the script that trigger the error. This information will make you convenient to perform debugging process.
Base URL
https://exchange.kineticpay.my
Authenticating requests
Authenticate requests to this API's endpoints by sending an Authorization
header with the value "Bearer {YOUR_AUTH_KEY}"
.
All authenticated endpoints are marked with a requires authentication
badge in the documentation below.
IMPORTANT!!!
Make sure that you have setup Public Key Infrastructure (PKI) components properly before making API calls.
Only users with FPX Merchant role can make API call. Get your user Personal Access Token (PAT) by clicking on Create PAT link or icon at Users record listing module.
Alternatively you may automate the process by using Authentication section.
Authentication
User authentication.
Authenticate a user to this application and get a Personal Access Token (PAT).
Usage;
1. Provide your credential that was registered at this application. Expecting email
and password
.
2. Copy personal_access_token
and save that information securely. Note that you need to generate another PAT if you lost this one.
3. Provide that PAT as Bearer Token
to perform integration to this application.
By default, a PAT is valid up to 1 year. You may automate the renewal process by checking the expires_at
parameter from the response.
Example request:
$client = new \GuzzleHttp\Client();
$response = $client->post(
'https://exchange.kineticpay.my/api/login',
[
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'email' => 'support@k-ict.org',
'password' => 'p4$sW0rD',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://exchange.kineticpay.my/api/login'
payload = {
"email": "support@k-ict.org",
"password": "p4$sW0rD"
}
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()
curl --request POST \
"https://exchange.kineticpay.my/api/login" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"support@k-ict.org\",
\"password\": \"p4$sW0rD\"
}"
const url = new URL(
"https://exchange.kineticpay.my/api/login"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "support@k-ict.org",
"password": "p4$sW0rD"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
Example response (200, Success):
{
"personal_access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiOGE3NGEzODAxZjBiNThjZmVkYzAyNTc1MDRmZjA0MjQ3N2YzOWRkMzY0MzA2MzVhMDI2Y2QyYTkxZjg2NDkyMGMwYTRlMjRjOGVmYzYwNjMiLCJpYXQiOjE2NTQwOTM4NTIuNzU2MTQ2LCJuYmYiOjE2NTQwOTM4NTIuNzU2MTY4LCJleHAiOjE2ODU2Mjk4NTIuNzQxNzk2LCJzdWIiOiIxIiwic2NvcGVzIjpbIioiXX0.0PReaRRy71L8MM8JfDWC53ZXpv4Ycwz6KfHVQz9PB68DKXmrrs4tu-5cx0HHQHPAxWQTINbNQOujFer8v5fRDrFg3Dn6dL_ReofHhjM1xSv0A1oQRWXwRWFu9FgLw6imoVR3ibiNOHxP4DwOtPaeU-o7NrM8WXy4Cj_R5hKGlCbyliayVaLKmZRgqPzo4imsIicDa_7GI7FrPEmGcbt9iMMreFccRYEMPTE1KSM1f2e4_0l1rt_LdrrhVHV0gDa5GUc_29rSYTdOITjAjYJnCH9SFem6RIS6gmoqwnV4Ldj6lRr2FmK_KC2hDLrxmj8GYDMnxWtptjSvjMp7Jim5CgsyHYl4u7c0ljeY7KgZuuIOTR1TVxrrP5IezHDt9uDN7r7yPzdVsAqzd46ZOGLHRgM4gs4vOvf50PSOhA8jQz5K8FXssRC4bSo-Kkpal66u-2Jh_sjfSfUqA8ZIwQq6BBVl5Q1162ktE-1MpnqEULYbLcsUHs2qB9FTdLd7Cd-y7FZNsaNWvRbaZ5-UoaULfGcilqjj-u2A2tSvm_AJVZOgVxGXx31aOW81HN2aSZ8mfyWIJEMRmFRQ3GlwGBjxIdTKCF_OcBjzPybG3ND7KSw190Bp0RLEZ5-c7pOI9qP7eIm3rGd6mn4fWltF6TCmWnEvOyE7AUfaG1Bi0FkLsGQ",
"created_at": "2022-06-01 14:30:52",
"updated_at": "2022-06-01 14:30:52",
"expires_at": "2023-06-01T14:30:52.000000Z",
"id": "8a74a3801f0b58cfedc0257504ff042477f39dd36430635a026cd2a91f864920c0a4e24c8efc6063"
}
Example response (422, Unprocessible Entity):
{
"message": The email field is required. (and 1 more error)",
"errors": {
"email": [
"The email field is required."
],
"password": [
"The password field is required."
]
}
}
Example response (401, Unauthorized):
{
"message": "Authentication failed.",
"errors": {
"fpx_main_response": [],
"fpx_exchange_response": [
"Invalid credential."
]
}
}
Received response:
Request failed with error:
Post-transaction
Transaction receipt.
Capture FPX transaction response sent by FPX main server after making transaction.
IMPORTANT! Make sure that you have registered these URL at PayNet;
Indirect URL: https://exchange.kineticpay.my/fpx_authorization_confirmations/indirect
Direct URL: https://exchange.kineticpay.my/fpx_authorization_confirmations/direct
Usage;
1. Create a new transaction by using calling any API in Pre-transaction section. Set receipt_url and transaction_update_url to redirect to this application.
2. Complete the transaction.
3. Decode the encoded_transaction_data (JSON format) obtained from API response, and display record -> transaction_status
as the transaction status to the buyer. Alternatively decrypt the encrypted_transaction_data contents using SECRET_KEY
constant defined in .env
for data integrity purposes.
Refer FPX documents regarding to FPX receipt page compliance.
You are unable to perform the test by using this Try it out! features since the POST parameters from PayNet are subject to Private and Confidential. Please refer FPX documents and use other tools like Postman
or Imsonia
to test.
Example request:
$client = new \GuzzleHttp\Client();
$response = $client->post(
'https://exchange.kineticpay.my/fpx_acs',
[
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://exchange.kineticpay.my/fpx_acs'
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers)
response.json()
curl --request POST \
"https://exchange.kineticpay.my/fpx_acs" \
--header "Content-Type: application/json" \
--header "Accept: application/json"
const url = new URL(
"https://exchange.kineticpay.my/fpx_acs"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());
Example response (200, Success):
<form id="366b8195e7d3b74b042d78d474a4cbcd" method="post" action="https://shopping-cart.cloud.org.my/payment_receipt">
<input name="encoded_transaction_data" type="hidden" value="{"record":{"order_number":"-test-v2-1-655-300-095-509489","order_description":"-test payment-","order_currency":"MYR","order_amount":"2.00","merchant_name":"KICT","buyer_name":"-test buyer-","buyer_email":"support@k-ict.org","buyer_bank_name":"SBI Bank A","buyer_bank_code":"TEST0021","exchange_order_number":"v2-1-655-300-096-294356","show_custom_buyer_info_at_landing_page":"1","custom_buyer_name":"custom buyer name","custom_buyer_email":"alt.email@cloud.org.my","custom_buyer_personal_info":{"gender":"male","date_of_birth":"01\/01\/2001","phone_numbers":{"office":"+60389595505","mobile":"+60146764788"},"address":{"billing":"Level 15 DPulze, Lingkaran Cyber Point Timur, Cyber 12, Cyberjaya, 63000 Selangor, MY","shipping":"Jabatan Perdana Menteri, Setia Perdana 8, Kompleks Setia Perdana, Pusat Pentadbiran Kerajaan Persekutuan, 62502 Putrajaya, Malaysia"}},"custom_order_description":{"order_items":{"laptop":{"Acer":{"Chromebook":{"Swift 3 - SF314-43-R9GU":{"qty":"3","unit_price":"3999","total_price":"11997"},"Swift 3 - SF314-43-R6WW":{"qty":"2","unit_price":"3299","total_price":"6598"}}}}}},"html_form":false,"transaction_status":"Successful","transaction_status_code":"00","transaction_status_description":"Approved","transaction_id":"2206152135040137","transaction_date_time":"2022-06-15 21:35:04","payment_model":"b2c"}}">
<input name="encrypted_transaction_data" type="hidden" value="eyJpdiI6ImRjdnRtWnJYTTlJckVHN0pSZUFDSWc9PSIsInZhbHVlIjoiK2hKYUVnQmdVb3JtOGtORVJrZE1Xc3Q0NjVYaG9iRjgrc2xzZkNvNUFWZWp5bVZ0NVRoYnRBYmt1YWVZTVc4S243UU8vbUVuY3owNDFJelV0THV1YmhnUmhRWW16T3FlZW9BTmV0ejBjTmVyWVRFMWNvU2pxdkFiYmxzRDN3VVRDSkh4c2dUVGZKL0kxWHNocDdueWhUcUxacW0rQWhVbGlJWmphVmxTNStJaC8va0ljNkFPTmZoZjlSWjJxYVRNT2YyazZScVdlamwwKzhzajMzczBGZjBScExIZHBqdGp3RDl1SGgxVXZVc1JQZWNxQmRrNjFIUzFKNkE2MkhHQlRKN0FRMDhyeEZNYlpyZXl6eEdqSXNSdzh6dUQ2YVJ0aDl6Y1RRU1lOcWRHU2Iwb3hSSWpBUCtIYW9xb2Q4VzVSL0k1YklDQ1RHNnV4Y3kySk1ibGtaaDBya3Y1R0VVdXRuTUJaUm5URUtEVWNpZ29VdnlQMm9PMG1sN1ZLbUp3V0JSTUZrYStUUUx6RWZsMTVzQjdibXBUMVZ0dGttbjE5ZGdhTHNYRDBuOFV3OExlM0ZodVo5MlBMSTRzWDdsSmJzNzBCS3ZCUkpFdlRsbjBPeU9tUkpEYkVYMFZuT2FxWmlRZWxHcmJXYXIrOGFxc3hoVEwyaExOdkMvalZsMmNaQjUzQVR1T0l4WUJLU0pKU2xmOENDQVNaSXhYSEFzbTFRQjFrSklWcXN5U0w0cTR5MWlpb2xZSTkwRW5neHdUUjNHRmVuOWxIcnd3SHo5UnRTMFpVdHdPNDQ2T1R5MnhHcHNTcTA4eVdvRklCbkFOQmV4bzZzS1puMFhvSWhzdTQvRnZlVWlZYUd6Z2xKNWwzMGs1TE1IdkZwdjVqOVRYSHpia0VHL1hhODFZSXBFVmVJVE8rMGNTTVoyczNTeHowNE1zdTB6UmdFR0FLR1ppNUVtMjJXUE5idEZvZzcyNDNBUXRnTTZBUEVNK1ZxZzFNZUxCNS91ZEFGR25VU3ZZMS91ZWx5WjhNZndVbFpQZGVjaFUrbnB5dit4UFVaZTFxZ0dZOVkzQlV5N28rM3NWd1FGR0h4bWVkSE1vTHpmSzVDdkF5aWk2NWxZS1dBWHNiczBpdmNoUkdzRHp1KzdZd2RWUVlkVUxmTHV0SWhKSHpNVStvVzFLRk9NVE5RRndSY29uOGJtZXYxZnNsYXVjTjh0dmw1WHpDYzFtRTlJUzV6Yy9sQkpYVkJOeXVKUkJRdWtJdHNHU1hIeFRtVFBuNzc1NWs3Q2ZUSDJzNWoyZS9ZKyszVnVibTdOdTB3eGRabVFSUkluYTlYSDdJSTdKVzRLSUp1Slg2RE8ya2QyMWRiaktjWFVNb3ZneFJpZGZIRDhITFlsRUl6Q29DUElWSThvWUZwUy80NHc9IiwibWFjIjoiZGEyMDc2NmI4MThhNmFhNWJmMDRhZDUyNmY0ODgyMDJlYTkyZDlmYWIxNDk1ZDA0ZTkxZjE0NWRhMTFmYTc3MSIsInRhZyI6IiJ9">
<input name="receipt_url" type="hidden" value="https://shopping-cart.cloud.org.my/payment_receipt">
<input name="hide_page_header" type="hidden" value="1">
</form>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
$('#animatedLoader').show();
document.getElementById('366b8195e7d3b74b042d78d474a4cbcd').submit();
});
</script>
Example response (404, No transaction found):
{
"message": "No associated FPX AR found"
}
Received response:
Request failed with error:
Re-query FPX transaction status.
requires authentication
Re-query FPX transaction status request to Exchange server.
Usage;
1. Create an HTML form like example below;
<form method="POST" action="script_to_requery_transaction.php">
[display all parameters as input fields]
<button type="submit" value="Proceed">
</form>
2. Call this API in script_to_requery_transaction.php
3. Capture API response as post-transaction data. Update the associated order in local database.
4. Simply display the record obtained from API response as the transaction status to the buyer. Alternatively decrypt the encrypted_transaction_data contents using SECRET_KEY
constant defined in .env
with AES-128-CBC cipher for data integrity purposes.
Your script_to_requery_transaction.php
should be like this;
<?php
# Step 1 of 4: Make API call.
# Step 2 of 4: Capture API response.
# Step 3 of 4: Handle exceptions.
# Step 4 of 4: Display the record contents from API response.
Refer FPX documents regarding to FPX receipt page compliance.
Pre-transaction
Make FPX bank list enquiry.
requires authentication
Make FPX bank list enquiry with its availability request to FPX Exchange server. You should call this API if you wish to display self-hosted FPX landing page using fpx_authorization_requests.
Usage;
1. Call this API on the FPX landing page after the buyer chose FPX at the checkout page.
2. Prepare an HTML dropdown like below;
<select name="banks_list" required>
<option value="bank_code_hashed">bank_display_name</option>
</select>
Display buyer bank selection like this;
Refer FPX documents regarding to FPX bank selection listing and landing page compliance.
Example request:
$client = new \GuzzleHttp\Client();
$response = $client->post(
'https://exchange.kineticpay.my/fpx_banks_list_enquiries',
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'payment_model' => 'b2c',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://exchange.kineticpay.my/fpx_banks_list_enquiries'
payload = {
"payment_model": "b2c"
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()
curl --request POST \
"https://exchange.kineticpay.my/fpx_banks_list_enquiries" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"payment_model\": \"b2c\"
}"
const url = new URL(
"https://exchange.kineticpay.my/fpx_banks_list_enquiries"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"payment_model": "b2c"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
Example response (200, Success):
{
"record": {
"fpx_banks_list_availability": [
{
"bank_display_name": "ABB0234",
"bank_name": "ABB0234",
"bank_code": "ABB0234",
"bank_code_hashed": "a1ff1c836eb71209cf64935041f8e993",
"bank_availability": 1
},
{
"bank_display_name": "Affin Bank",
"bank_name": "Affin Bank Berhad",
"bank_code": "ABB0233",
"bank_code_hashed": "472e729c398dbc372d96f5d852393b76",
"bank_availability": 0
},
{
"bank_display_name": "AGRO01",
"bank_name": "AGRO01",
"bank_code": "AGRO01",
"bank_code_hashed": "6f692c003561e3c52f0d993805b6be01",
"bank_availability": 1
},
]
}
}
Example response (422, Unprocessible Entity):
{
"message": "The given data was invalid.",
"errors": {
"payment_model": [
"The selected payment model is invalid."
]
}
}
Received response:
Request failed with error:
Display FPX landing page.
requires authentication
Display the built-in FPX Exchange landing page to the buyer.
Notes: You may test this endpoint using Postman by choosing Body > raw with JSON (application/json) since certain parameters are using array.
Usage;
1. Create a CURL request like the example.
2. Capture API response as pre-transaction data. Note that you need to use order_number along with exchange_order_number to perform transaction status re-query later.
3. Render the html contents obtained from the response to display FPX landing page.
Your script_to_display_fpx_landing_page.php
should be like this;
<?php
# Step 1 of 4: Make API call.
# Step 2 of 4: Capture API response.
# Step 3 of 4: Handle exceptions.
# Step 4 of 4: Render HTML contents from API response.
Refer FPX documents regarding to FPX landing page compliance.
Example request:
$client = new \GuzzleHttp\Client();
$response = $client->post(
'https://exchange.kineticpay.my/fpx_landing_page',
[
'headers' => [
'Authorization' => 'Bearer {YOUR_AUTH_KEY}',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'order_number' => 'KICT-Invoice/2021/03/01234',
'order_description' => 'FPX Online Payment',
'order_amount' => '1234.56',
'buyer_name' => 'Ahmad Fazli Ismail',
'buyer_email' => 'sales@k-ict.org',
'receipt_url' => 'https://shopping-cart.cloud.org.my/orders/888',
'transaction_update_url' => '<?php echo route(\'fpx_payments.update\'); ?>',
'show_custom_buyer_info_at_landing_page' => true,
'custom_buyer_name' => 'Fazli',
'custom_buyer_email' => 'fazli@cloud.org.my',
'custom_buyer_personal_info' => [
'gender' => 'male',
'date_of_birth' => '2001-01-01',
'phone_number' => [
'office' => '+60389595505',
'mobile' => '+60146764788',
],
'address' => [
'billing' => 'Level 15 DPulze, Lingkaran Cyber Point Timur, Cyber 12, Cyberjaya, 63000 Selangor, MY',
'shipping' => 'Jabatan Perdana Menteri, Setia Perdana 8, Kompleks Setia Perdana, Pusat Pentadbiran Kerajaan Persekutuan, 62502 Putrajaya, Malaysia',
],
],
'custom_order_data' => [
'purchase_order_ref_number' => 'PO/KICT/2022-00234',
'quotation_ref_number' => '2022/01/00088',
'po_date' => '2020-05-13',
'items' => [
'laptop' => [
[
'brand' => 'Acer',
'series' => 'Chromebook',
'model' => 'C733-C8F7',
'qty' => 25,
'unit_price' => 1349.0,
'total_price' => 33725.0,
],
[
'brand' => 'Apple',
'series' => 'Macbook',
'model' => 'M1 Pro 512GB SSD Storage',
'qty' => 15,
'unit_price' => 8799.0,
'total_price' => 131985.0,
],
],
'smartphone' => [
'brand' => 'Apple',
'series' => 'iPhone',
'model' => 'iPhone 13 Pro',
'qty' => 5,
'unit_price' => 4899.0,
'total_price' => 24495.0,
],
],
'grandtotal' => 190205.0,
],
'html_form' => true,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));
import requests
import json
url = 'https://exchange.kineticpay.my/fpx_landing_page'
payload = {
"order_number": "KICT-Invoice\/2021\/03\/01234",
"order_description": "FPX Online Payment",
"order_amount": "1234.56",
"buyer_name": "Ahmad Fazli Ismail",
"buyer_email": "sales@k-ict.org",
"receipt_url": "https:\/\/shopping-cart.cloud.org.my\/orders\/888",
"transaction_update_url": "<?php echo route('fpx_payments.update'); ?>",
"show_custom_buyer_info_at_landing_page": true,
"custom_buyer_name": "Fazli",
"custom_buyer_email": "fazli@cloud.org.my",
"custom_buyer_personal_info": {
"gender": "male",
"date_of_birth": "2001-01-01",
"phone_number": {
"office": "+60389595505",
"mobile": "+60146764788"
},
"address": {
"billing": "Level 15 DPulze, Lingkaran Cyber Point Timur, Cyber 12, Cyberjaya, 63000 Selangor, MY",
"shipping": "Jabatan Perdana Menteri, Setia Perdana 8, Kompleks Setia Perdana, Pusat Pentadbiran Kerajaan Persekutuan, 62502 Putrajaya, Malaysia"
}
},
"custom_order_data": {
"purchase_order_ref_number": "PO\/KICT\/2022-00234",
"quotation_ref_number": "2022\/01\/00088",
"po_date": "2020-05-13",
"items": {
"laptop": [
{
"brand": "Acer",
"series": "Chromebook",
"model": "C733-C8F7",
"qty": 25,
"unit_price": 1349,
"total_price": 33725
},
{
"brand": "Apple",
"series": "Macbook",
"model": "M1 Pro 512GB SSD Storage",
"qty": 15,
"unit_price": 8799,
"total_price": 131985
}
],
"smartphone": {
"brand": "Apple",
"series": "iPhone",
"model": "iPhone 13 Pro",
"qty": 5,
"unit_price": 4899,
"total_price": 24495
}
},
"grandtotal": 190205
},
"html_form": true
}
headers = {
'Authorization': 'Bearer {YOUR_AUTH_KEY}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request('POST', url, headers=headers, json=payload)
response.json()
curl --request POST \
"https://exchange.kineticpay.my/fpx_landing_page" \
--header "Authorization: Bearer {YOUR_AUTH_KEY}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"order_number\": \"KICT-Invoice\\/2021\\/03\\/01234\",
\"order_description\": \"FPX Online Payment\",
\"order_amount\": \"1234.56\",
\"buyer_name\": \"Ahmad Fazli Ismail\",
\"buyer_email\": \"sales@k-ict.org\",
\"receipt_url\": \"https:\\/\\/shopping-cart.cloud.org.my\\/orders\\/888\",
\"transaction_update_url\": \"<?php echo route(\'fpx_payments.update\'); ?>\",
\"show_custom_buyer_info_at_landing_page\": true,
\"custom_buyer_name\": \"Fazli\",
\"custom_buyer_email\": \"fazli@cloud.org.my\",
\"custom_buyer_personal_info\": {
\"gender\": \"male\",
\"date_of_birth\": \"2001-01-01\",
\"phone_number\": {
\"office\": \"+60389595505\",
\"mobile\": \"+60146764788\"
},
\"address\": {
\"billing\": \"Level 15 DPulze, Lingkaran Cyber Point Timur, Cyber 12, Cyberjaya, 63000 Selangor, MY\",
\"shipping\": \"Jabatan Perdana Menteri, Setia Perdana 8, Kompleks Setia Perdana, Pusat Pentadbiran Kerajaan Persekutuan, 62502 Putrajaya, Malaysia\"
}
},
\"custom_order_data\": {
\"purchase_order_ref_number\": \"PO\\/KICT\\/2022-00234\",
\"quotation_ref_number\": \"2022\\/01\\/00088\",
\"po_date\": \"2020-05-13\",
\"items\": {
\"laptop\": [
{
\"brand\": \"Acer\",
\"series\": \"Chromebook\",
\"model\": \"C733-C8F7\",
\"qty\": 25,
\"unit_price\": 1349,
\"total_price\": 33725
},
{
\"brand\": \"Apple\",
\"series\": \"Macbook\",
\"model\": \"M1 Pro 512GB SSD Storage\",
\"qty\": 15,
\"unit_price\": 8799,
\"total_price\": 131985
}
],
\"smartphone\": {
\"brand\": \"Apple\",
\"series\": \"iPhone\",
\"model\": \"iPhone 13 Pro\",
\"qty\": 5,
\"unit_price\": 4899,
\"total_price\": 24495
}
},
\"grandtotal\": 190205
},
\"html_form\": true
}"
const url = new URL(
"https://exchange.kineticpay.my/fpx_landing_page"
);
const headers = {
"Authorization": "Bearer {YOUR_AUTH_KEY}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"order_number": "KICT-Invoice\/2021\/03\/01234",
"order_description": "FPX Online Payment",
"order_amount": "1234.56",
"buyer_name": "Ahmad Fazli Ismail",
"buyer_email": "sales@k-ict.org",
"receipt_url": "https:\/\/shopping-cart.cloud.org.my\/orders\/888",
"transaction_update_url": "<?php echo route('fpx_payments.update'); ?>",
"show_custom_buyer_info_at_landing_page": true,
"custom_buyer_name": "Fazli",
"custom_buyer_email": "fazli@cloud.org.my",
"custom_buyer_personal_info": {
"gender": "male",
"date_of_birth": "2001-01-01",
"phone_number": {
"office": "+60389595505",
"mobile": "+60146764788"
},
"address": {
"billing": "Level 15 DPulze, Lingkaran Cyber Point Timur, Cyber 12, Cyberjaya, 63000 Selangor, MY",
"shipping": "Jabatan Perdana Menteri, Setia Perdana 8, Kompleks Setia Perdana, Pusat Pentadbiran Kerajaan Persekutuan, 62502 Putrajaya, Malaysia"
}
},
"custom_order_data": {
"purchase_order_ref_number": "PO\/KICT\/2022-00234",
"quotation_ref_number": "2022\/01\/00088",
"po_date": "2020-05-13",
"items": {
"laptop": [
{
"brand": "Acer",
"series": "Chromebook",
"model": "C733-C8F7",
"qty": 25,
"unit_price": 1349,
"total_price": 33725
},
{
"brand": "Apple",
"series": "Macbook",
"model": "M1 Pro 512GB SSD Storage",
"qty": 15,
"unit_price": 8799,
"total_price": 131985
}
],
"smartphone": {
"brand": "Apple",
"series": "iPhone",
"model": "iPhone 13 Pro",
"qty": 5,
"unit_price": 4899,
"total_price": 24495
}
},
"grandtotal": 190205
},
"html_form": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());
Example response (200, Success):
{
"record": {
"order_number": "KICT-Invoice/2021/03/01234",
"order_description": "FPX Online Payment",
"order_currency": "MYR",
"order_amount": "1234.56",
"merchant_name": "fpx-exchange@k-ict.org",
"buyer_name": "Ahmad Fazli Ismail",
"buyer_email": "sales@k-ict.org",
"exchange_order_number": "1-616-250-124-403629",
"show_custom_buyer_info_at_landing_page": true,
"custom_buyer_name": "Fazli",
"custom_buyer_email": "fazli@cloud.org.my",
"custom_buyer_personal_info": {
"gender": "male",
"date_of_birth": "2001-01-01",
"phone_number": {
"office": "+60389595505",
"mobile": "+60146764788"
},
"address": {
"billing": "Level 15 DPulze, Lingkaran Cyber Point Timur, Cyber 12, Cyberjaya, 63000 Selangor, MY",
"shipping": "Jabatan Perdana Menteri, Setia Perdana 8, Kompleks Setia Perdana, Pusat Pentadbiran Kerajaan Persekutuan, 62502 Putrajaya, Malaysia"
}
}
"custom_order_description": {
"purchase_order_ref_number": "PO/KICT/2022-00234",
"quotation_ref_number": "2022/01/00088",
"po_date": "2020-05-13",
"items": {
"laptop": [
{
"brand": "Acer",
"series": "Chromebook",
"model": "C733-C8F7",
"qty": 25,
"unit_price": 1349,
"total_price": 33725
},
{
"brand": "Apple",
"series": "Macbook",
"model": "M1 Pro 512GB SSD Storage",
"qty": 15,
"unit_price": 8799,
"total_price": 131985
}
],
"smartphone": {
"brand": "Apple",
"series": "iPhone",
"model": "iPhone 13 Pro",
"qty": 5,
"unit_price": 4899,
"total_price": 24495
}
},
"grandtotal": 190205
},
"html_form": true,
},
"html": "<form id=\"f1dd4e7c28c5eaadf939fb0e688dd5b8\" method=\"post\" style=\"display: none;\" action=\"https://php74.cloud.org.my/draft/exchange.k-ict.org/fpx_payments/create\"><input name=\"prep_fpx_ar_data\" type=\"hidden\" value=\"1\"><input name=\"encrypted_data\" type=\"hidden\" value=\"eyJpdiI6IkJRZVg1eC9rTEs2OGFwODVVd0VlSlE9PSIsInZhbHVlIjoibitUbExVRklUUGVNTFdodWZDUG5kaGZhcTF3ZFJFNm5uTEpEZzNWWW9OeStScGtPeWIycGdLL2dZZTAvWC9KMVJXbzV0ODBSelZZMGJhdi9RN3IveW5oQ054cWdiT2hrU0gxTlpUUkdCOGpoTVZwM3BQekJYYUxrVTI1WDZTdGhqc0VIcVY4WU8wTi9sSy9qdHlYdE02aElUQWtnb3N2R2NyOGRUelpJb3QrV2c0ZndHeUxaZ20yQ0hjQXVXSUdrRUlDQjR0SlYvQVBqMUFzUGZuWXNCRmhtbVZvNWJ3SmZTN3VOY0hMc0hGNXdsOXlydkRHcDJDWHdMQ1pmRFZvazVmYmRad0R0Z0VwN2tqZnNOYXIxbmEwZVU1L21ZREo1SlFDVGVoc3hOZndsUEcyZ1l4ZFZ5eHU3c0tvVDlLSmNKR3ZUVTFDNjFYSkZITGdJL2NsbER0Rm9hdFBtZE1MQitvc3lvQzIvcW9DdVI2Vy8yZXBiUDM4MjY1WWlTTDUzaUZuT25FVmd5OE5GbUE3Z3cyRnRlZWNnL3lXZFpaZjFHQjQxZUw2US90eFBMZ3ZDTGNEUUtrTzBxSjdKLytmeiIsIm1hYyI6IjY3OWU5YmU5ZWJhYTBhMGMzN2QyNmJkMDMxZDdlZjVkMjhlYThmMWU4MmNlZmVkYmUxMTY5Y2Q4NWM4YWJmMjYifQ==\"><script type=\"text/javascript\">document.getElementById(\"f1dd4e7c28c5eaadf939fb0e688dd5b8\").submit();</script></form>"
}
Example response (422, Unprocessible Entity):
{
"message": "The given data was invalid.",
"errors": {
"order_amount": [
"The order amount must be a number."
],
"buyer_email": [
"The buyer email must be a valid email address."
],
"receipt_url": [
"The receipt url field is required."
],
"transaction_update_url": [
"The transaction update url field is required."
]
}
}
Received response:
Request failed with error:
Create a new FPX transaction.
requires authentication
Create a new FPX transaction request to Exchange server by using your self-hosted FPX landing page.
Notes: You may test this endpoint using Postman by choosing Body > raw with JSON (application/json) since certain parameters are using array.
Usage;
1. Create an HTML form like example below;
<form method="POST" action="script_to_create_transaction.php">
[display all parameters as input fields]
[display the bank selection list here]
<button type="submit" value="Proceed">
</form>
2. Call this API in script_to_create_transaction.php
3. Capture API response as pre-transaction data. Note that you need to use order_number along with exchange_order_number to perform transaction status re-query later.
4. Render the html contents obtained from the response to redirect the buyer to his / her preferred Internet Banking login page.
Your script_to_create_transaction.php
should be like this;
<?php
# Step 1 of 4: Make API call.
# Step 2 of 4: Capture API response.
# Step 3 of 4: Handle exceptions.
# Step 4 of 4: Render HTML contents from API response.
Refer FPX documents regarding to FPX landing page compliance.