Introduction
What is Fastpay
FastPay is an online payment tool for businesses to accept all modes of payment including debit cards, credit cards, e-wallet, online banking, buy now pay later and instalment payment plans by major banks.
It allows users to make online purchases using their preferred payment method. Users can save payment details in their accounts to enable one-click checkout for all future purchases within the FastPay merchant network.
This documentation is for the use of vendors/businesses integrating FastPay into their e-commerce websites.
API Reference
The FastPay API is organised around REST. Our API returns JSON-encoded responses and uses standard HTTP response codes, authentication, and verbs.
All API requests must be made over HTTPS. Calls made over plain HTTP will fail. API requests without authentication will also fail.
Here are the parties we will refer to in this API documentation:
- Vendor - Refers to parties integrating these APIs (the intended recipient of this API documentation).
Requirements
System Requirements
- Compatible with HMAC, which is used to authenticate API requests.
- Make API calls over HTTPS.
Credentials
Please reach out to us at partners.my@fastpaynow.com to receive credentials for integration.
FastPay will provide the vendor with the following information:
- Secret key: The vendor will receive a private API key (secret key) which will be used to generate the payload signature.
- Vendor reference number: The vendor will receive a unique prefix to prepend to
omni_reference
.
API Versions
The FastPay API is currently on version 1.0.
API URL Paths
There are two parts to the FastPay API URL paths - The base URL and the endpoint.
{base_url}/{endpoint}
{base_url}
should be replaced with the URL of the intended environment, and {endpoint}
should be replaced with the specific API endpoint to produce a valid API URL path.
For instance, a call to the Request Checkout Link API endpoint in the Production environment would look like so:
Production Base URL
Staging Base URL
Authentication
The FastPay API uses payload signature to authenticate requests. Please refer to Appendix A and Appendix B for more information.
Requests will be rejected by FastPay if they do not contain a valid HMAC-SHA256 signature. A request signature can be generated using the vendor’s API key (secret key) provided by FastPay, which is shared between FastPay and the vendor only.
Tenancy by Country
FastPay practises multi-tenancy architecture and scopes data by country. We use :country_code
in the request URL to specify which country to fetch data from. The currently available countries are Malaysia, Singapore, and Indonesia.
:country_code
should be replaced with the country code of the intended country, like so:
Specifying the correct country code where the vendor account is registered is essential to ensure successful requests.
API Parameter Requirement
Requirement | Description |
---|---|
R | Required |
CR | Conditionally Required |
O | Optional |
API Workflow
Vendor handles shipping
This is the flow when skip_shipping: true
is provided in the Request Checkout Link API.
The typical use case for this flow is when the user clicks on the payment button on the vendor's checkout page. FastPay will only handle the payment transaction.
- The user visits the vendor’s site.
- The user clicks the FastPay button on the vendor’s checkout page.
- The vendor creates an order and requests a one-off checkout payment URL from FastPay.
- FastPay returns the payment URL to the vendor.
- The vendor redirects the user to the payment URL.
- The user enters a phone number and selects a payment method. If the user chooses to skip entering a phone number, they will continue to checkout as a FastPay guest user.
- Fastpay displays the payment details and proceeds to process the payment.
- Fastpay returns the transaction status to the vendor, and the vendor handles it accordingly.
Vendor does not ship
This is the flow when skip_shipping: false
is provided in the Request Checkout Link API.
The typical use case for this flow is when the user clicks the FastPay Buy Now button on the product/SKU page. FastPay will pass the updated order and shipping details to the vendor.
- The user visits the vendor’s site.
- The user clicks the FastPay button for express checkout with a single item.
- The vendor creates an order and requests a one-off checkout payment URL from FastPay.
- FastPay returns the payment URL to the vendor.
- The vendor redirects the user to the payment URL.
- The user enters a phone number and selects a payment method.
- The user selects or updates the shipping address.
- Fastpay gets a list of available shipping options from the vendor.
- The user selects a shipping option.
- Fastpay sends the updated order details to the vendor according to the selected shipping option. The details include shipping and billing information.
- The vendor returns the final charge amount to Fastpay.
- Fastpay displays the payment details and proceeds to process the payment.
- Fastpay returns the transaction status to the vendor, and the vendor handles it accordingly.
FastPay Guest User
- When making a payment with FastPay, if the user chooses not to enter their phone number, they will continue the checkout flow as a FastPay Guest user.
- A FastPay Guest user will not be able to collect any rewards as the user’s information will not be stored.
Webhooks (Optional)
List of webhook endpoints that FastPay Backend requires when skip_shipping
is false
. They should be provided in the Request Checkout Link API endpoint. These webhooks will be invoked from FastPay Backend to Vendor Backend for the reasons listed below.
Webhook: shipping_info_url
Expects the vendor to return a list of available shipping options. FastPay will include the selected shipping option in the update_order_url webhook request.
Response
GET
https://api.vendor-backend.com/shipping-options
[
{
"id": "1",
"method_id": "normal_delivery",
"title": "Normal Delivery",
"cost": "5.50"
}
]
FastPay Backend expects this webhook to return the following JSON format from the Vendor Backend.
Name | Type | Description |
---|---|---|
id | string | Unique shipping option ID. |
method_id | string | Title of the shipping option. |
title | string | Readable title of the shipping option. |
cost | string | Total shipping amount in cents for display. |
Example of shipping options user interface:
Webhook: update_order_url
Update the Order details on the vendor site with additional details such as shipping options. It should return the final charge amount total_amount_cents
in the response.
Request Parameters:
POST
https://api.vendor-backend.com/update-order
Example (JSON)
{
"id": "727",
"shipping_address": {
"first_name": "John",
"last_name": "Doe",
"address1": "969 Market",
"address2": "",
"city": "San Francisco",
"state": "CA",
"postcode": "94103",
"country": "US",
"email": "lorem@ipsum.com",
"phone": "+60169999999"
},
"billing_address": {
"first_name": "John",
"last_name": "Doe",
"address1": "969 Market",
"address2": "",
"city": "San Francisco",
"state": "CA",
"postcode": "94103",
"country": "US",
"email": "lorem@ipsum.com",
"phone": "+60169999999"
},
"shipping_line": {
"id": 1,
"method_id": "normal_delivery"
},
"note": "Please leave the package at the door."
}
Response
{
"total_amount_cents": 3000 //RM30.00
}
FastPay Backend will send the following JSON payload to the Vendor Backend in this webhook.
Name | Type | R/CR/O | Description |
---|---|---|---|
id | string | R | Order ID obtained from Request Checkout Link API. |
shipping_address | string | R | Shipping address details. |
billing_address | string | R | Billing address details. |
shipping_line | string | R | Shipping line information from Webhook: shipping_info_url. Required to pass both id and method_id . |
note | string | O | Note from customer, if available. |
Shipping Address Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
first_name | string | R | Recipient’s first name. |
last_name | string | R | Recipient’s last name. |
address1 | string | R | First line of recipient’s address. |
address2 | string | O | Second line of recipient’s address. |
city | string | R | Recipient’s city. |
state | string | R | Recipient’s state. |
postcode | string | R | Recipient’s postcode. |
country | string | R | Recipient’s country. |
string | O | Recipient’s email address. | |
phone | string | R | Recipient’s phone number. Format: {country_code}{phone_number} , and must begin with +. |
Billing Address Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
first_name | string | R | Recipient’s first name. |
last_name | string | R | Recipient’s last name. |
address1 | string | R | First line of recipient’s address. |
address2 | string | O | Second line of recipient’s address. |
city | string | R | Recipient’s city. |
state | string | R | Recipient’s state. |
postcode | string | R | Recipient’s postcode. |
country | string | R | Recipient’s country. |
string | O | Recipient’s email address. | |
phone | string | R | Recipient’s phone number. Format: {country_code}{phone_number} , and must begin with +. |
V1
If you're new to the FastPay implementation, this version is not in active development state and we would recommend you to navigate to V2 for the current version.
Request Checkout Link API V1
Request for a one-off use payment URL. This API is used to initiate the FastPay payment process. The vendor will redirect the user to the payment URL returned by FastPay. The sign must be generated following Appendix A.
/api/fastpay/v1/:country_code/checkout
Shipping Options V1
With FastPay, shipping can be handled either from the vendor’s side or FastPay’s side. This is
determined by the boolean value skip_shipping
passed in the request of this API.
For shipping to be handled by the vendor, the value must be set to true
; shipping will be
handled by FastPay when the value is false
.
Request Checkout Parameters V1
curl -X POST 'https://omni.myfave.com/api/fastpay/v1/my/checkout' \
-H 'Content-Type: application/json' \
-d '{
"omni_reference": "PL-0001",
"total_amount_cents": 1000,
"app_id": "a3osyvuayt",
"outlet_id": 11637,
"sign": "6c92b6704b99526ee9900d00d8d375386524add07838c907c87a94baa0bd2903",
"callback_url": "https://vendor-backend.com",
"redirect_url": "https://www.123.com",
"shipping_info_url": "https://api.vendor-backend.com/shipping-options",
"update_order_url": "https://api.vendor-backend.com/update-order",
"phone": "+60171234567",
"skip_shipping": true,
"skip_email": true,
"test": true
}'
var axios = require('axios');
var data = JSON.stringify({
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7",
"omni_reference": "WCM-1667541435030",
"total_amount_cents": 200,
"app_id": "f0l6wkqzfn",
"outlet_id": 12581,
"qr_format": "web_url",
"redirect_url": "https://example.com",
"callback_url": "https://example.com/api/callback",
"skip_shipping": true,
"phone": "+60123456789"
});
axios.post('/api/fastpay/v1/my/checkout', data)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
$client = new Client();
$headers = [
'Content-Type' => 'application/json'
];
$body = '{
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7",
"omni_reference": "WCM-1667541435030",
"total_amount_cents": 200,
"app_id": "f0l6wkqzfn",
"outlet_id": 12581,
"qr_format": "web_url",
"redirect_url": "https://example.com",
"callback_url": "https://example.com/api/callback",
"skip_shipping": true,
"phone": "+60123456789"
}';
$request = new Request('POST', 'https://omni.app.fave.ninja/api/fastpay/v1/my/checkout', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
import requests
import json
url = "https://omni.app.fave.ninja/api/fastpay/v1/my/checkout"
payload = json.dumps({
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7",
"omni_reference": "WCM-1667541435030",
"total_amount_cents": 200,
"app_id": "f0l6wkqzfn",
"outlet_id": 12581,
"qr_format": "web_url",
"redirect_url": "https://example.com",
"callback_url": "https://example.com/api/callback",
"skip_shipping": true,
"phone": "+60123456789"
})
response = requests.request("POST", url, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://omni.app.fave.ninja/api/fastpay/v1/my/checkout")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7",
"omni_reference": "WCM-1667541435030",
"total_amount_cents": 200,
"app_id": "f0l6wkqzfn",
"outlet_id": 12581,
"qr_format": "web_url",
"redirect_url": "https://example.com",
"callback_url": "https://example.com/api/callback",
"skip_shipping": true,
"phone": "+60123456789"
})
response = https.request(request)
puts response.read_body
JSON response example
{
"code":
"https://myfave.onelink.me/U7Uv?af_dp=fave%3A%2F%2Faccess.kfit.com%2Ffastpay%3Ffp_ref%3DWCM-1648084297118%26country_code%3Dmy%26expired%3D600%26skip_shipping%3Dfalse%26amount%3D10.00%26amount_locked%3D1%26outlet_id%3D12581%26client_name%3DWCM%26latitude%3D3.1379835%26longitude%3D101.6582551&af_ios_url=https://qa-staging.pwa.fave.ninja/fastpay-checkout?fp_ref=WCM-1648084297118&country_code=my&expired=600&skip_shipping=false&amount=10.00&amount_locked=1&outlet_id=12581&client_name=WCM&latitude=3.1379835&longitude=101.6582551&af_r=https://qa-staging.pwa.fave.ninja/fastpay-checkout?fp_ref=WCM-1648084297118&country_code=my&expired=600&skip_shipping=false&amount=10.00&amount_locked=1&outlet_id=12581&client_name=WCM&latitude=3.1379835&longitude=101.6582551&af_force_deeplink=true",
"expires_in": 600,
"format": "web_url"
}
Name | Type | R/CR/O | Description |
---|---|---|---|
omni_reference | string | R | Unique reference string provided by the vendor for the transaction. The vendor should prepend the prefix issued by FastPay in front of the vendor’s reference number. Max-length: 28 characters. Format: [prefix]-[reference_id] |
total_amount_cents | integer | R | Total payment amount in cents. Discount and merchant cashback are not included. Accepts positive integers only. |
app_id | string | R | Vendor ID issued by FastPay. Format: 10 digits of alphanumeric. |
outlet_id | integer | R | Merchant’s outlet id in FastPay. |
sign | string | R | SHA256 API request signature. Refer to Appendix A for details. |
callback_url | string | R | Vendor-side URL to which the transaction object will be sent in the event that the payment has been processed, regardless of successful or rejected payment. Refer to the Transaction API section for details. |
redirect_url | string | R | Redirects to this page when payment has been processed, regardless of successful or rejected payment. |
shipping_info_url | string | CR | Vendor-side webhook API endpoint for FastPay Backend to retrieve a list of shipping options. Required when: skip_shipping is false . |
update_order_url | string | CR | Vendor-side webhook API endpoint to create/update the user’s order details in the vendor’s platform (e.g. WooCommerce). Required when: skip_shipping is false . |
order | object | CR | User's order with a list of merchant's line items. Required when: skip_shipping is false . |
phone | string | O | User’s phone number. |
skip_shipping | boolean | O | If true , the API will return the URL that skips the shipping address page in FastPay and goes directly to the payment page. If shipping is handled by the vendor, set this value to true. Default: false . |
skip_email | boolean | O | If true , FastPay will not request for the user’s email address and name upon a new user sign up, and proceed directly to the checkout page. Default: false . |
test | boolean | O | If true , the API will return a mock payment page that the vendor can use for testing a payment without actual payment details. Default: false . |
Order Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
id | string | R | Unique order ID from the vendor. |
currency | string | R | Currency. |
discount_total | string | R | Total discounted amount. |
total | string | R | Total order amount before discount. |
tax_total | string | R | Total tax amount. |
line_items | array of object | R | List of line items. |
Line Item Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
name | string | R | Product name. |
product_id | string | R | Unique product ID. |
variation_id | string | R | Unique product variation's ID. |
image | string | R | Image URL. |
currency | string | R | Currency |
price | string | R | Price of a single item. |
subtotal | string | R | Subtotal amount. |
quantity | string | R | Quantity of items. |
total_tax | string | R | Total tax amount. |
Usage of omni_ref
in Redirect URL V1
Upon payment completion on FastPay’s payment page, the user will be redirected to the vendor’s website as specified by the parameter
redirect_url
in this API.FastPay will append encrypted transaction details to the specified
redirect_url
in the form of parameteromni_ref
.
Example:
The value of
omni_ref
is encrypted with AES; therefore, the vendor must decryptomni_ref
to obtain basic transaction details. These details are the transaction’sreceipt_id
,omni_reference
,status
, andtotal_amount_cents
.The algorithm used for the encryption is AES-128 CBC Mode, PCKS7 Padding.
Example:
The
omni_ref
can be decrypted by using the vendor’s API key (secret key). In this example, the API key (secret key),d25f1p1zf6ww8eja
is used to decrypt theomni_ref
.After decryption of the
omni_ref
with private key provided to the vendor (d25f1p1zf6ww8eja
), the transaction details would be as follows:
Reference:
https://www.devglan.com/online-tools/aes-encryption-decryption
Transactions API V1
Each merchant’s configuration and each transaction may be different, some of the transaction values may be null
.
Receipt ID can be 9 digits or 30 digits alphanumeric string depending on the source of the transaction.
Available statuses:
Status | Status Code |
---|---|
pending_payment | 0 |
payment_processing | 1 |
successful | 2 |
disputed | 3 |
rejected | 4 |
refunded | 5 |
Transaction Object V1
All calls under Transaction API will return the transaction object.
JSON response example:
Note : this is a sample transaction and values might not be entirely accurate.
{
"id": "FP_792619",
"receipt_id": "0118-7347",
"outlet_name": "TTDI",
"total_amount_cents": "2100",
"refund_amount_cents": "0",
"currency": "MYR",
"outlet_id": "1593",
"mid": "1166",
"omni_reference": "PL-0001",
"status": "successful",
"status_code": "2",
"created_at": "2021-03-26T18:14:59.698+08:00",
"campaign_credit_amount_cents": "0",
"campaign_funded_by": "N/A",
"aabig_points_used_amount_cents": "0",
"merchant_cashback_amount_cents": "350",
"fave_credits_amount_cents": "200",
"promo_code_value_cents": "0",
"e_card_credits_used_cents": "0",
"charged_amount_cents": "1550",
"cashback_rate": "0.0",
"merchant_cashback_issued_cents": "0",
"promo_code_cashback_value": "2.00",
"promo_code_cashback_type": "absolute_cashback",
"promo_code_cashback_issued_cents": "200",
"promo_code_cashback_funded_by": "merchant",
"fave_fees_percentage": "1.0",
"fave_fees_cents": "18",
"sst_on_total_fees_cents": "1",
"merchant_takeback_cents": "1881",
"user_id": "2818771",
"fpl_transaction": "false",
"fpl_fees_percentage": "N/A",
"fpl_fees_cents": "N/A",
"fpl_merchant_cashback_reduction_percentage": "N/A",
"sign": "56f6054ed61a3a3eb3dff2c06c320339044a4562f63f7d53cee0ff010df561a8"
}
Field | Description |
---|---|
id |
max length 35 chars |
receipt_id |
max length 35 chars |
outlet_name |
|
total_amount_cents |
|
refund_amount_cents |
|
currency |
|
outlet_id |
|
mid |
|
omni_reference |
|
status |
|
status_code |
|
created_at |
|
campaign_credit_amount_cents |
campaign credit redeemed amnt |
campaign_funded_by |
|
aabig_points_used_amount_cents |
AABig points redeemed amnt |
merchant_cashback_amount_cents |
merchant cashback redeemed amnt |
fave_credits_amount_cents |
Fave credit redeemed amnt |
promo_code_value_cents |
promo code discount amnt |
e_card_credits_used_cents |
user’s eCard membership credits amnt |
charged_amount_cents |
credit card/e-wallet charged amnt |
cashback_rate |
cashback rate that offered by merchant |
merchant_cashback_issued_cents |
the cashback amnt user earned |
promo_code_cashback_value |
the cashback amnt user earned |
promo_code_cashback_type |
|
promo_code_cashback_issued_cents |
|
promo_code_cashback_funded_by |
|
fave_fees_percentage |
|
fave_fees_cents |
total fee charged by Fave |
sst_on_total_fees_cents |
mandated government tax by country |
merchant_takeback_cents |
total amount merchant will receive |
user_id |
FastPay unique user id |
fpl_transaction |
to indicate favepay later transaction |
fpl_fees_percentage |
|
fpl_fees_cents |
|
fpl_merchant_cashback_reduction_percentage |
For security reasons, Vendors should use the sign
parameter value in the payload above to verify our payload integrity. Please refer to Appendix C for the details. Do note that only the transaction object in the webhook callback will contain the sign parameter for payload verification.
The field fpl_transaction
is used to indicate if a particular transaction is a FavePay Later transaction. The string true
indicates that the transaction is a FavePay Later transaction or vice versa.
If a transaction is not a FavePay Later transaction, the associated fields of fpl_fees_percentage
, fpl_fees_cents
, fpl_merchant_cashback_reduction_percentage
would be N/A
.
API: Get a transaction V1
The transaction status can be retrieved either by the omni_reference
or by the receipt_id
.
/api/fpo/v1/:country_code/transactions
curl \
--location \
--request \
GET 'https://omni.app.fave.ninja//api/fpo/v1/my/transactions?app_id=f0l6wkqzfn&omni_reference=WCM-1667541435030&sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7'
var axios = require('axios');
axios.get('/api/fpo/v1/my/transactions', {
params: {
'app_id': 'f0l6wkqzfn',
'omni_reference': 'WCM-1667541435030',
'sign': '57c2af5432362011d1e2925d1ab2f6020313c7599e45e5d5840c7d607363e340',
}
})
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
$client = new Client();
$request = new Request('GET', 'https://omni.app.fave.ninja/api/fpo/v1/my/transactions?app_id=f0l6wkqzfn&omni_reference=WCM-1667541435030&sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7');
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
import requests
url = "https://omni.app.fave.ninja/api/fpo/v1/my/transactions?app_id=f0l6wkqzfn&omni_reference=WCM-1667541435030&sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
response = requests.request("GET", url)
print(response.text)
require "uri"
require "net/http"
url = URI("https://omni.app.fave.ninja/api/fpo/v1/my/transactions?app_id=app_id here&omni_reference=WCM-1667541435030&sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
response = https.request(request)
puts response.read_body
Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
receipt_id | string | CR | Fave receipt_id as displayed on the app. |
omni_reference | string | CR | The omni_reference is the unique reference string provided by the vendor for the transaction. |
app_id | string | R | Vendor ID issued by Fave |
sign | string | R | API request signature |
Transaction Response V1
Errors
Name | Description | Possible Reasons |
---|---|---|
resource_not_found |
The resource provided is not found or invalid. |
|
validation |
There is an issue with the validation of the request parameters. |
|
Unauthorized |
The request is not authorised or there is an issue with the request. |
|
Note: The API may return an unauthorized
request error if the provided receipt_id
or omni_reference
does not exist in our database records.
API: Transaction History V1
The Transaction History API returns a list of transaction objects that match the query criteria. The vendor can use this API either with a limit or with a timestamp. When the limit
parameter is provided, the API will return the n last transactions associated with the given outlet_id
. The timestamp parameter used to retrieve all the transactions between the timestamp and current time.
/api/fpo/v1/:country_code/outlets/:outlet_id/transactions
curl \
--location \
--request GET 'https://omni.app.fave.ninja/api/fpo/v1/my/outlets/21791/transactions?sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7&app_id=f0l6wkqzfn'
var axios = require('axios');
axios.get('/api/fpo/v1/my/outlets/21791/transactions', {
params: {
'app_id': 'f0l6wkqzfn',
'sign': '57c2af5432362011d1e2925d1ab2f6020313c7599e45e5d5840c7d607363e340',
}
})
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
$client = new Client();
$request = new Request('GET', 'https://omni.app.fave.ninja/api/fpo/v1/my/outlets/21791/transactions?sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7&app_id=f0l6wkqzfn');
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
import requests
url = "https://omni.app.fave.ninja/api/fpo/v1/my/outlets/21791/transactions?sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7&app_id=f0l6wkqzfn"
response = requests.request("GET", url)
print(response.text)
require "uri"
require "net/http"
url = URI("https://omni.app.fave.ninja/api/fpo/v1/my/outlets/21791/transactions?sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7&app_id=app_id here")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
response = https.request(request)
puts response.read_body
Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
app_id | string | R | Vendor ID issued by Fave |
limit | integer | CR | The number of transactions to return. Default: 10 Max-value: 1000" |
timestamp | integer | CR | Filter the result by transaction timestamp. Default: null Format: Unix Timestamp. The timestamp must not be earlier than one month. |
ack | boolean | O | Filter the result by acknowledgement status. Filter out the acknowledged transactions when the value is false. Default: true |
sign | string | R | API request signature |
Transaction Response V1
Errors
Name | Description | Possible Reasons |
---|---|---|
resource_not_found |
The resource provided is not found or invalid. | The outlet_id provided is not valid. |
validation |
There is an issue with the validation of the request parameters. |
|
Unauthorized |
The request is not authorised or there is an issue with the request. |
|
error |
There is no result for the request given. | No records match the query. |
API: Refund a transaction V1
A POST request can make a refund request with the request body containing the omni_reference
and the refund status. This API is idempotent; any call after the first successful call will directly return the status. The transaction only can be refunded through this API within 24 hours. Any request that comes after that will receive a stale_transaction
error.
/api/fpo/v1/:country_code/transactions
curl \
--location \
--request POST 'https://omni.app.fave.ninja/api/fpo/v1/my/transactions' \
--header 'Content-Type: application/json' \
--data-raw '{
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
}'
var axios = require('axios');
var data = JSON.stringify({
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
});
axios.post('/api/fpo/v1/my/transactions', data)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
$client = new Client();
$headers = [
'Content-Type' => 'application/json'
];
$body = '{
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
}';
$request = new Request('POST', 'https://omni.app.fave.ninja/api/fpo/v1/my/transactions', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
import requests
import json
url = "https://omni.app.fave.ninja/api/fpo/v1/my/transactions"
payload = json.dumps({
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://omni.app.fave.ninja/api/fpo/v1/my/transactions")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
})
response = https.request(request)
puts response.read_body
Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
omni_reference | string | R | The omni_reference is the unique reference string provided by the vendor for the transaction. First introduced in the QR code API request. |
app_id | string | R | Vendor ID issued by Fave. |
status | string | R | Transaction status. Accepted values: refunded |
partial_refund_cents | integer | O | Partial refund amount. This is only applicable for FavePayment. If this parameter is not provided, a full refund will be performed. |
sign | string | R | API request signature. |
Transaction Response V1
Errors V1
Name | Description | Possible Reasons |
---|---|---|
resource_not_found |
The resource provided is not found or invalid. | The omni_reference provided is not valid. |
validation |
There is an issue with the validation of the request parameters. | The status provided is not valid. The only accepted value is refunded. partial_refund_cents exceeds the transaction’s charged_amount_cents . |
Unauthorized |
The request is not authorised or there is an issue with the request. | Signature is incorrect. |
stale_transaction |
The request was made more than 24 hours after the transaction was created. | Refund attempt was made after 24 hours of transaction creation. Transaction can no longer be refunded. |
failed_request |
The request failed. | Refund request failed. |
unexpected_error |
The request was rejected. | Refund request rejected. |
V2
This version is in active development state.
Request Checkout Link API V2
Request for a one-off use payment URL. This API is used to initiate the FastPay payment process. The vendor will redirect the user to the payment URL returned by FastPay. The sign must be generated following Appendix A.
/api/fastpay/v2/:country_code/checkout
Shipping Options V2
With FastPay, shipping can be handled either from the vendor’s side or FastPay’s side. This is
determined by the boolean value shipping_required
passed in the request of this API.
For shipping to be handled by the vendor, the value must be set to false
; shipping will be
handled by FastPay when the value is true
.
Request Checkout Parameters V2
curl -X POST 'https://omni.myfave.com/api/fastpay/v2/my/checkout' \
-H 'Content-Type: application/json' \
-d '{
"omni_reference": "PL-0001",
"total_amount_cents": 1000,
"app_id": "a3osyvuayt",
"outlet_id": 11637,
"sign": "6c92b6704b99526ee9900d00d8d375386524add07838c907c87a94baa0bd2903",
"callback_url": "https://vendor-backend.com",
"redirect_url": "https://www.123.com",
"shipping_info_url": "https://api.vendor-backend.com/shipping-options",
"update_order_url": "https://api.vendor-backend.com/update-order",
"phone": "+60171234567",
"shipping_required": true,
"email_required": true,
"test": true
}'
var axios = require('axios');
var data = JSON.stringify({
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7",
"omni_reference": "WCM-1667541435030",
"total_amount_cents": 200,
"app_id": "f0l6wkqzfn",
"outlet_id": 12581,
"qr_format": "web_url",
"redirect_url": "https://example.com",
"callback_url": "https://example.com/api/callback",
"shipping_required": true,
"phone": "+60123456789"
});
axios.post('/api/fastpay/v2/my/checkout', data)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
$client = new Client();
$headers = [
'Content-Type' => 'application/json'
];
$body = '{
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7",
"omni_reference": "WCM-1667541435030",
"total_amount_cents": 200,
"app_id": "f0l6wkqzfn",
"outlet_id": 12581,
"qr_format": "web_url",
"redirect_url": "https://example.com",
"callback_url": "https://example.com/api/callback",
"shipping_required": true,
"phone": "+60123456789"
}';
$request = new Request('POST', 'https://omni.app.fave.ninja/api/fastpay/v2/my/checkout', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
import requests
import json
url = "https://omni.app.fave.ninja/api/fastpay/v2/my/checkout"
payload = json.dumps({
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7",
"omni_reference": "WCM-1667541435030",
"total_amount_cents": 200,
"app_id": "f0l6wkqzfn",
"outlet_id": 12581,
"qr_format": "web_url",
"redirect_url": "https://example.com",
"callback_url": "https://example.com/api/callback",
"shipping_required": true,
"phone": "+60123456789"
})
response = requests.request("POST", url, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://omni.app.fave.ninja/api/fastpay/v2/my/checkout")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7",
"omni_reference": "WCM-1667541435030",
"total_amount_cents": 200,
"app_id": "f0l6wkqzfn",
"outlet_id": 12581,
"qr_format": "web_url",
"redirect_url": "https://example.com",
"callback_url": "https://example.com/api/callback",
"shipping_required": true,
"phone": "+60123456789"
})
response = https.request(request)
puts response.read_body
JSON response example
{
"code":
"https://myfave.onelink.me/U7Uv?af_dp=fave%3A%2F%2Faccess.kfit.com%2Ffastpay%3Ffp_ref%3DWCM-1648084297118%26country_code%3Dmy%26expired%3D600%26shipping_required%3Dfalse%26amount%3D10.00%26amount_locked%3D1%26outlet_id%3D12581%26client_name%3DWCM%26latitude%3D3.1379835%26longitude%3D101.6582551&af_ios_url=https://qa-staging.pwa.fave.ninja/fastpay-checkout?fp_ref=WCM-1648084297118&country_code=my&expired=600&shipping_required=false&amount=10.00&amount_locked=1&outlet_id=12581&client_name=WCM&latitude=3.1379835&longitude=101.6582551&af_r=https://qa-staging.pwa.fave.ninja/fastpay-checkout?fp_ref=WCM-1648084297118&country_code=my&expired=600&shipping_required=false&amount=10.00&amount_locked=1&outlet_id=12581&client_name=WCM&latitude=3.1379835&longitude=101.6582551&af_force_deeplink=true",
"expires_in": 600,
"format": "web_url"
}
Name | Type | R/CR/O | Description |
---|---|---|---|
omni_reference | string | R | Unique reference string provided by the vendor for the transaction. The vendor should prepend the prefix issued by FastPay in front of the vendor’s reference number. Max-length: 28 characters. Format: [prefix]-[reference_id] |
total_amount_cents | integer | R | Total payment amount in cents. Discount and merchant cashback are not included. Accepts positive integers only. |
app_id | string | R | Vendor ID issued by FastPay. Format: 10 digits of alphanumeric. |
outlet_id | integer | R | Merchant’s outlet id in FastPay. |
sign | string | R | SHA256 API request signature. Refer to Appendix A for details. |
callback_url | string | R | Vendor-side URL to which the transaction object will be sent in the event that the payment has been processed, regardless of successful or rejected payment. Refer to the Transaction API section for details. |
redirect_url | string | R | Redirects to this page when payment has been processed, regardless of successful or rejected payment. |
shipping_info_url | string | CR | Vendor-side webhook API endpoint for FastPay Backend to retrieve a list of shipping options. Required when: shipping_required is true . |
update_order_url | string | CR | Vendor-side webhook API endpoint to create/update the user’s order details in the vendor’s platform (e.g. WooCommerce). Required when: shipping_required is true . |
order | object | CR | User's order with a list of merchant's line items. Required when: shipping_required is true . |
phone | string | O | User’s phone number. |
shipping_required | boolean | O | If true , the API will return the URL that skips the shipping address page in FastPay and goes directly to the payment page. If shipping is handled by the vendor, set this value to true. Default: false . |
email_required | boolean | O | If true , FastPay will not request for the user’s email address and name upon a new user sign up, and proceed directly to the checkout page. Default: false . |
test | boolean | O | If true , the API will return a mock payment page that the vendor can use for testing a payment without actual payment details. Default: false . |
Order Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
id | string | R | Unique order ID from the vendor. |
currency | string | R | Currency. |
discount_total | string | R | Total discounted amount. |
total | string | R | Total order amount before discount. |
tax_total | string | R | Total tax amount. |
line_items | array of object | R | List of line items. |
Line Item Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
name | string | R | Product name. |
product_id | string | R | Unique product ID. |
variation_id | string | R | Unique product variation's ID. |
image | string | R | Image URL. |
currency | string | R | Currency |
price | string | R | Price of a single item. |
subtotal | string | R | Subtotal amount. |
quantity | string | R | Quantity of items. |
total_tax | string | R | Total tax amount. |
Usage of omni_ref
in Redirect URL
Upon payment completion on FastPay’s payment page, the user will be redirected to the vendor’s website as specified by the parameter
redirect_url
in this API.FastPay will append encrypted transaction details to the specified
redirect_url
in the form of parameteromni_ref
.
Example:
The value of
omni_ref
is encrypted with AES; therefore, the vendor must decryptomni_ref
to obtain basic transaction details. These details are the transaction’sreceipt_id
,omni_reference
,status
, andtotal_amount_cents
.The algorithm used for the encryption is AES-128 CBC Mode, PCKS7 Padding.
Example:
The
omni_ref
can be decrypted by using the vendor’s API key (secret key). In this example, the API key (secret key),d25f1p1zf6ww8eja
is used to decrypt theomni_ref
.After decryption of the
omni_ref
with private key provided to the vendor (d25f1p1zf6ww8eja
), the transaction details would be as follows:
Reference:
https://www.devglan.com/online-tools/aes-encryption-decryption
Transactions API V2
Each merchant’s configuration and each transaction may be different, some of the transaction values may be null
.
Receipt ID can be 9 digits or 30 digits alphanumeric string depending on the source of the transaction.
Available statuses:
Status | Status Code |
---|---|
pending_payment | 0 |
payment_processing | 1 |
successful | 2 |
disputed | 3 |
rejected | 4 |
refunded | 5 |
Transaction Object V2
All calls under Transaction API will return the transaction object.
JSON response example:
Note : this is a sample transaction and values might not be entirely accurate.
{
"id": "FP_792619",
"created_at": "2021-03-26T18:14:59.698+08:00",
"omni_reference": "PL-0001",
"receipt_id": "0118-7347",
"merchant_name": "Cafe Testa",
"merchant_id": "1166",
"outlet_id": "1593",
"user_id": "2818771",
"currency": "MYR",
"total_amount_cents": "2100",
"payment_type": "Credit_card",
"payment_type_variant": "Visa",
"status": "successful",
"status_code": "2",
"failure_reason": "",
"promo_code": "apicbpartner2",
"promo_code_value_cents": "200",
"charged_amount_cents": "1550",
"payment_method_fee_percentage": "1",
"payment_method_fee_cents": "2",
"minimum_fee_applied": true,
"sst_on_total_fees_cents": "1",
"merchant_takeback_cents": "1881",
"ipp_details": {
"bank_name": "Maybank",
"tenure": "12",
},
"sign":"fc12259055f146e8bf0b587cbd8dbb9283e4db6a525243bc608e5762e43c6b29"
}
Field | Description |
---|---|
id |
Unique identifier for each transaction |
created_at |
Date and time of transaction |
omni_reference |
Unique reference number generated by FastPay partner as reference to reconcile for both FastPay and partner systems |
receipt_id |
Unique identifier for the receipt generated by FastPay for the transaction |
outlet_id |
Unique identifier for the outlet where the payment was made |
outlet_name |
Outlet name where the payment was made |
merchant_id |
Unique identifier for the merchant who received the payment |
merchant_name |
Name of merchant who received the payment |
user_id |
Unique identifier for the user who made the payment |
currency |
Currency used for the transaction |
total_amount_cents |
Total amount paid in cents |
payment_type |
Payment method used for the transaction, such as credit card or paypal |
payment_type_variant |
Specific type of payment method used, such as Visa or Mastercard |
status |
Status of transaction, refer here |
status_code |
Represents the status of the transaction, refer here |
failure_reason |
Reason why the transaction failed, if applicable |
promo_code |
Promo code used for the transaction, if applicable |
promo_code_value_cents |
Promo code discount amnt |
charged_amount_cents |
Amount charged to the user's payment method in cents |
payment_method_fee_percentage |
Percentage of fees charged by the payment method for the transaction in cents |
payment_method_fee_cents |
Amount of fees charged by the payment method for the transaction in cents |
minimum_fee_applied |
Minimum fee is applied to transactions if it returns true |
sst_on_total_fees_cents |
Sales and Service Tax(SST) mandated government tax charged on the total fees in cents by country |
merchant_takeback_cents |
Total amount merchant will receive |
sign |
To verify the integrity of the payload |
ipp_details |
Details of the Instalment Payment Plans(IPP) |
bank_name |
Bank name associate with the IPP |
tenure |
Length of the IPP tenure |
For security reasons, Vendors should use the sign
parameter value in the payload above to verify our payload integrity. Please refer to Appendix C for the details. Do note that only the transaction object in the webhook callback will contain the sign parameter for payload verification.
API: Get a transaction V2
The transaction status can be retrieved either by the omni_reference
or by the receipt_id
.
/api/fastpay/v2/my/transactions
curl \
--location \
--request \
GET 'https://omni.app.fave.ninja/api/fastpay/v2/my/transactions?app_id=f0l6wkqzfn&omni_reference=WCM-1667541435030&sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7'
var axios = require('axios');
axios.get('/api/fastpay/v2/my/transactions', {
params: {
'app_id': 'f0l6wkqzfn',
'omni_reference': 'WCM-1667541435030',
'sign': '57c2af5432362011d1e2925d1ab2f6020313c7599e45e5d5840c7d607363e340',
}
})
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
$client = new Client();
$request = new Request('GET', 'https://omni.app.fave.ninja/api/fastpay/v2/my/transactions?app_id=f0l6wkqzfn&omni_reference=WCM-1667541435030&sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7');
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
import requests
url = "https://omni.app.fave.ninja/api/fastpay/v2/my/transactions?app_id=f0l6wkqzfn&omni_reference=WCM-1667541435030&sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
response = requests.request("GET", url)
print(response.text)
require "uri"
require "net/http"
url = URI("https://omni.app.fave.ninja/api/fastpay/v2/my/transactions?app_id=app_id here&omni_reference=WCM-1667541435030&sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
response = https.request(request)
puts response.read_body
Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
receipt_id | string | CR | Fave receipt_id as displayed on the app. |
omni_reference | string | CR | The omni_reference is the unique reference string provided by the vendor for the transaction. |
app_id | string | R | Vendor ID issued by Fave |
sign | string | R | API request signature |
Transaction Response
Errors
Name | Description | Possible Reasons |
---|---|---|
resource_not_found |
The resource provided is not found or invalid. |
|
validation |
There is an issue with the validation of the request parameters. |
|
Unauthorized |
The request is not authorised or there is an issue with the request. |
|
Note: The API may return an unauthorized
request error if the provided receipt_id
or omni_reference
does not exist in our database records.
API: Transaction History V2
The Transaction History API returns a list of transaction objects that match the query criteria. The vendor can use this API either with a limit or with a timestamp. When the limit
parameter is provided, the API will return the n last transactions associated with the given outlet_id
. The timestamp parameter used to retrieve all the transactions between the timestamp and current time.
/api/fastpay/v2/:country_code/transactions/history
curl \
--location \
--request GET 'https://omni.app.fave.ninja/api/fastpay/v2/my/transactions/history?sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7&app_id=f0l6wkqzfn'
var axios = require('axios');
axios.get('/api/fastpay/v2/my/transactions/history', {
params: {
'app_id': 'f0l6wkqzfn',
'sign': '57c2af5432362011d1e2925d1ab2f6020313c7599e45e5d5840c7d607363e340',
'timestamp' : '1640994222'
'outlet_id' : '21111'
}
})
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
$client = new Client();
$request = new Request('GET', 'https://omni.app.fave.ninja/api/fastpay/v2/my/transactions/history?sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7&app_id=f0l6wkqzfn');
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
import requests
url = "https://omni.app.fave.ninja/api/fastpay/v2/my/transactions/history?sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7&app_id=f0l6wkqzfn"
response = requests.request("GET", url)
print(response.text)
require "uri"
require "net/http"
url = URI("https://omni.app.fave.ninja/api/fastpay/v2/my/transactions/history?sign=133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7&app_id=app_id here")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Get.new(url)
response = https.request(request)
puts response.read_body
Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
app_id | string | R | Vendor ID issued by Fave |
limit | integer | CR | The number of transactions to return. Default: 10 Max-value: 1000" |
timestamp | integer | CR | Filter the result by transaction timestamp. Default: null Format: Unix Timestamp. The timestamp must not be earlier than one month. |
ack | boolean | O | Filter the result by acknowledgement status. Filter out the acknowledged transactions when the value is false. Default: true |
sign | string | R | API request signature |
outlet_id | integer | CR | Outlet id signature |
Transaction Response
Errors
Name | Description | Possible Reasons |
---|---|---|
resource_not_found |
The resource provided is not found or invalid. | The outlet_id provided is not valid. |
validation |
There is an issue with the validation of the request parameters. |
|
Unauthorized |
The request is not authorised or there is an issue with the request. |
|
error |
There is no result for the request given. | No records match the query. |
API: Refund a transaction V2
A POST request can make a refund request with the request body containing the omni_reference
and the refund status. This API is idempotent; any call after the first successful call will directly return the status. The transaction only can be refunded through this API within 24 hours. Any request that comes after that will receive a stale_transaction
error.
/api/fastpay/v2/my/transactions
curl \
--location \
--request POST 'https://omni.app.fave.ninja/api/fastpay/v2/my/transactions' \
--header 'Content-Type: application/json' \
--data-raw '{
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
}'
var axios = require('axios');
var data = JSON.stringify({
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
});
axios.post('/api/fastpay/v2/my/transactions', data)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
$client = new Client();
$headers = [
'Content-Type' => 'application/json'
];
$body = '{
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
}';
$request = new Request('POST', 'https://omni.app.fave.ninja/api/fastpay/v2/my/transactions', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
import requests
import json
url = "https://omni.app.fave.ninja/api/fastpay/v2/my/transactions"
payload = json.dumps({
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
require "uri"
require "json"
require "net/http"
url = URI("https://omni.app.fave.ninja/api/fastpay/v2/my/transactions")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/json"
request.body = JSON.dump({
"omni_reference": "WCM-1667541435030",
"app_id": "f0l6wkqzfn",
"status": "refunded",
"sign": "133b8f8aeec227c2613f53c691c13b96805ec6bcc67e3dac3af6c6a702e3dbb7"
})
response = https.request(request)
puts response.read_body
Parameters:
Name | Type | R/CR/O | Description |
---|---|---|---|
omni_reference | string | R | The omni_reference is the unique reference string provided by the vendor for the transaction. First introduced in the QR code API request. |
app_id | string | R | Vendor ID issued by Fave. |
status | string | R | Transaction status. Accepted values: refunded |
partial_refund_cents | integer | O | Partial refund amount. This is only applicable for FavePayment. If this parameter is not provided, a full refund will be performed. |
sign | string | R | API request signature. |
Transaction Response
Errors
Name | Description | Possible Reasons |
---|---|---|
resource_not_found |
The resource provided is not found or invalid. | The omni_reference provided is not valid. |
validation |
There is an issue with the validation of the request parameters. | The status provided is not valid. The only accepted value is refunded. partial_refund_cents exceeds the transaction’s charged_amount_cents . |
Unauthorized |
The request is not authorised or there is an issue with the request. | Signature is incorrect. |
stale_transaction |
The request was made more than 24 hours after the transaction was created. | Refund attempt was made after 24 hours of transaction creation. Transaction can no longer be refunded. |
failed_request |
The request failed. | Refund request failed. |
unexpected_error |
The request was rejected. | Refund request rejected. |
API Errors
The FastPay API will return an error response if anything goes wrong with the vendor’s API call.
Request Checkout Link API Error Object
Every error response of the Request Checkout Link API will consist of code
, message
,
error_type
, and attributes
to provide a brief explanation of why the error was triggered.
The code
returned here refers to the HTTP error code, which is further mentioned below.
Example (JSON)
{
"code": "500",
"message": "Internal server error",
"error_type": "update_order#not_found",
"attributes": "base"
}
Name | Type | Description | Example |
---|---|---|---|
code | string | HTTP error code. | 500 |
message | string | Extensive description of what could have potentially caused the error. | Internal server error |
error_type | string | Brief description of what could have potentially caused the error. Not present for all errors. | update_order#not_found |
attributes | string | Error metadata. | base |
Transaction APIs Error Object
Every error response of the Transaction APIs will consist of error
, and error_description
to
provide a brief explanation of why the error was triggered. An error status will also be returned.
The Transaction APIs are Get a Transaction, Transaction History, and Refund a Transaction.
Example (JSON)
{
"error": "internal_error",
"error_description": "Unable to acknowledge the transaction"
}
The error status refers to the HTTP error code, which is further mentioned below.
Name | Type | Description | Example |
---|---|---|---|
error | string | Name of the error. | internal_error |
error_description | string | Description of the error. | Unable to acknowledge the transaction |
HTTP Error Codes
The Fast Pay API response will return specific HTTP status codes to indicate a failed request.
Error codes in the range of 4xx
indicate an issue with the vendor’s request, and error codes in
the range of 5xx
indicate an issue with FastPay’s server.
Name | Description | Action |
---|---|---|
400 Bad Request | There are parameter errors or the request cannot be fulfilled. | Ensure the request is formatted properly and all necessary parameters are present. |
401 Unauthorized | The request does not have a valid app_id or the signature in the request is wrong. |
Ensure the app_id and signature provided are correct. |
404 Not Found | The resource_not_found error is present. The ID provided is not valid. Either the resource does not exist or an ID for a different resource has been provided. |
Ensure the requested resource exists. |
500 Internal Server Error | The server encountered an unexpected condition that prevented it from fulfilling the request. | Please try again later |
Appendix
Appendix A: Signature Generation for Request Checkout Link API
The signature generated below will be used in the Request Checkout Link API request sign parameter.
Steps to generate sign
Make a copy of the request’s JSON payload (do not include the
sign
parameter).Minify the JSON payload. Assuming the JSON is:
{ "omni_reference": "PL-0001", "total_amount_cents": 1000, "app_id": "a3osyvuayx", "outlet_id": 6, "skip_shipping": true }
Minify the JSON to (note that thesign
parameter is not present):{"omni_reference":"PL-0001","total_amount_cents":1000,"app_id":"a3osy vuayx","outlet_id":6,"skip_shipping":true}
Easily minify the JSON payload with this online tool.Use the SHA256 algorithm to hash the minified JSON with the
secret key
provided by FastPay. Assuming the secret key issomesecretkey
, the signature generated will be as such:3348219bc84c2a2a650cd803e456a382390c6696621a355393c70f6c34c97211
.
You can verify the signature with this online tool.Append the signature generated in step 3 into the original JSON under the
sign
parameter:{ "omni_reference": "PL-0001", "total_amount_cents": 1000, "app_id": "a3osyvuayx", "outlet_id": 6, "skip_shipping": true, "sign": "3348219bc84c2a2a650cd803e456a382390c6696621a355393c70f6c34c97211" }
Appendix B: Signature Generation for Transaction APIs
The signature generated below will be used in the Transaction APIs request sign
parameter.
The Transaction APIs are Get a Transaction, Transaction History, and Refund a Transaction.
Steps to generate sign
Make a copy of the request’s parameters (do not include the
sign
parameter)."omni_reference": "PL-0001" "app_id": "a3osyvuayx" "status": "refunded"
Build the string of the parameters. Assuming the string is:
omni_reference=PL-0001&app_id=a3osyvuayx&status=refunded
Note:- The order of parameters for the string must be in the same order as listed under each API’s Request Parameters.
Use the HMAC-SHA256 algorithm to hash the parameters with the secret key provided by FastPay. Assuming the secret key is
somesecretkey
, the signature generated will be as such:4f1bd5f2119cb87364f0e0e4dcea7c425ba6281c79f96219b2c591c559e920c4
.
You can verify the signature with this online tool.Append the signature generated in step 3 into the request’s parameters under the sign parameter:
"omni_reference": "PL-0001" "app_id": "a3osyvuayx" "status": "refunded" "sign": "4f1bd5f2119cb87364f0e0e4dcea7c425ba6281c79f96219b2c591c559e920c4"
Appendix C : Transaction Payload Verification
The value of the sign
parameter is computed using the HMAC-SHA256 algorithm. To verify the integrity of our payload, the Vendor should generate an HMAC-SHA256 hash using the private api key (secret key) provided by Fave, combined with the URL safe encoded content body of the payload at the Vendor’s end and compare against the value of the sign
returned in the payload.
Steps to generate sign:
Transaction Payload Example:
{
"id": "FP_792619",
"receipt_id": "0118-7347",
"outlet_name": "TTDI Shop",
"total_amount_cents": "2100",
"currency": "MYR",
"outlet_id": "1593",
"mid": "1166",
"omni_reference": "PL-0001",
"status": "successful",
"status_code": "2",
"created_at": "2021-03-26T18:14:59.698+08:00",
"campaign_credit_amount_cents": "0",
"campaign_funded_by": "N/A",
"aabig_points_used_amount_cents": "0",
"merchant_cashback_amount_cents": "350",
"fave_credits_amount_cents": "200",
"promo_code_value_cents": "0",
"e_card_credits_used_cents": "0",
"charged_amount_cents": "1550",
"cashback_rate": "0.0",
"merchant_cashback_issued_cents": "0",
"promo_code": "apicbpartner2",
"promo_code_cashback_value": "2.00",
"promo_code_cashback_type": "absolute_cashback",
"promo_code_cashback_issued_cents": "200",
"promo_code_cashback_funded_by": "merchant",
"fave_fees_percentage": "1.0",
"fave_fees_cents": "18",
"sst_on_total_fees_cents": "1",
"merchant_takeback_cents": "1881",
"user_id": "2818771",
"fpl_transaction": "false",
"fpl_fees_percentage": "N/A",
"fpl_fees_cents": "N/A",
"fpl_merchant_cashback_reduction_percentage": "N/A",
"sign": "fc12259055f146e8bf0b587cbd8dbb9283e4db6a525243bc608e5762e43c6b29"
}
Make a copy of the JSON body (do not include the
sign
parameter).
id=FP_792619&receipt_id=0118-7347&outlet_name=TTDI+Shop&total_amount_cents=2100¤cy=MYR&outlet_id=1593&mid=1166&omni_reference=PL-0001&status=successful&status_code=2&created_at=2021-03-26T18%3A14%3A59.698%2B08%3A00&campaign_credit_amount_cents=0&campaign_funded_by=N%2FA&aabig_points_used_amount_cents=0&merchant_cashback_amount_cents=350&fave_credits_amount_cents=200&promo_code_value_cents=0&e_card_credits_used_cents=0&charged_amount_cents=1550&cashback_rate=0.0&merchant_cashback_issued_cents=0&promo_code=apicbpartner2&promo_code_cashback_value=2.00&promo_code_cashback_type=absolute_cashback&promo_code_cashback_issued_cents=200&promo_code_cashback_funded_by=merchant&fave_fees_percentage=1.0&fave_fees_cents=18&sst_on_total_fees_cents=1&merchant_takeback_cents=1881&user_id=2818771&fpl_transaction=false&fpl_fees_percentage=N%2FA&fpl_fees_cents=N%2FA&fpl_merchant_cashback_reduction_percentage=N%2FA
Build the string of the content body. Assuming the JSON body is:
id=FP_792619&receipt_id=0118-7347&outlet_name=TTDI+Shop&total_amount_ cents=2100¤cy=MYR&outlet_id=1593&mid=1166&omni_reference=PL-000 1&status=successful&status_code=2&created_at=2021-03-26T18%3A14%3A59. 698%2B08%3A00&campaign_credit_amount_cents=0&campaign_funded_by=N%2FA &aabig_points_used_amount_cents=0&merchant_cashback_amount_cents=350& fave_credits_amount_cents=200&promo_code_value_cents=0&e_card_credits _used_cents=0&charged_amount_cents=1550&cashback_rate=0.0&merchant_ca shback_issued_cents=0&promo_code=apicbpartner2&promo_code_cashback_va lue=2.00&promo_code_cashback_type=absolute_cashback&promo_code_cashba ck_issued_cents=200&promo_code_cashback_funded_by=merchant&fave_fees_ percentage=1.0&fave_fees_cents=18&sst_on_total_fees_cents=1&merchant_ takeback_cents=1881&user_id=2818771&fpl_transaction=false&fpl_fees_pe rcentage=N%2FA&fpl_fees_cents=N%2FA&fpl_merchant_cashback_reduction_p ercentage=N%2FA
Note:- Use
+
instead of%20
for white spaces. For example:TTDI Shop
will be encoded toTTDI+Shop
instead ofTTDI%20Shop
. - The order of parameters for the string must be in the same order as the example provided above.
- Use
Use the HMAC-SHA256 algorithm to hash the content body with the secret key provided by FastPay. Assuming the secret key is
d25f1p1zf6ww8eja
, the signature generated will be as such:fc12259055f146e8bf0b587cbd8dbb9283e4db6a525243bc608e5762e43c6b29
.
You can verify the signature with this online tool.
Frequently Asked Questions (FAQ)
1. Q: The vendor has difficulty decrypting FastPay redirect_url
appended parameters.
Vendor may test using openssl command line like so:
# write the encrypted string to a file
cat
"bcpyuNt2/9us2qKvi+mf3WpVjlrx3nZ4UDo5PNY9I5fbK/seb9fiErkmck4ItMSNjAQi
KSP4lO3TnTY/Zl3URVwRKsvI5ITMxmoADgyPRfYmnDiek9CcTrOWyXHWnnlYKCSqxtwnS
+8Qe3AA27cysg==" > string.txt
# convert secret key to hexadecimal (use online tool such as
# https://www.devglan.com/online-tools/aes-encryption-decryption)
# eg. nwgv9juqpb9tjjbi -> 6E776776396A7571706239746A6A6269
# Run the following to decrypt
cat string.txt | openssl enc -d -aes-128-cbc -K
6E776776396A7571706239746A6A6269 -iv 0000000000000000 -nosalt -base64
-A
# You should see the decrypted string below
receipt_id=0740-9849&omni_reference=2C2P-Test150622172810166&status=r
ejected&total_amount_cents=131000
A: Check FastPay encryption details.
The details are as so:
- AES-128 CBC mode
- PCKS7 padding
- No IV (or 16-byte of 0. eg. 0000000000000000)
2. Q: Is the item’s weight/dimension or location taken into consideration for shipping options?
A: No, FastPay currently only supports a fixed fee shipping option.