Introduction
The Xfers Core API provides a set of simple RESTFUL APIs to allow businesses to integrate internet banking and credit card payments into your business or applications.
You will make use of the Xfers Core API to manage your own account programmatically.
Xfers Connect is for accepting payments on behalf of others, think of this as a super user that can manage and create accounts on the behalf of others.
Official SDKs for the Xfers API are available in several languages.
Integration Guides
Here are a list of diagrams to guide your integration with Xfers:
API endpoints
Xfers provides a dedicated sandbox environment where you can simulate an incoming bank transfer for testing purposes. Note that this feature will not be available in production mode. Refer to the testing section to get started.
<?php
require_once('vendor/autoload.php');
# SG: Singapore
# ID: Indonesia
# Set one of the following endpoints below:
\Xfers\Xfers::setSGProduction();
\Xfers\Xfers::setSGSandbox();
\Xfers\Xfers::setIDProduction();
\Xfers\Xfers::setIDSandbox();
# SG: Singapore
# ID: Indonesia
# Set one of the following endpoints below:
import xfers
xfers.set_sg_production()
xfers.set_sg_sandbox()
xfers.set_id_production()
xfers.set_id_sandbox()
# SG: Singapore
# ID: Indonesia
# Set one of the following endpoints below:
require 'xfers'
Xfers.set_sg_production
Xfers.set_sg_sandbox
Xfers.set_id_production
Xfers.set_id_sandbox
// SG: Singapore
// ID: Indonesia
// Set one of the following endpoints below:
Xfers.setSGProduction();
Xfers.setSGSandbox();
Xfers.setIDProduction();
Xfers.setIDSandbox();
For testing purposes, we highly recommend that your head over to sandbox.xfers.io and create a sandbox account.
While in testing mode, point to our sandbox API endpoint at:
Singapore:
https://sandbox.xfers.io/api/v3
Indonesia:https://sandbox-id.xfers.com/api/v3
To switch to production, point to our production API endpoint at:
Singapore: https://www.xfers.io/api/v3
Indonesia: https://id.xfers.com/api/v3
Note that all API calls are done through HTTPS, please do not attempt to hit our endpoint via HTTP, as you will also be exposing your API key in plain text.
Xfers Connect
Introduction
Xfers Connect is the first set of APIs used by our partners to gain authorisation to either:
- Directly interact with our users’ Xfers account
- Host private-wallet solutions on Xfers
You can find a typical integration flow of Xfers Connect.
Authentication
Xfers Connect uses a pair of API Keys and API Secret to access its APIs.
Write in to us at support@xfers.io to request for your Xfers Connect API Keys.
You will provided with a pair of keys named X-XFERS-APP-API-KEY
and X-XFERS-APP-SECRET-KEY
.
Xfers Connect expects the API key to be included in the “Signup/login to Xfers” and “Get User API Token” process to look like the following:
X-XFERS-APP-API-KEY: yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ
These keys are different from the usual API keys which you include in the X-XFERS-USER-API-KEY
header. App Connect API keys are only used for the Xfers Connect APIs. Thus instead of X-XFERS-USER-API-KEY: YOUR-NORMAL-USER-API-KEY
, you pass in X-XFERS-APP-API-KEY: THE-APP-API-KEY
as the header instead.
Signup/login to Xfers
curl "https://sandbox.xfers.io/api/v3/authorize/signup_login"\
-H "X-XFERS-APP-API-KEY: yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ"\
-H "Content-Type: application/json" \
-d '{"phone_no" : "+65XXXXXXXX", "signature" : "178502abfa891b69a9a2f72192d51f5fc141f978"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setSGSandbox();
$xfers_app_api_key = 'yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ';
try {
$resp = \Xfers\Connect::authorize(array(
'phone_no' => '+65XXXXXXXX',
'signature' => '178502abfa891b69a9a2f72192d51f5fc141f978'
), $xfers_app_api_key);
print_r($resp);
} catch (\Xfers\Error\Api $e) {
echo 'Caught Api exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfconnect
from xfers import error
xfers.set_sg_sandbox()
XFERS_APP_API_KEY = 'yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ'
try:
print 'Authorizing connect...'
params = {
'phone_no': '+65XXXXXXXX',
'signature': '178502abfa891b69a9a2f72192d51f5fc141f978'
}
resp = xfconnect.authorize(params, XFERS_APP_API_KEY)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_sg_sandbox
XFERS_APP_API_KEY = 'yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ'
begin
puts 'Authorizing connect...'
params = {
'phone_no'=> '+65XXXXXXXX',
'signature'=> '178502abfa891b69a9a2f72192d51f5fc141f978'
}
resp = Xfers::Connect.authorize params, XFERS_APP_API_KEY
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
Xfers.setSGSandbox();
String xfersAppApiKey = "yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ";
String xfersAppSecretKey = "178502abfa891b69a9a2f72192d51f5fc141f978";
try {
System.out.println("Authorizing");
Map<String, Object> params = new HashMap<String, Object>();
params.put("phone_no", "+65XXXXXXXX");
Response response = Connect.authorize(params, xfersAppApiKey, xfersAppSecretKey);
System.out.println(response.getMsg());
} catch (Exception e) {
e.printStackTrace();
}
Response
{
"msg": "success"
}
This API call will attempt to login(existing user) or signup a new user.
An SMS with a OTP will be send to that number which must be used for get_token api call.
HTTPS Request
POST https://sandbox.xfers.io/api/v3/authorize/signup_login
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
phone_no | string | required | User mobile no | +65XXXXXXXX |
signature | string | required | SHA1-hex of (phone_no + APP_SECRET_KEY) | Phone Number: Secret Key: Signature: 178502abfa891b69a9a2f72192d51f5fc141f978 |
Get User API Token
curl "https://sandbox.xfers.io/api/v3/authorize/get_token?otp=541231&phone_no=%2B65XXXXXXXX&signature=bdc26373b3a78dd11dc840a1b7973f197cf34c91" \
-H "X-XFERS-APP-API-KEY: yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ"
# You can now change the X-XFERS-USER-API-KEY to the returned user_api_token
# and make API calls on behalf of the connect user.
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setSGSandbox();
$xfers_app_api_key = 'yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ';
try {
$resp = \Xfers\Connect::getToken(array(
'otp' => '541231',
'phone_no' => '+65XXXXXXXX',
'signature' => '178502abfa891b69a9a2f72192d51f5fc141f978',
'return_url' => 'https://mywebsite.com/api/v3/account_registration/completed'
), $xfers_app_api_key);
print_r($resp);
# You can now call \Xfers\Xfers::setApiKey again to change the X-XFERS-USER-API-KEY to the returned user_api_token
# and make API calls on behalf of the connect user.
$user_api_token = $resp['user_api_token'];
\Xfers\Xfers::setApiKey($user_api_token);
$resp = \Xfers\User::retrieve();
} catch (\Xfers\Error\Api $e) {
echo 'Caught Api exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfconnect
from xfers import xfuser
from xfers import error
xfers.set_sg_sandbox()
XFERS_APP_API_KEY = 'yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ'
try:
print 'Getting token...'
params = {
'otp': '541231',
'phone_no': '+65XXXXXXXX',
'signature': '178502abfa891b69a9a2f72192d51f5fc141f978',
'return_url': 'https://mywebsite.com/api/v3/account_registration/completed'
}
resp = xfconnect.get_token(params, XFERS_APP_API_KEY)
print resp
# You can now set xfers.api_key again to change the X-XFERS-USER-API-KEY to the returned user_api_token
# and make API calls on behalf of the connect user.
xfers.api_key = resp['user_api_token']
connected_user = xfuser.retrieve()
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_sg_sandbox
XFERS_APP_API_KEY = 'yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ'
begin
puts 'Getting connect token...'
params = {
'otp'=> '541231',
'phone_no'=> '+65XXXXXXXX',
'signature'=> '178502abfa891b69a9a2f72192d51f5fc141f978',
'return_url'=> 'https://mywebsite.com/api/v3/account_registration/completed'
}
resp = Xfers::Connect.get_token params, XFERS_APP_API_KEY
user_api_token = resp[:user_api_token]
puts resp
# You can now call Xfers.set_api_key again to change the X-XFERS-USER-API-KEY to the returned user_api_token
# and make API calls on behalf of the connect user.
Xfers.set_api_key user_api_token
connect_user = Xfers::User.retrieve
puts connect_user[:first_name]
puts connect_user[:last_name]
puts connect_user[:available_balance]
puts connect_user
rescue Xfers::XfersError => e
puts e.to_s
end
Xfers.setSGSandbox();
String xfersAppApiKey = "AeWpKz5cdPoJFUwF53sBee_WsSoqym_hspiX3bcoB_Y";
String xfersAppSecretKey = "yyyMATdkKiv2s9ZQVQ-C1x2RY4xF928xnrUagfQwXaQ";
try {
System.out.println("Getting token");
Map<String, Object> params = new HashMap<String, Object>();
params.put("otp", "541231");
params.put("phone_no", "+65XXXXXXXX");
params.put("return_url", "https://mywebsite.com/api/v3/account_registration/completed");
Response response = Connect.getToken(params, xfersAppApiKey, xfersAppSecretKey);
System.out.println(response.getMsg());
System.out.println(response.getUserApiToken());
System.out.println(response.getSignUpUrl());
// You can now set Xfers.apiKey again to change the X-XFERS-USER-API-KEY to the returned user_api_token
// and make API calls on behalf of the connect user.
Xfers.apiKey = response.getUserApiToken();
System.out.println("Retrieving connected user");
User user = User.retrieve();
} catch (Exception e) {
e.printStackTrace();
}
Response
{
"msg": "success",
"user_api_token": "1DnsZkv3qXwKx4EAdps8AJ8jXCPsxP2sKSygMHTAFLM",
"sign_up_url" : "https://sandbox.xfers.io/api/v3/account_registration?phone_no=%2B65XXXXXXXX&token=4014d3e9f0600f78dbfabd86036de7b008f70c52"
}
This API call will return the user’s user_api_token
. You should save this token in database for reuse. There is no need to go through the connect flow again for this user.
It will also return a sign_up_url
if and ONLY IF they do not already have an Xfers account. The url can be loaded to serve a page that allow user to complete their Xfers account registration (this is optional and is only needed if the user wants to login to their Xfers Dashboard).
It will also return a is_fully_verified
if and ONLY IF they already have an Xfers account and have completed our KYC process.
If you choose to redirect new Xfers user to the unique sign_up_url to allow them to complete their Xfers account registrations, upon successfully account registration, Xfers will redirect user back to the return_url
specified or the default at “<Endpoint>/api/v3/account_registration/completed”. The automated SMS from Xfers will not be sent if user complete their account registration this way within 15mins.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/authorize/get_token?otp=541231&phone_no=%2B65XXXXXXXX&signature=bdc26373b3a78dd11dc840a1b7973f197cf34c91
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
otp | string | required | 6 digit one-time-password send over SMS | 541231 |
phone_no | string | required | User mobile no | +65XXXXXXXX |
signature | string | required | SHA1-hex of (phone_no + OTP + APP_SECRET_KEY) | Phone Number: OTP: Secret Key: Signature: a972388d58c1443295cb89cc9c6f59789630a45f |
return_url | string | optional | Url that new user will be redirected after they completed Xfers account registration at sign_up_url provided. |
Default “<Endpoint>/api/v3/account_registration/completed” |
/authorize/signup_login
- SHA1-hex of (phone_no + APP_SECRET_KEY)
/authorize/get_token
- SHA1-hex of (phone_no + OTP + APP_SECRET_KEY)
What’s Next
Now that you have gotten a user_api_token
linked to your customer, you can
- Pass this
user_api_token
as params when creating a charge to bypass authentication for your customer - Pass this
user_api_token
as params when adding and charging credit cards cards - Pass this
user_api_token
as params when creating a payout in place of the recipient field - Use the header
"X-XFERS-USER-API-KEY": "the user_api_token"
(instead of"X-XFERS-USER-API-KEY": "your own token"
) to modify user details and bank accounts on behalf of your user
Xfers Core
Introduction
The Xfers Core API provides a set of simple RESTFUL APIs to allow businesses to integrate internet banking and credit card payments into your business or applications.
You will make use of the Xfers Core API to manage your own account programmatically.
Authentication
Setting API keys
# With shell, you can just pass the correct header with each request
curl "https://sandbox.xfers.io/api/v3/authorize/hello" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
import xfers
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
Xfers.apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
Make sure to replace
2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk
with your own API key.
Xfers uses API keys to allow access to the API. You can get your API key from your Account Settings page.
Xfers expects the API key to be included in the header of all API requests to the server, like so:
X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk
HTTPS Request
GET https://sandbox.xfers.io/api/v3/authorize/hello
Types of API Keys
Type | Version | Description |
---|---|---|
X-XFERS-APP-API-KEY | V3 | Only used for Xfers Connect |
X-XFERS-USER-API-KEY | V3 | The majority of our APIs uses this |
X-XFERS-USER-API-KEY | V2 (Legacy) | Our legacy V2 API keys. These are only used for our WooCommerce, Opencart and Magento plugins. |
User Account
The account info API supports querying and making changes to a User’s account.
Get Account Info
curl "https://sandbox.xfers.io/api/v3/user" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
$resp = \Xfers\User::retrieve();
print_r($resp);
import xfers
from xfers import xfuser
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Retrieving user...'
resp = xfuser.retrieve()
print resp['available_balance']
bank_accounts = resp['bank_accounts']
for account in bank_accounts:
print 'Bank account: {}'.format(account)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Retrieving user...'
resp = Xfers::User.retrieve
puts resp[:available_balance]
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Retrieving current user");
User user = User.retrieve(apiKey);
for (BankAccount bankAccount : user.getBankAccounts()) {
System.out.println(bankAccount.toString());
}
System.out.println(user.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response (SG):
{
"id": "user_gksj43jgzgqv",
"available_balance":"37387.3",
"ledger_balance":"37387.3",
"bank_transfer_rates":"0.0",
"bank_transfer_fees":"0.45",
"phone_no":"+6591240987",
"full_name": "Luther Tan",
"first_name":"Luther",
"last_name":"Tan",
"date_of_birth":"1995-05-21",
"gender":"",
"email":"luther@gmail.com",
"country":"SG",
"nationality":"Singaporean",
"address_line_1":"PASIR RIS DRIVE 1",
"address_line_2":"04-180",
"postal_code":"510608",
"identity_no":"S9539495J",
"bank_accounts":[
{
"id": 399,
"account_no": "9484853433",
"account_holder_name": "Luther Tan",
"verification_status": "pending",
"bank_abbrev": "DBS",
"usage": "all"
}
],
"annual_income":"",
"id_front":"my_id_front.jpg",
"id_back":"my_id_back.jpg",
"selfie_2id":"nricSelfiePlaceholder.png",
"proof_of_address":"my_proof_of_address.pdf",
"multi_bank_account_detected":false,
"account_locked":false,
"google_auth_enabled":false,
"kyc_limit_remaining":120000.0,
"kyc_verified":true,
"meta_data":"",
"wallet_name":"Your General Wallet Account",
"wallet_id": 1
}
Response (ID):
{
"id": "user_gksj43jgzgqv",
"available_balance":"37387.3",
"ledger_balance":"37387.3",
"bank_transfer_rates":"0.0",
"bank_transfer_fees":"0.45",
"phone_no":"+6591240987",
"first_name":"Bobby",
"last_name":"Keong",
"date_of_birth":"1995-05-21",
"gender":"",
"email":"bobby@gmail.com",
"country":"SG",
"nationality":"Singaporean",
"address_line_1":"TAMBUN UTARA",
"address_line_2":"KABUPATEN BEKASI",
"postal_code":"510608",
"identity_no":"1212121200050006",
"bank_accounts":[
{
"id": 399,
"account_no": "9484853433",
"account_holder_name": "Bobby Keong",
"verification_status": "pending",
"bank_abbrev": "BCA",
"usage": "all"
}
],
"annual_income":"",
"id_front":"my_id_front.jpg",
"selfie_2id":"nricSelfiePlaceholder.png",
"account_locked":false,
"google_auth_enabled":false,
"kyc_verified":true,
"meta_data":"",
"place_of_birth":"Malang",
"blood_type":"B",
"rt_rw":"011/017",
"administrative_village":"Penjaringan",
"district":"Pluit",
"religion":"Buddhism",
"marital_status":"Married",
"occupation":"007 | Konsultan"
}
This endpoint return information related to your account such as available balance, ledger balance, name and bank account information.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/user
Update Account Info
curl "https://sandbox.xfers.io/api/v3/user" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-X PUT \
-d '{"first_name": "wenbin", "last_name": "tay", "address_line_1": "Blk 712 loyang Avenue 5", "address_line_2": "#01-41", "nationality": "Singaporean", "postal_code": "340712", "identity_no": "s86917127G", "country": "sg"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
$resp = \Xfers\User::update(array(
'first_name' => 'wenbin',
'last_name' => 'tay',
'address_line_1' => 'Blk 712 loyang Avenue 5',
'address_line_2' => '#01-41',
'nationality' => 'Singaporean',
'postal_code' => '340712',
'identity_no' => 's86917127G',
'country' => 'sg'
));
print_r($resp);
import xfers
from xfers import xfuser
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Updating user...'
params = {
'first_name': 'wenbin',
'last_name': 'tay',
'address_line_1': 'Blk 712 loyang Avenue 5',
'address_line_2': '#01-41',
'nationality': 'Singaporean',
'postal_code': '340712',
'identity_no': 's86917127G',
'country': 'sg'
}
resp = xfuser.update(params)
print resp['first_name']
print resp['last_name']
print resp['available_balance']
print resp['address_line_1']
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Updating user...'
params = {
'first_name' => 'wenbin',
'last_name' => 'tay',
'address_line_1' => 'Blk 712 loyang Avenue 5',
'address_line_2' => '#01-41',
'nationality' => 'Singaporean',
'postal_code' => '340712',
'identity_no' => 's86917127G',
'country' => 'sg'
}
resp = Xfers::User.update params
puts resp[:first_name]
puts resp[:last_name]
puts resp[:available_balance]
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Updating current user");
Map<String, Object> updateParams = new HashMap<String, Object>();
updateParams.put("first_name", "wenbin");
updateParams.put("last_name", "tay");
updateParams.put("address_line_1", "Blk 712 loyang Avenue 5");
updateParams.put("address_line_2", "#01-41");
updateParams.put("nationality", "Singaporean");
updateParams.put("postal_code", "340712");
updateParams.put("identity_no", "s86917127G");
updateParams.put("country", "sg");
User user = User.update(updateParams,apiKey);
System.out.println(user.getFirstName());
System.out.println(user.getLastName());
System.out.println(user.getDateOfBirth());
System.out.println(user.getMetaData());
System.out.println(user.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response (SG):
{
"id": "user_gksj43jgzgqv",
"available_balance":"37387.3",
"ledger_balance":"37387.3",
"bank_transfer_rates":"0.0",
"bank_transfer_fees":"0.45",
"phone_no":"+6591240987",
"first_name":"Bobby",
"last_name":"Keong",
"date_of_birth":"1995-05-21",
"gender":"",
"email":"bobby@gmail.com",
"country":"SG",
"nationality":"Singaporean",
"address_line_1":"PASIR RIS DRIVE 1",
"address_line_2":"04-180",
"postal_code":"510608",
"identity_no":"S9539495J",
"bank_accounts":[
{
"id": 399,
"account_no": "9484853433",
"account_holder_name": "John Tan",
"verification_status": "pending",
"bank_abbrev": "DBS",
"usage": "all"
}
],
"annual_income":"",
"id_front":"my_id_front.jpg",
"id_back":"my_id_back.jpg",
"selfie_2id":"nricSelfiePlaceholder.png",
"proof_of_address":"my_proof_of_address.pdf",
"multi_bank_account_detected":false,
"account_locked":false,
"kyc_limit_remaining":120000.0,
"kyc_verified":true,
"meta_data":"",
"wallet_name":"Xfers"
}
Response (ID):
{
"id": "user_gksj43jgzgqv",
"available_balance":"37387.3",
"ledger_balance":"37387.3",
"bank_transfer_rates":"0.0",
"bank_transfer_fees":"0.45",
"phone_no":"+6591240987",
"first_name":"Bobby",
"last_name":"Keong",
"date_of_birth":"1995-05-21",
"gender":"",
"email":"bobby@gmail.com",
"country":"SG",
"nationality":"Singaporean",
"address_line_1":"TAMBUN UTARA",
"address_line_2":"KABUPATEN BEKASI",
"postal_code":"510608",
"identity_no":"1212121200050006",
"bank_accounts":[
{
"id": 399,
"account_no": "9484853433",
"account_holder_name": "Bobby Keong",
"verification_status": "pending",
"bank_abbrev": "BCA",
"usage": "all"
}
],
"annual_income":"",
"id_front":"my_id_front.jpg",
"selfie_2id":"nricSelfiePlaceholder.png",
"account_locked":false,
"kyc_verified":true,
"meta_data":"",
"place_of_birth":"Malang",
"blood_type":"B",
"rt_rw":"011/017",
"administrative_village":"Penjaringan",
"district":"Pluit",
"religion":"Buddhism",
"marital_status":"Married",
"occupation":"007|Konsultan"
}
Callback Body:
{
"id": "user_gksj43jgzgqv",
"verification_status":false,
"reason":"The NRIC Photo is too blur"
}
This endpoint allows user to update their account information, this is especially important for account that would require KYC. Do note that some fields are not shown in the response even if you just updated them (like first_name) due to privacy concerns.
HTTPS Request
PUT https://sandbox.xfers.io/api/v3/user
URL Parameters
mother_maiden_name, id_front_url, selfie_2id_url is a required field in Indonesia
Name | Type | Required | Description | Value |
---|---|---|---|---|
first_name | string | optional | Account holder firstname | Doe |
last_name | string | optional | Account holder lastname | John |
string | optional | User email | example@example.com | |
date_of_birth | string | optional | Date of birth for account holder in yyyy-mm-dd | 1990-01-01 |
mother_maiden_name | string | ID: required, SG: optional | Name of Mother | John Doe |
gender | string | optional | Gender | male / female |
address_line_1 | string | optional | Address line 1 | Lorem Ipsum Road |
address_line_2 | string | optional | Address line 2 | #01-01 |
nationality | string | optional | Account holder nationality | Singaporean |
postal_code | string | optional | Address postal code | 123456 |
identity_no | string | optional | Account holder national identity number or, KTP number of Indonesian. | s12345678g |
country | string | optional | Account holder country of residence in abbreviation. | SG |
city | string | optional | Account holder city of residence | Singapore |
annual_income | integer | optional | Annual income of user in the local currency (SGD/IDR) | 60000 |
id_front_url | string | ID: required, SG: optional | URL storing the front image of user identity card | |
id_back_url | string | optional | URL storing the back image of user identity card | |
selfie_2id_url | string | ID: required, SG: optional | URL storing the selfie of user holding their id card or a second form of id like driving license or passport | |
proof_of_address_url | string | optional | URL storing the image/pdf of proof of address document of user like bank statement or telco bill. | |
support_document_1_url | string | optional | URL storing the image/pdf of support documents like proof of user income | |
support_document_2_url | string | optional | URL storing the image/pdf of support documents like proof of user income | |
support_document_3_url | string | optional | URL storing the image/pdf of support documents like proof of user income | |
support_document_4_url | string | optional | URL storing the image/pdf of support documents like proof of user income | |
support_document_5_url | string | optional | URL storing the image/pdf of support documents like proof of user income | |
meta_data | string | optional | Additional data like Jumio info dump. | |
place_of_birth | string | ID: optional, SG: ignore | Account holder’s birth place according to his/her KTP. | Jakarta |
blood_type | string | optional | Account holder’s blood type, without rhesus. | ‘A’, ‘B’, 'AB’, or 'O’ |
rt | string | ID: optional, SG: ignore | Account holder’s RT according to his/her KTP. Leading zero is optional. | 001 |
rw | string | ID: optional, SG: ignore | Account holder’s RW according to his/her KTP. Leading zero is optional. | 005 |
administrative_village | string | ID: optional, SG: ignore | Account holder’s administrative_village address. In KTP, it is called Kelurahan or Desa. | Meruya Utara |
state | string | optional | Account holder’s state of residence. In KTP, it is called Provinsi. | Jawa Barat |
district | string | optional | Account holder’s district address. In KTP, it is called Kecamatan. | Kembangan |
religion | string | ID: optional, SG: ignore | Account holder’s religion according to his/her KTP. | 'Islam’, 'Katholik’, 'Kristen Protestan’, 'Hindu’, 'Budha’, 'Kong Hu Cu’, or 'Aliran Kepercayaan’ |
marital_status | string | ID: optional, SG: ignore | Account holder’s marital status according to his/her KTP. | 'Belum Kawin’, 'Kawin’, 'Janda’, or 'Duda’ |
occupation | string | ID: optional, SG: ignore | Account holder’s occupation according to his/her KTP. | Pelajar/Mahasiswa |
callback_url | string | optional | URL to receive callback notifications on account verification changes. |
Verify User Account
This API forcefully verify the user with corresponding API KEY. This API can only be called from sandbox.
curl "https://sandbox.xfers.io/api/v3/user/verify" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
--request PATCH
Response:
{
"message": "success"
}
HTTPS Request
PATCH https://sandbox.xfers.io/api/v3/user/verify
Get Account Activities
The activities API supports querying of a user’s activity. If you are a merchant and querying a connected user’s account, only transactions with your merchant account will be shown. I.e. user’s transactions with other merchants will not be displayed.
curl -X GET \
'https://sandbox.xfers.io/api/v3/user/activities?limit=5&start_date=2018-07-04T11%3A49%3A58%2B08%3A00&offset=5' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
$resp = \Xfers\User::activities();
print_r($resp);
import xfers
from xfers import xfuser
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Getting activities...'
activities = xfuser.activities()
for activity in activities:
print activity
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Getting activities...'
activities = Xfers::User.activities
activities.each { |activity|
puts activity
}
rescue Xfers::XfersError => e
puts e.to_s
end
Response:
{
"activities": [
{
"id": "252933",
"amount": 10,
"fee": 0,
"created_at": "2018-07-22T16:28:46+08:00",
"status": "completed",
"type": "Deposit",
"metadata": {
"description": "Xfers - United Overseas Bank"
},
"wallet_name": "General Wallet"
},
{
"id": "63785",
"amount": -10,
"fee": 0,
"created_at": "2018-07-21T16:28:46+08:00",
"status": "paid",
"type": "Withdrawal",
"metadata": {
"description": "Development Bank of Singapore 029290083"
},
"wallet_name": "General Wallet"
},
{
"id": "0a114b08c9244a0xo28ec63b0a905265",
"amount": -66.08,
"fee": 0,
"created_at": "2018-07-20T16:28:46+08:00",
"status": "completed",
"type": "Charge",
"metadata": {
"origin_name": "Chris Tan",
"destination_name": "ABC Airlines",
"description": "Booking ABC Airlines Code XXYYZZ"
},
"wallet_name": "General Wallet"
},
{
"id": "2a718acab6454cdcaf362d51739b9271",
"amount": -30,
"fee": 0,
"created_at": "2018-07-18T10:11:40+08:00",
"status": "completed",
"type": "Payout",
"metadata": {
"origin_name": "Chris Tan",
"destination_name": "JanetIsMe",
"description": "XFERS.COM"
},
"wallet_name": "General Wallet"
},
{
"id": "56949bb8c9f84b60a31afe8fa6e13939",
"amount": 12.91,
"fee": 0,
"created_at": "2018-07-17T16:28:46+08:00",
"status": "credit_completed",
"type": "Credit Card",
"metadata": {
"origin_name": "sidhbansal",
"destination_name": "Chris Tan",
"description": "Keep Calm and Pay"
},
"wallet_name": "General Wallet"
}
],
"activities_returned": 5,
"limit": 5,
"offset": 5,
"start_date": "2018-07-04T11:49:58+08:00",
"end_date": "2018-08-15T23:59:59+08:00"
}
This endpoint returns information related to your account activites such as the types and statuses of transactions that the user has.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/user/activities
Query Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
limit | integer | optional | Max number of results to return per page | 50 (default) |
start_date | DateTime, iso8601 format.URL encode this. | optional | Earliest date to query | 2018-07-04T11%3A49%3A58%2B08%3A00 (Defaults to 1 month ago) |
end_date | DateTime, iso8601 format. URL encode this. | optional | Latest date to query | 2018-07-04T11%3A49%3A58%2B08%3A00 (Defaults to today) |
offset | integer | optional | Offset results for pagination purposes. | 0 (default) |
types | String | optional | Only show transactions of that type. Only “Credit Card”, “Charge”, “Payout”, “Deposit”, “Withdrawal” allowed. You can add additional types by separating with a comma. | Payout,Deposit (If this param is left blank, it will show all transaction types) |
status | String | optional | Only show transactions of that status. Only “completed”, “refunded”, “expired”, “cancelled”, “pending”, “accepted”, “on_hold” allowed. You can add additional types by separating with a comma. Note that putting “completed” will also return transactions with “paid” - you can take them to be the same. | completed,expired (If this param is left blank, it will show all transaction statuses) |
To do pagination:
- Decide on number of entries per page (e.g. 100 for this example). Set the limit as this
- First page: Offset 0. The latest 100 entries, 1-100, will be returned.
- Second page: Offset 100. The next 100 entries, 101-200, will be returned.
- Third page: Offset 200. The next 100 entries, 201-300, will be returned.
Hence your offset should always be a multiple of limit.
Response
Attribute | Description |
---|---|
id | ID of the Charge/Payout/Withdrawal/Payout. You can use this ID to query Charges and Payouts. |
type | 5 types: Credit Card, Charge, Payout, Withdrawal, Deposit |
amount | If money going out of account, negative. If coming in, positive. Note that only a completed Charge will actually deduct money. For example, if a Charge is expired/accepted/pending/unclaimed, no money will actually flow in/out of the wallet, even though there is a amount displayed. |
fee | Fee charged by Xfers for the transaction, if any. Will be 0 if no fees |
metadata | Shows additional information about a transaction |
activities_returned | Number of activities returned. If activities returned is less than the limit, this is the final page. |
Metadata for Deposits:
Xfers - Xfers Bank name you topped up to
"description": "Xfers - United Overseas Bank"
Metadata for Withdrawals:
Your Bank name Your account number
"description": "Development Bank of Singapore 029290083"
Metadata for Payouts/Charges/Credit Card:
"origin_name": <name of merchant or customer>
,
"destination_name": <name of merchant or customer>
,
"description": "Booking ABC Airlines Code XXYYZZ"
Get Transfer Info
curl "https://sandbox.xfers.io/api/v3/user/transfer_info" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
$resp = \Xfers\User::transferInfo();
print_r($resp);
import xfers
from xfers import xfuser
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Getting transfer info...'
resp = xfuser.transfer_info()
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Getting transfer info...'
resp = Xfers::User.transfer_info
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Retrieving current user transfer info");
TransferInfo transferInfo = User.transferInfo(apiKey);
System.out.println(transferInfo.getBankNameFull());
System.out.println(transferInfo.getBankNameAbbreviation());
System.out.println(transferInfo.getBankAccountNo());
System.out.println(transferInfo.getBankCode());
System.out.println(transferInfo.getBranchCode());
System.out.println(transferInfo.getBranchArea());
System.out.println(transferInfo.getUniqueId());
System.out.println(transferInfo.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"bank_name_full" : "Malaysia Banking BHD",
"bank_abbrev" : "MBB",
"bank_account_no" : "04111066899",
"bank_code" : "7302",
"branch_code" : "001",
"branch_area" : "Maybank Tower",
"unique_id" : "XXXXXXXX"
}
All Banks Response:
[
{
"bank_name_full": "Bank Mandiri",
"bank_abbrev": "MANDIRI",
"bank_account_no": "8855845678901242",
"bank_code": "",
"branch_code": "",
"branch_area": "",
"unique_id": "81128125",
"img_src": "https://www.xfers.io/images/bankLogos/bank-logo-mandiri.png",
"transfer_info_array": [
{
"bank_name_full": "Bank Central Asia",
"bank_abbrev": "BCA",
"bank_account_no": "06420856789021",
"bank_code": "",
"branch_code": "",
"branch_area": "",
"unique_id": "81128125",
"img_src": "https://www.xfers.io/images/bankLogos/bank-logo-bca.png"
},
{
"bank_name_full": "Bank Mandiri",
"bank_abbrev": "MANDIRI",
"bank_account_no": "8855845678901242",
"bank_code": "",
"branch_code": "",
"branch_area": "",
"unique_id": "81128125",
"img_src": "https://www.xfers.io/images/bankLogos/bank-logo-mandiri.png"
}
]
}
]
This will return transfer in info specific to the user. This information is used for topping up the user’s Xfers account.
On your User Interface, instruct the user to make a bank transfer to the bank name and bank account number specified. For our non-VA account, the user must also include his mobile phone number in the “Initials” and “Comments for Recipient” field when doing a bank transfer so Xfers can identify which user this bank transfer belongs to.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/user/transfer_info
Register Updates Callback
curl "https://sandbox.xfers.io/api/v3/user/balance_callback" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{"callback_url": "www.example.com/update", "name": "hello-world", "events":"[\"deposit\"]"}'
Response:
{
"callback_id":"1",
"callback_url":"www.example.com/update",
"name":"hello-world",
"events":["deposit"],
"created_at":"2017-07-12T03:36:28Z"
}
This will allow you to register for a callback which will be triggered whenever the event you registered for occurs.
There can only be one registration at any point. Any existing ones will be overwritten.
HTTPS Request
POST https://sandbox.xfers.io/api/v3/user/balance_callback
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
callback_url | string | required | URL to receive callback notifications on account changes | https://www.example.com/updates |
events | array | required | Array of events to subscribe to. This should be a valid JSON array. Refer to the section below on the types of events available | [“deposit”] |
name | string | optional | A name that you can attach to this request. It can be useful for storing additional information. You will be provided with this field in your callback notification | xyz-123 |
Types of Events
Name | Description |
---|---|
deposit | Triggered when a user makes a deposit to his Xfers Account via a bank transfer. |
Callback Notification Format
This is a server to server HTTPS/HTTP POST and you will need to acknowledge the callback by responding with a HTTP 200 status.
If your callback_url given is https://www.example.com/updates
, Xfers will send:
POST https://www.example.com/updates
The following parameters will be part of the HTTPS/HTTP POST:
Callback Format:
{
"notification_id": "5",
"callback_id":"1",
"name":"hello-world",
"event_type":"deposit",
"created_at":"2017-08-08T03:36:28Z",
"user_contact":"83994956",
"data": {
"ledger_balance": 436750.00,
"available_balance": 336750.00,
"credit": 335000.00,
"debit": 0.00,
"details": "BCA Transfer"
}
}
Name | Type | Description | Value |
---|---|---|---|
notification_id | string | A unique ID for this particular event | 5 |
callback_id | string | The ID of your callback registration | 1 |
name | string | The string you previously provided in the register request | hello-world |
event_type | string | The type of event | deposit |
created_at | string | When this event was triggered. In ISO8601 datetime format | 2017-08-08T03:36:28Z |
user_contact | string | Contact number of the user | 83994956 |
data | dictionary | Additional information about the event | Look at the below table |
Additional information about the event
Key | Description | Value Type | Value |
---|---|---|---|
ledger_balance | Ledger balance of the user at this point in time | float | 436750.00 |
available_balance | Available balance of the user at this point in time | float | 336750.00 |
credit | How much was credited in this event | float | 335000.00 |
debit | How much was debited in this event | float | 0.00 |
details | Additional details. For deposit, it would be the bank the user did a transfer from | String | BCA Transfer |
Cancel Updates Callback
curl -X DELETE "https://sandbox.xfers.io/api/v3/user/balance_callback" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
Response:
{
"callback_id":"1",
"callback_url":"www.example.com/update",
"name":"hello-world",
"events":["deposit"],
"created_at":"2017-07-12T03:36:28Z",
"deleted": true
}
Deletes the existing callback subscription
HTTPS Request
DELETE https://sandbox.xfers.io/api/v3/user/balance_callback
Merchant
The merchant API supports querying and making changes to a user’s business details for compliance purposes.
Get Merchant Info
curl "https://sandbox.xfers.io/api/v3/merchant" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
Response:
{
"business_id": "53348831Z",
"business_name" : "Alpha Events",
"business_type" : "Private Company",
"business_position" : "Director",
"business_address_line_1" : "78 Lucky Plaza",
"business_address_line_2" : "#14-39",
"business_postal_code" : "938884",
"business_telephone" : "+6583994012",
"bizfile_document" : "BIZFILE.pdf",
"business_verified" : false,
"shareholders": [
{
"firstName":"Samson",
"lastName":"Leo",
"nricNumber":"S8781203Q",
"dateOfBirth":"19/02/1987",
"nationality":"Singaporean",
"address1":"Blk 600 Elias Road",
"address2":"#09-123",
"postalCode":"510600",
"phoneNumber":"+6583004848",
"businessType":"Private Company",
"businessPosition":"Director"
}
]
}
This endpoint returns merchant information related to your account.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/merchant
Update Merchant Info
curl "https://sandbox.xfers.io/api/v3/merchant" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-X PUT \
-d '{"business_id": "53348831Z", "business_name": "Alpha Events", "business_type": "Private Company"}'
Response:
{
"business_id": "53348831Z",
"business_name" : "Alpha Events",
"business_type" : "Private Company",
"business_position" : "Director",
"business_address_line_1" : "78 Lucky Plaza",
"business_address_line_2" : "#14-39",
"business_postal_code" : "938884",
"business_telephone" : "+6583994012",
"bizfile_document" : "BIZFILE.pdf",
"business_verified" : false,
"shareholders": [
{
"firstName":"Samson",
"lastName":"Leo",
"nricNumber":"S8781203Q",
"dateOfBirth":"19/02/1987",
"nationality":"Singaporean",
"address1":"Blk 600 Elias Road",
"address2":"#09-123",
"postalCode":"510600",
"phoneNumber":"+6583004848",
"businessType":"Private Company",
"businessPosition":"Director"
}
]
}
This endpoint allows user to update their merchant information. If the user is not yet a merchant, this process converts them to a merchant.
HTTPS Request
PUT https://sandbox.xfers.io/api/v3/merchant
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
business_id | string | optional | Enter your singapore recognized bizfile ID. (eg: UEN, incorporation number, business registration number). | |
business_position | string | optional | Position in the business. | “Owner”, “Partner”, “Director”, “Shareholder”, “Director & Shareholder”, “Chairperson”, “Treasurer”, “Civil Servant” |
business_name | string | optional | Enter in the name of your business. | |
business_type | string | optional | Type of your business | “Individual”, “Sole Proprietorship”, “Partnership”, “Private Company”, “Public Company”, “Societies / Nonprofit organisations”, “Government Entity” |
business_address_line_1 | string | optional | Enter in the first line of your business’ address. | 123 Xfers Road |
business_address_line_2 | string | optional | Enter in the last line of your business’ address. | Block 10 #17A |
business_postal_code | string | optional | Enter in your business’ postal code. | S323233 |
business_telephone | string | optional | Enter your business’ phone number along with the country code. | +6591234567 |
bizfile_document | string | optional | URL storing the ACRA Bizfile document as proof of your business details |
Add Shareholder
curl "https://sandbox.xfers.io/api/v3/merchant/shareholder" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{"firstName": "wenbin", "lastName": "tay", "nricNumber": "Blk 712 loyang Avenue 5", "dateOfBirth": "#01-41", "nationality": "Singaporean", "postalCode": "340712", "nricNumber": "s86917127G", "businessType": "Private Company", "businessPosition": "Director", "phoneNumber":"+6583004848"}'
Response:
{
"business_id": "53348831Z",
"business_name" : "Alpha Events",
"business_type" : "Private Company",
"business_position" : "Director",
"business_address_line_1" : "78 Lucky Plaza",
"business_address_line_2" : "#14-39",
"business_postal_code" : "938884",
"business_telephone" : "+6583994012",
"bizfile_document" : "BIZFILE.pdf",
"business_verified" : false,
"shareholders": [
{
"firstName":"Samson",
"lastName":"Leo",
"nricNumber":"S8781203Q",
"dateOfBirth":"19/02/1987",
"nationality":"Singaporean",
"address1":"Blk 600 Elias Road",
"address2":"#09-123",
"postalCode":"510600",
"phoneNumber":"+6583004848",
"businessType":"Private Company",
"businessPosition":"Director"
}
]
}
This endpoint allows businesses to add a shareholder.
HTTPS Request
POST https://sandbox.xfers.io/api/v3/merchant/shareholder
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
firstName | string | required | First name | Samson |
lastName | string | required | Last name | Leo |
nricNumber | string | required | National identity number | S8781203Q |
dateOfBirth | string | required | Date of birth | 19/02/1987 |
nationality | string | required | Nationality | Singaporean |
address1 | string | required | First line of address | Blk 600 Elias Road |
address2 | string | required | Last line of address | #09-123 |
postalCode | string | required | Postal code | 510600 |
phoneNumber | string | required | Phone number with country code | +6583004848 |
businessType | string | required | Business type | “Individual”, “Sole Proprietorship”, “Partnership”, “Private Company”, “Public Company”, “Societies / Nonprofit organisations”, “Government Entity” |
businessPosition | string | required | Business position | “Owner”, “Partner”, “Director”, “Shareholder”, “Director & Shareholder”, “Chairperson”, “Treasurer”, “Civil Servant” |
Delete Shareholder
curl -X DELETE "https://sandbox.xfers.io/api/v3/merchant/shareholder/<shareholder_nric_number>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
Response:
{
"business_id": "53348831Z",
"business_name" : "Alpha Events",
"business_type" : "Private Company",
"business_position" : "Director",
"business_address_line_1" : "78 Lucky Plaza",
"business_address_line_2" : "#14-39",
"business_postal_code" : "938884",
"business_telephone" : "+6583994012",
"bizfile_document" : "BIZFILE.pdf",
"business_verified" : false,
"shareholders": [
]
}
This request allow you to delete an existing shareholder.
HTTPS Request
DELETE https://sandbox.xfers.io/api/v3/merchant/shareholder/<shareholder_nric_number>
Response
The latest business details.
Bank Account
The follow APIs allow you to add or update your bank account info and fetch a list of available banks.
Available Banks
curl "https://sandbox.xfers.io/api/v3/banks" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
System.out.println("Listing all available xfers Banks");
List<BankAccount> bankAccounts = BankAccount.availableBanks(apiKey);
for (BankAccount bankAccount : bankAccounts) {
System.out.println(bankAccount.toString());
}
Response:
[
{
"name": "Development Bank of Singapore",
"abbreviation": "DBS",
"img_src": "https://xfers.com/bank-logo-dbs.png"
},
{
"name": "United Oversea Bank",
"abbreviation": "UOB",
"img_src": "https://xfers.com/bank-logo-uob.png"
},
{
"name": "Malaysia Banking BHD",
"abbreviation": "MBB",
"img_src": "https://xfers.com/bank-logo-mbb.png"
},
{
"name": "Oversea-Chinese Banking Corporation Limited",
"abbreviation": "OCBC",
"img_src": "https://xfers.com/bank-logo-ocbc.png"
},
{
"name": "Citibank Singapore",
"abbreviation": "CITI",
"img_src": "https://xfers.com/bank-logo-citi.png"
},
{
"name": "Standard Chartered Bank",
"abbreviation": "SCB",
"img_src": "https://xfers.com/bank-logo-scb.png"
},
{
"name": "Australia and New Zealand Bank Group",
"abbreviation": "ANZ",
"img_src": "https://xfers.com/bank-logo-anz.png"
},
{
"name": "CIMB Bank Berhad",
"abbreviation": "CIMB",
"img_src": "https://xfers.com/bank-logo-cimb.png"
},
{
"name": "Deutsche bank AG",
"abbreviation": "DBAG",
"img_src": "https://xfers.com/bank-logo-dbag.png"
},
{
"name": "Far Eastern Bank Ltd",
"abbreviation": "FEB",
"img_src": "https://xfers.com/bank-logo-feb.png"
},
{
"name": "Hong Kong and Shanghai Banking Corporation",
"abbreviation": "HSBC",
"img_src": "https://xfers.com/bank-logo-hsbc.png"
},
{
"name": "RHB Bank Berhad",
"abbreviation": "RHB",
"img_src": "https://xfers.com/bank-logo-rhb.png"
},
{
"name": "Sumitomo Mitsui Banking Corporation",
"abbreviation": "SMFG",
"img_src": "https://xfers.com/bank-logo-smfg.png"
},
{
"name": "Bank of China",
"abbreviation": "BOC",
"img_src": "https://xfers.com/bank-logo-boc.png"
},
{
"name": "Bank of Tokyo-Mitsubshi UFJ",
"abbreviation": "MUFG",
"img_src": "https://xfers.com/bank-logo-mufg.png"
},
{
"name": "BNP PARIBAS",
"abbreviation": "BNP",
"img_src": "https://xfers.com/bank-logo-bnp.png"
},
{
"name": "HL BANK",
"abbreviation": "HLB",
"img_src": "https://xfers.com/bank-logo-hlb.png"
},
{
"name": "Mizuho Bank",
"abbreviation": "MIZ",
"img_src": "https://xfers.com/bank-logo-miz.png"
}
]
This will provide you with a list of banks we support.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/banks
Add a Bank Account
curl "https://sandbox.xfers.io/api/v3/user/bank_account" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{"account_no": "0393123432", "bank":"DBS", "account_holder_name": "Tian Wei"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\BankAccount::add(array(
'account_no' => '0393123432',
'bank' => 'DBS'
));
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught invalid request exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfbankaccount
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Adding bank account...'
params = {
'account_no': '0393123432',
'bank': 'DBS'
}
bank_accounts = xfbankaccount.add(params)
for bank_account in bank_accounts:
print 'Bank account: {}'.format(bank_account)
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Adding bank account...'
params = {
'account_no'=> '0393123432',
'bank'=> 'DBS'
}
bank_accounts = Xfers::BankAccount.add params
puts "number of bank accounts=> #{bank_accounts.length}"
bank_accounts.each { |account| puts "Bank Account=> #{account}" }
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
Map<String, Object> params = new HashMap<String, Object>();
System.out.println("Adding Bank Account");
params.put("account_no", "0393123432");
params.put("bank", "DBS");
List<BankAccount> bankAccounts = BankAccount.add(params,apiKey);
for (BankAccount bankAccount : bankAccounts) {
System.out.println(bankAccount.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Response:
[
{
"id": 400,
"account_no": "0393123432",
"account_holder_name": "Tian Wei",
"verification_status": "verified",
"bank_abbrev": "DBS",
"usage": "all"
}
]
This request will add a new bank account to this Xfers account. You will be able to withdraw your Xfers available balances to these account(s).
HTTPS Request
POST https://sandbox.xfers.io/api/v3/user/bank_account
Response
List of all bank accounts belonging to user.
For Xfers Indonesia API, an additional attribute detected_name
will be returned. This is the actual name of the bank account holder gotten directly from the bank.
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
account_no | string | required | bank account no | 0393123432 |
bank | string | required | bank abbreviation (Refer to available banks | DBS |
usage | string | optional | Is this bank account to be used as a funding source or for withdrawals? | Either “funding_source” or “withdrawal” or “all”. Defaults to “all” |
account_holder_name | string | optional | Name of bank account holder | Tian Wei |
List Bank Accounts
curl "https://sandbox.xfers.io/api/v3/user/bank_account" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\BankAccount::retrieve();
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught invalid request exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfbankaccount
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Listing all bank_accounts...'
bank_accounts = xfbankaccount.list_all()
for bank_account in bank_accounts:
print 'Bank account: {}'.format(bank_account)
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Listing all bank accounts...'
bank_accounts = Xfers::BankAccount.list_all
puts "number of bank accounts => #{bank_accounts.length}"
bank_accounts.each { |account| puts "Bank Account=> #{account}" }
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Retrieving Bank Account");
List<BankAccount> bankAccounts = BankAccount.retrieve(apiKey);
for (BankAccount bankAccount : bankAccounts) {
System.out.println(bankAccount.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Response:
[
{
"id": 399,
"account_no": "0393123432",
"account_holder_name": null,
"verification_status": "pending",
"bank_abbrev": "DBS",
"usage": "all"
},
{
"id": 400,
"account_no": "888123432",
"account_holder_name": "Tian Wei",
"verification_status": "verified",
"bank_abbrev": "DBS",
"usage": "all"
}
]
This will list all bank accounts belonging to the user.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/user/bank_account
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
usage | string | optional | type of bank account | Either “funding_source” or “withdrawal” or “all”. Defaults to “all” |
Update a Bank Account
curl "https://sandbox.xfers.io/api/v3/user/bank_account/<bank_account_id>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-X PUT \
-d '{"account_no": "0393123432", "bank":"DBS"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\BankAccount::update('<bank_account_id>', array(
'account_no' => '0393123432',
'bank' => 'DBS'
));
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught invalid request exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfbankaccount
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Updating bank account {}...'.format('<bank_account_id>')
params = {
'account_no': '0393123432',
'bank': 'DBS'
}
resp = xfbankaccount.update('<bank_account_id>', params)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
params = {
'account_no'=> '0393123432',
'bank'=> 'DBS'
}
puts 'Updating bank account...'
resp = Xfers::BankAccount.update '<bank_account_id>', params
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
Map<String, Object> params = new HashMap<String, Object>();
System.out.println("Updating Bank Account");
params.put("account_no", "0393123432");
params.put("bank", "DBS");
List<BankAccount> bankAccounts = BankAccount.update("<bank_account_id>", params, apiKey);
for (BankAccount bankAccount : bankAccounts) {
System.out.println(bankAccount.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Response:
[
{
"id": 400,
"account_no": "0393123432",
"account_holder_name": "Tian Wei",
"verification_status": "verified",
"bank_abbrev": "DBS",
"usage": "all"
}
]
This request allows you to update an existing bank account record.
HTTPS Request
PUT https://sandbox.xfers.io/api/v3/user/bank_account/<bank_account_id>
Response
List of all bank accounts belonging to user.
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
account_no | string | optional | bank account no | 0393123432 |
bank | string | optional | bank abbreviation (Refer to available banks) | DBS |
usage | string | optional | Is this bank account to be used as a funding source or for withdrawals? | Either “funding_source” or “withdrawal” or “all”. |
account_holder_name | string | optional | Name of bank account holder | Tian Wei |
Delete Bank Account
curl -X DELETE "https://sandbox.xfers.io/api/v3/user/bank_account/<bank_account_id>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\BankAccount::delete('<bank_account_id>');
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught invalid request exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfbankaccount
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Deleting bank account {}...'.format('<bank_account_id>')
resp = xfbankaccount.delete('<bank_account_id>')
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Deleting bank account...'
resp = Xfers::BankAccount.delete '<bank_account_id>'
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Deleting Bank Account");
List<BankAccount> bankAccounts = BankAccount.delete("<bank_account_id>",apiKey);
for (BankAccount bankAccount : bankAccounts) {
System.out.println(bankAccount.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Response:
[
{
"id": 399,
"account_no": "0393123432",
"account_holder_name": null,
"verification_status": "pending",
"bank_abbrev": "DBS",
"usage": "all"
}
]
This request allow you to delete an existing bank account record.
HTTPS Request
DELETE https://sandbox.xfers.io/api/v3/user/bank_account/<bank_account_id>
Response
List of all bank accounts belonging to user.
Submit Withdrawal Request
curl "https://sandbox.xfers.io/api/v3/user/bank_account/<bank_account_id>/withdraw" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{"amount": "50.0"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\BankAccount::withdraw('<bank_account_id>', array(
'amount' => '50.0'
));
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught invalid request exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfbankaccount
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Withdrawing from bank account {}...'.format('<bank_account_id>')
params = {
'amount': '50.0'
}
resp = xfbankaccount.withdraw('<bank_account_id>', params)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Withdrawing from bank account...'
params = {
'amount'=> '50.0'
}
resp = Xfers::BankAccount.withdraw '<bank_account_id>', params
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
Map<String, Object> params = new HashMap<String, Object>();
System.out.println("Making a withdrawal request");
params.put("amount", "50.0");
params.put("express", false);
Withdrawal withdrawal = BankAccount.withdraw("<bank_account_id>", params, apiKey);
System.out.println(withdrawal.getId());
System.out.println(withdrawal.getAccountNo());
System.out.println(withdrawal.getBankAbbrev());
System.out.println(withdrawal.getAmount());
System.out.println(withdrawal.getFees());
System.out.println(withdrawal.getExpress());
System.out.println(withdrawal.getStatus());
System.out.println(withdrawal.getArrival());
System.out.println(withdrawal.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"available_balance": "0.00",
"ledger_balance" : "200.00",
"withdrawal_request" :
{
"id" : "59",
"account_no" : "0393123432",
"bank_abbrev" : "DBS",
"amount" : "50.0",
"fees" : "0.0",
"express" : "false",
"status" : "pending",
"arrival" : "31 March 2016"
}
}
This will make a withdrawal request to the bank account given, provided that your account has sufficient available balance.
For same day withdrawal(additional fees applies), set ‘express’ field to true. Funds will arrive at recipient bank within 24 hrs.
Standard withdrawal takes 2-3 business day to arrive at recipient bank.
HTTPS Request
POST https://sandbox.xfers.io/api/v3/user/bank_account/<bank_account_id>/withdraw
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
amount | string | required | Amount to withdraw | 50.0 |
idempotency_id | string | optional | Unique ref no provided by you to prevent double transaction, this cannot be repeated, Currently only activated for Indonesia | Order_123 |
express | boolean | optional | Default to 'false’ | true |
notify_url | string | optional | To receive HTTP POST callback notifications on withdrawal status changes | https://www.mysite.com/withdrawal |
Withdrawal notification
If you put a notify_url in your withdrawal, we will send you the callback with the following parameter when the withdrawal is “completed” or “failed”
Name | Type | Description | Value |
---|---|---|---|
account_no | string | bank account no of withdrawal | 0393123432 |
amount | string | withdrawal amount | 125000 |
bank_abbrev | string | bank abbreviation of withdrawal | DBS |
express | string | Express/normal withdrawal | true |
fees | string | Withdrawal Fee | 0 |
id | string | Xfers Generated Unique Key | contract_dd5a6b83 |
idempotency_id | string | The key you put in the withdrawal request | AZ0001 |
status | string | Status of transaction | “completed” or “failed” |
value_date | string | Date of withdrawal completed as provided by partner bank. will only available for “completed” status | 2018-09-12 |
Withdrawing on behalf
If you wish to withdraw to a bank account not belonging to you, add in two additional params.
(1) The user’s user_api_token
(2) A unique payout_invoice_id
in the params.
Behind the scenes, Xfers does a payout of funds from your Xfers account to that user’s Xfers account, followed by a withdrawal. This is required for compliance purposes as we cannot directly withdraw funds to a bank account not belonging to you.
Name | Type | Required | Description | Value |
---|---|---|---|---|
user_api_token | string | required | Use this param if you want to withdraw to another user’s bank account instead of your own. | efgowZwKoMoPL_dxV7zpuoakM7STLb14uQrtX4J2F4o |
payout_invoice_id | string | required | Unique ref no provided by merchant. This will need to be unique. | AZ0001 |
Mock Sandbox Withdrawal
curl "https://sandbox.xfers.io/api/v3/user/bank_account/withdrawal_requests/mock_result" \
-H "Content-Type: application/json" \
-H "X-XFERS-USER-API-KEY:2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"\
-X PUT \
-d '{"idempotency_id":"AZ0001","status":"completed"}'
HTTPS Request
PUT https://sandbox.xfers.io/api/v3/user/bank_account/withdrawal_requests/mock_result
(Currently only available for Indonesia sandbox)
In Sandbox, you can mock the status of a withdrawal so that it will trigger the corresponding callback to your server. Currently the available statuses are “failed” and “completed”
Name | Type | Required | Description | Value |
---|---|---|---|---|
idempotency_id | string | required | This is the idempotency_id you put in your withdrawal. | AZ0001 |
status | string | required | Withdrawal response you want to mock | “completed” or “failed” |
Get Withdrawal Request
curl "https://sandbox.xfers.io/api/v3/user/bank_account/withdrawal_requests/<withdrawal_request_id>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Getting a withdrawal request");
Withdrawal withdrawalRequest = BankAccount.retrieveWithdrawalRequest("23771");
System.out.println(withdrawalRequest.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id" : "59",
"account_no" : "0393123432",
"bank_abbrev" : "DBS",
"amount" : "50.0",
"fees" : "0.0",
"express" : "false",
"status" : "pending",
"arrival" : "31 March 2016"
}
This will retrieve one withdrawal request made previously.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/user/bank_account/withdrawal_requests/<withdrawal_request_id>
List Withdrawal Request
curl "https://sandbox.xfers.io/api/v3/user/bank_account/withdrawal_requests" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\BankAccount::withdrawalRequests(array(
'filter' => 'pending'
));
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught invalid request exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfbankaccount
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Listing withdrawal requests...'
params = {
'filter': 'pending'
}
withdrawal_requests = xfbankaccount.withdrawal_requests(params)
for request in withdrawal_requests:
print 'Withdrawal request: {}'.format(request)
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Listing withdrawal requests...'
params = {
'filter'=> 'pending'
}
withdrawal_requests = Xfers::BankAccount.withdrawal_requests params
withdrawal_requests.each { |req| puts "Withdrawal request=> #{req}" }
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Listing all withdrawal request");
List<Withdrawal> withdrawalRequests = BankAccount.withdrawalRequests("pending", apiKey);
for (Withdrawal withdrawal : withdrawalRequests) {
System.out.println(withdrawal.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"withdrawal_requests" : [
{
"id" : "59",
"account_no" : "209884413",
"bank_abbrev" : "DBS",
"amount" : "50.0",
"fees" : "0.0",
"express" : "false",
"status" : "pending",
"arrival" : "31 March 2016"
},
{
"id" : "99",
"account_no" : "0393123432",
"bank_abbrev" : "OCBC",
"amount" : "250.0",
"fees" : "2.99",
"express" : "true",
"status" : "pending",
"arrival" : "28 March 2016"
}
]
}
This will list all withdrawal requests made previously.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/user/bank_account/withdrawal_requests
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
filter | string | optional | filter by withdrawal status | Default to no filter |
Withdrawal Status
Name | Description |
---|---|
unverified | Withdrawal request is awaiting confirmations |
pending | Withdrawal request is being process now. |
paid | Withdrawal request has been processed and completed. |
cancelled | Withdrawal request has been cancelled. |
Prepaid Cards
The follow APIs allow you to withdraw money into a prepaid card.
Providers
wirecard_test_2
Add a Prepaid Card
curl "https://sandbox.xfers.io/api/v3/prepaid" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{"proxy_number": "21794", "description":"John card", "provider": "wirecard_test_2"}'
COMING SOON
COMING SOON
COMING SOON
COMING SOON
Response:
{
"id" : "12315",
"proxy_number" : "21794",
"description" : "John card",
"provider": "wirecard_test_2"
}
HTTPS Request
POST https://sandbox.xfers.io/api/v3/prepaid
Response
The prepaid card object.
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
proxy_number | string | required | The prepaid card’s proxy number | 21794 |
provider | string | required | Prepaid card provider type | wirecard_test_2 |
description | string | optional | Description about this prepaid card | Sam’s card |
Topup a Prepaid Card
curl "https://sandbox.xfers.io/api/v3/prepaid/CARD-ID/topup" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{"amount": 10.59}'
COMING SOON
COMING SOON
COMING SOON
COMING SOON
Response:
{
"id":"319095ff12474a50ada1f2874fd1d3b2",
"object":"charge",
"amount":"84.52",
"total_amount":"84.52",
"currency":"sgd",
"customer":"+65XXXXXXXX",
"order_id":"XFER170113160234758",
"description":"Load card 21794",
"statement_descriptor":null,
"status":"completed",
"currency_symbol":"$",
"currency_precision":2
}
HTTPS Request
POST https://sandbox.xfers.io/api/v3/prepaid/CARD-ID/topup
Response
The completed charge object.
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
amount | float | required | How much to topup | 9.85 |
List all Prepaid Card
curl "https://sandbox.xfers.io/api/v3/prepaid" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
COMING SOON
COMING SOON
COMING SOON
COMING SOON
Response:
[
{
"id": "554",
"proxy_number": "444",
"description": "helloworld",
"provider": "wirecard_test_0"
},
{
"id": "556",
"proxy_number": "454",
"description": "meng",
"provider": "wirecard_test_2"
}
]
HTTPS Request
GET https://sandbox.xfers.io/api/v3/prepaid
Response
List of prepaid cards added.
Delete Prepaid Card
curl -X DELETE "https://sandbox.xfers.io/api/v3/prepaid/<card_id>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
COMING SOON
COMING SOON
COMING SOON
COMING SOON
Response:
[
{
"id": "556",
"proxy_number": "454",
"description": "meng",
"provider": "wirecard_test_2"
}
]
This request allow you to delete an existing prepaid card. Note that this only deletes the prepaid card stored on Xfers; the card will still work and you can add back the card anytime.
HTTPS Request
DELETE https://sandbox.xfers.io/api/v3/prepaid/<card_id>
Response
List of all prepaid cards belonging to user.
Charges
The following APIs allow anyone to pay you via an internet banking transfer or credit card.
The user pays by going to the checkout_url
returned (assuming redirect
is set to false
). When redirect
is true, instead of the JSON response, Xfers will automatically redirect the request to our checkout page.
Our checkout page contains the relevant instructions for the user to login/signup and guides them to make payment. If the user already has an Xfers account with enough balance, we deduct directly from that account.
Creating a Charge
curl "https://sandbox.xfers.io/api/v3/charges" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{ "amount": "9.99", "currency": "SGD", "redirect": "false", "notify_url": "https://mysite.com/payment_notification", "return_url": "https://mysite.com/return", "cancel_url": "https://mysite.com/cancel", "order_id": "AZ9912", "description":"unused red dress", "metadata": {"firstname":"Tianwei", "lastname":"Liu"}}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('Vsya_qc5KjiUGK3xyKRgmhb2Atir2wAyizqssRuYJYw');
\Xfers\Xfers::setSGSandbox();
try {
$metadata = array(
'firstname' => 'Tianwei',
'lastname' => 'Liu'
);
$resp = \Xfers\Charge::create(array(
'amount' => '9.99',
'currency' => 'SGD',
'notify_url' => 'https://mysite.com/payment_notification',
'return_url' => 'https://mysite.com/return',
'cancel_url' => 'https://mysite.com/cancel',
'order_id' => 'AZ9912',
'description' => 'unused red dress',
'redirect' => 'false',
'metadata' => $metadata
));
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import json
import xfers
from xfers import xfcharge
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Creating charge...'
metadata = {'firstname': 'Tianwei', 'lastname': 'Liu'}
params = {
'amount' : '9.99',
'currency' : 'SGD',
'notify_url' : 'https://mysite.com/payment_notification',
'return_url' : 'https://mysite.com/return',
'cancel_url' : 'https://mysite.com/cancel',
'order_id' : 'AZ9912',
'description' : 'unused red dress',
'redirect': False,
'metadata' : json.dumps(metadata)
}
resp = xfcharge.create(params)
charge_id = resp['id']
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Creating charge...'
params = {
'amount' => '9.99',
'currency' => 'SGD',
'notify_url' => 'https://mysite.com/payment_notification',
'return_url' => 'https://mysite.com/return',
'cancel_url' => 'https://mysite.com/cancel',
'order_id' => 'AZ9912',
'description' => 'unused red dress',
'redirect' => false,
'metadata' => {'firstname'=> 'Tianwei', 'lastname'=> 'Liu'}
}
resp = Xfers::Charge.create params
charge_id = resp[:id]
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
try {
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
System.out.println("Creating a charge");
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("firstname", "Tianwei");
metadata.put("lastname", "Liu");
Map<String, Object> params = new HashMap<String, Object>();
Gson gson = new Gson();
params.put("amount", "9.99");
params.put("currency", "SGD");
params.put("notify_url", "https://mysite.com/payment_notification");
params.put("return_url", "https://mysite.com/return");
params.put("cancel_url", "https://mysite.com/cancel");
params.put("order_id", "AZ9912");
params.put("description", "unused red dress");
params.put("redirect", false);
params.put("metadata", gson.toJson(metadata));
Charge charge = Charge.create(params, apiKey);
System.out.println(charge.getId());
System.out.println(charge.getAmount());
System.out.println(charge.getCheckoutUrl());
System.out.println(charge.getOrderId());
System.out.println(charge.getStatus());
System.out.println(charge.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "contract_b840cc9fc5a359c22ed2ccef3427aacd",
"object": "TransferContract",
"checkout_url" : "https://sandbox.xfers.io/checkout_transaction/b840cc9fc5a359c22ed2ccef3427aacd",
"notify_url" : "https://mysite.com/payment_notification",
"return_url" : "https://mysite.com/return",
"cancel_url" : "https://mysite.com/cancel",
"amount" : "9.99",
"currency" : "SGD",
"order_id" : "A012312",
"description" : "Carousell user - Konsolidate",
"receipt_email" : "",
"total_amount" : "12.49",
"fee_amount" : "0.12",
"status" : "completed",
"metadata" : {
"firstname":"Tianwei",
"lastname": "Liu"
},
"transfer_info": {
"bank_name_full": "United Overseas Bank",
"bank_name_abbreviation": "UOB",
"bank_account_no": "123456789",
"bank_code": "7375",
"swift_code": "UOVBSGSGXXX",
"unique_id": "89898989",
"outstanding_amount": "0"
}
}
The following request will allow you to create a charge against a customer
POST https://sandbox.xfers.io/api/v3/charges
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
amount | float | required | How much you want to charge the customer | 9.99 |
currency | string | required | 3-letter ISO code for currency | SGD |
order_id | string | required | Unique ref no provided by you to prevent double charging, this cannot be repeated | A012312 |
description | string | optional | Description of transaction for display purposes | Carousell user - Konsolidate |
customer | string | optional | Customer email or phone number. If provided, only that user can use the checkout_url returned. If the customer does not exist, an account will be created for them using the email/phone number provided. An OTP will be sent to the email/phone for the user to log in | johnny@xfers.com or +65XXXXXXXX |
notify_url | string | optional | URL to receive callback notifications on charge success/failure/expiration | https://mysite.com/payment_notification |
return_url | string | optional | URL Xfers will redirect customer to on completion of Xfers checkout | https://mysite.com/return |
cancel_url | string | optional | URL Xfers will redirect customer to on cancellation of Xfers checkout | https://mysite.com/cancel |
user_api_token | string | optional | Buyer’s api token obtain via Connect’s get user token APIs. When this is provide, this charge will skip user auth. | NbKjcFV5XxGZ-Uf2XnxyshFcrGtoxmLms9YEgokzDRo |
user_phone_no | string | optional | When this is provided, buyer will receive an OTP(one time password) from Xfers which they can provide to merchant to skip user authentication. See Authorize a Charge. | 85228000 |
google_auth | boolean | optional | When this is true and user_phone_no is provided, instead of phone SMS OTP, user can use Google Authenticator to do OTP. See Authorize a Charge. | Default to false |
transactional_only | boolean | optional | Enables transactional charge when true. See more info. Only selected Xfers partners have this feature available. | Default to false |
debit_only | boolean | optional | When this is true, this charge will attempt to debit from users existing balance/card on file. Status returned will be “completed” on successful debit or “cancelled” when there insufficient funds / valid card on file in user wallet. | Default to false |
card_only | boolean | optional | When this is true, this charge will will attempt to take payments via credit/debit card. | Default to false |
redirect | boolean | optional | When this is true, instead of the JSON response, Xfers will automatically redirect the request to our checkout page | Default to true. |
hrs_to_expirations | float | optional | No of hours before this transactons will expire | Default to 48.0 hours from now. |
meta_data | string | optional | A set of key/value pairs that you can attach to a charge. It can be useful for storing additional information about the customer in a structured format. You will be provided with these metadata in your callback notification | {“firstname”:“tianwei”, “lastname”:“liu”} |
receipt_email | string | optional | The email address to send this charge’s receipt. | tianwei@xfers.io |
skip_notifications | boolean | optional | Setting this to true will not send transaction reminders/cancelled/expired emails/SMS. Users will still receive payment completed notification. | Default to false. |
Create Charge Response
If a user_api_token
is given and the user has insufficient xfers wallet balance, the response will return the transfer_info
object containing information about the bank the user should transfer to. If multiple banks are available, the transfer_info_array
will also be returned.
If you receive a status code of 503, please retry the request after a period of time. A “Retry-After” header is provided by the response to indicate the length of time (in seconds) before you should retry.
Transactional Charge (Not available yet)
A transactional charge has a bank topup tied to every charge created. That means, if you create a charge for an item that a user has bought - say a pair of jeans costing $25.99 - the user must then topup exactly $25.99 into the bank account number returned in the response. The charge will then go through.
Any wallet balance the user has will not be used. The $25.99 topup will only go towards payment of the pair of jeans.
Set the transactional_only
flag to true
when creating a charge. Note that this feature is only available to selected Xfers partners.
Transactional charges are not subject to KYC limits and merchants do not have to submit KYC documents of their customers.
Payment Notifications
After payment has been completed and verified by Xfers backend, Xfers will send a callback to the notify_url
you provided. This is a server to server HTTPS POST and you will need to acknowledge the callback by providing a HTTP 200 status. It is important to take note that this notification can arrive at your server before or after the customer is redirected to the return_url you provided.
POST https://mysite.com/payment_notification
The following parameters will be part of the HTTPS POST:
Name | Type | Description | Value |
---|---|---|---|
id | string | Xfers’s transaction id unique to each transaction | contract_b840cc9fc5a359c22ed2ccef3427aacd |
idempotency_id (formerly known as order_id) | string | Unique ref no provided by your during your charge call | A012312 |
amount | string | “12.49” | Total value for items |
fees | string | “5.0” | Fees for this payment |
status | string | Payment status. | “pending”, “accepted”, “completed”, “cancelled”, “expired”, “refunded” |
created_at | string | Date this status was created | “2019-05-15T20:04:57+08:00” |
Authorize a Charge
curl "https://sandbox.xfers.io/api/v3/charges/<id>/authorize" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{"auth_code": "512312"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('Vsya_qc5KjiUGK3xyKRgmhb2Atir2wAyizqssRuYJYw');
\Xfers\Xfers::setSGSandbox();
try {
// You must create the charge with user_phone_no param passed in
$chargeId = '782f2a6e1b5642edb10c8b6b215c4814';
$authCode = '213779';
$resp = \Xfers\Charge::authorize($chargeId, $authCode);
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcharge
from xfers import error
xfers.api_key = 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
xfers.set_sg_sandbox()
try:
charge_id = '0e140a1c251e48939d49651b57394737'
auth_code = '123049'
print 'Authorizing charge...'
resp = xfcharge.authorize(charge_id, auth_code)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
Xfers.set_sg_sandbox
begin
charge_id = 'your-charge-id'
auth_code = '012414'
puts "Authorizing charge... #{charge_id}"
resp = Xfers::Charge.authorize charge_id, auth_code
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Authorize a charge");
String chargeId = "236d026fb4a5457ca9f60d3b1e806bbc";
String authCode = "482729";
Charge charge = Charge.authorize(chargeId, authCode, apiKey);
System.out.println(charge.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "contract_b840cc9fc5a359c22ed2ccef3427aacd",
"object": "TransferContract",
"checkout_url" : "https://sandbox.xfers.io/checkout_transaction/b840cc9fc5a359c22ed2ccef3427aacd",
"notify_url" : "https://mysite.com/payment_notification",
"return_url" : "https://mysite.com/return",
"cancel_url" : "https://mysite.com/cancel",
"amount" : "9.99",
"currency" : "SGD",
"order_id" : "A012312",
"description" : "Carousell user - Konsolidate",
"receipt_email" : "",
"total_amount" : "12.49",
"fee_amount" : "0.12",
"status" : "accepted",
"metadata" : {
"firstname":"Tianwei",
"lastname": "Liu"
},
"transfer_info": {
"bank_name_full": "United Overseas Bank",
"bank_name_abbreviation": "UOB",
"bank_account_no": "123456789",
"bank_code": "7375",
"swift_code": "UOVBSGSGXXX",
"unique_id": "89898989",
"outstanding_amount": "0"
}
}
Authorize a previously created charge. This is an optional process that will allow buyer to skip the sign in flow on Xfers, allowing checkout to be completed on merchant site. If a correct auth_code is provided, the charge will immediately become “accepted” by the buyer.
This endpoint is only used if user_phone_no
param was passed in during charge creation. The response will return the transfer_info
object containing information the bank the user should transfer to. If multiple banks are available, the transfer_info_array
will also be returned.
HTTPS Request
POST https://sandbox.xfers.io/api/v3/charges/<id>/authorize
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
auth_code | string | Either auth_code or google_auth_code required | SMS OTP code provided to the buyer | 512312 |
google_auth_code | string | Either auth_code or google_auth_code required | Google Auth OTP code provided to the buyer. If google_auth_enabled of Get Account Info is false , user has not enabled Google Auth with Xfers. Direct users to Xfers 2FA setup page |
738844 |
Cancel a Charge
curl "https://sandbox.xfers.io/api/v3/charges/<CHARGE_ID>/cancel" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
-X POST
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\Charge::cancel("<CHARGE_ID>");
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcharge
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Cancelling charge {}...'.format('<CHARGE_ID>')
resp = xfcharge.cancel('<CHARGE_ID>')
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
charge_id = '<CHARGE_ID>'
puts "Cancelling charge... #{charge_id}"
resp = Xfers::Charge.cancel charge_id
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Cancelling a charge");
Charge charge = Charge.cancel("<CHARGE_ID>", apiKey);
System.out.println(charge.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "contract_b840cc9fc5a359c22ed2ccef3427aacd",
"object": "PendingTransferContract",
"checkout_url" : "https://sandbox.xfers.io/checkout_transaction/b840cc9fc5a359c22ed2ccef3427aacd",
"notify_url" : "https://mysite.com/payment_notification",
"return_url" : "https://mysite.com/return",
"cancel_url" : "https://mysite.com/cancel",
"amount" : "9.99",
"currency" : "SGD",
"order_id" : "A012312",
"description" : "Carousell user - Konsolidate",
"receipt_email" : "",
"total_amount" : "12.49",
"fee_amount" : "0.12",
"status" : "cancelled",
"metadata" : {
"firstname":"Tianwei",
"lastname": "Liu"
},
"transfer_info": {
"bank_name_full": "United Overseas Bank",
"bank_name_abbreviation": "UOB",
"bank_account_no": "123456789",
"bank_code": "7375",
"swift_code": "UOVBSGSGXXX",
"unique_id": "89898989",
"outstanding_amount": "0"
}
}
Cancelling a charge that has been previously created by not yet paid. To refund a paid charge, refer to creating a refund.
HTTPS Request
POST https://sandbox.xfers.io/api/v3/charges/<CHARGE_ID>/cancel
Retrieve a Charge
curl "https://sandbox.xfers.io/api/v3/charges/<id>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\Charge::retrieve("<id>");
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcharge
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Retrieving charge {}...'.format('<id>')
resp = xfcharge.retrieve('<id>')
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
charge_id = '<id>'
puts "Retrieving charge... #{charge_id}"
resp = Xfers::Charge.retrieve charge_id
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Retrieving a charge");
Charge charge = Charge.retrieve("<id>", apiKey);
System.out.println(charge.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "contract_b840cc9fc5a359c22ed2ccef3427aacd",
"object": "TransferContract",
"checkout_url" : "https://sandbox.xfers.io/checkout_transaction/b840cc9fc5a359c22ed2ccef3427aacd",
"notify_url" : "https://mysite.com/payment_notification",
"return_url" : "https://mysite.com/return",
"cancel_url" : "https://mysite.com/cancel",
"amount" : "9.99",
"currency" : "SGD",
"order_id" : "A012312",
"description" : "Carousell user - Konsolidate",
"receipt_email" : "",
"total_amount" : "12.49",
"fee_amount" : "0.12",
"status" : "completed",
"metadata" : {
"firstname":"Tianwei",
"lastname": "Liu"
},
"transfer_info": {
"bank_name_full": "United Overseas Bank",
"bank_name_abbreviation": "UOB",
"bank_account_no": "123456789",
"bank_code": "7375",
"swift_code": "UOVBSGSGXXX",
"unique_id": "89898989",
"outstanding_amount": "0"
}
}
Retrieves the details of a charge that has previously been created. Supply the unique charge ID that was returned from your previous request or provide the ORDER_ID that you previous provided in your create charge call, and Xfers will return the corresponding charge information. The same information is returned when creating or refunding the charge.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/charges/<CHARGE_ID or ORDER_ID>
List all Charges
curl "https://sandbox.xfers.io/api/v3/charges?limit=1" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
$resp = \Xfers\Charge::listAll(array(
'customer' => 'XXXXXXXX',
'limit' => '1'
));
import xfers
from xfers import xfcharge
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Listing all charges...'
params = {
'limit': '1'
}
charges = xfcharge.list_all(params)
for charge in charges:
print 'Charge: {}'.format(charge)
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Listing all charges...'
params = {
'limit'=> '5'
}
charges = Xfers::Charge.list_all params
charges.each { |charge|
puts charge
}
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Listing charges without filter");
List<Charge> charges = Charge.listAll(apiKey);
for (Charge charge : charges) {
System.out.println(charge.toString());
List<Item> items = charge.getItems();
for (Item item : items) {
System.out.println(item.toString());
}
}
System.out.println("Listing charges with filter");
Map<String, Object> params = new HashMap<String, Object>();
params.put("limit", "1");
charges = Charge.listAll(params);
for (Charge charge : charges) {
System.out.println(charge.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Response:
[
{
"id": "contract_b840cc9fc5a359c22ed2ccef3427aacd",
"object": "TransferContract",
"checkout_url" : "https://sandbox.xfers.io/checkout_transaction/b840cc9fc5a359c22ed2ccef3427aacd",
"notify_url" : "https://mysite.com/payment_notification",
"return_url" : "https://mysite.com/return",
"cancel_url" : "https://mysite.com/cancel",
"amount" : "9.99",
"currency" : "SGD",
"order_id" : "A012312",
"description" : "Carousell user - Konsolidate",
"receipt_email" : "",
"total_amount" : "12.49",
"fee_amount" : "0.12",
"status" : "completed",
"metadata" : {
"firstname":"Tianwei",
"lastname": "Liu"
},
"transfer_info": {
"bank_name_full": "United Overseas Bank",
"bank_name_abbreviation": "UOB",
"bank_account_no": "123456789",
"bank_code": "7375",
"swift_code": "UOVBSGSGXXX",
"unique_id": "89898989",
"outstanding_amount": "0"
}
}
]
Returns a list of charges you’ve previously created. The charges are returned in sorted order, with the most recent charges appearing first.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/charges
Cards (Singapore)
The following APIs allow you to add or update credit cards to a connected user (which means you have to go through our Xfers Connect flow to get their user_api_token
). You are also able to charge a credit card without creating an Xfers account for your user (see Charge Guest Card) or to charge the default card belonging to a user (see Charge Existing Card).
Add a Card
curl "https://sandbox.xfers.io/api/v3/cards" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{ "user_api_token": "osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ", "credit_card_token": "tok_197O8gB8MXWbQJDjPMILsIr6", "first6": "424242", "last4": "4242"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o');
\Xfers\Xfers::setSGSandbox();
// Get the following user_api_token from http://docs.xfers.io/#xfers-connect
// you should have one user_api_token for every user you wish to add a credit card to.
$user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ';
try {
echo "Adding card\n";
$params = array(
'user_api_token' => $user_api_token,
'credit_card_token' => 'tok_19BhBuB8MXWbQJDjkspwaL4n', // gotten from http://docs.xfers.io/#xfers-tokenize
'first6' => '424242',
'last4' => '4242'
);
$resp = \Xfers\Card::add($params);
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcard
from xfers import error
xfers.api_key = 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
xfers.set_sg_sandbox()
# Get the following user_api_token from http://docs.xfers.io/#xfers-connect
# you should have one user_api_token for every user you wish to add a credit card to.
user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ'
try:
print 'Adding card...'
params = {
'user_api_token': user_api_token,
'credit_card_token': 'tok_19C22fB8MXWbQJDjSx4Ek9Wk', # gotten from http://docs.xfers.io/#xfers-tokenize
'first6': '424242',
'last4': '4242'
}
resp = xfcard.add(params)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
Xfers.set_sg_sandbox
# Get the following user_api_token from http://docs.xfers.io/#xfers-connect
# you should have one user_api_token for every user you wish to add a credit card to.
user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ'
begin
puts 'Adding card...'
params = {
'user_api_token' => user_api_token,
'credit_card_token' => 'tok_19GiimB8MXWbQJDjF8FUIgpA', # gotten from http://docs.xfers.io/#xfers-tokenize
'first6' => '424242',
'last4' => '4242'
}
resp = Xfers::Card.add params
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
Xfers.apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
String user_api_token = "osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ";
try {
System.out.println("Adding card");
Map<String, Object> params = new HashMap<String, Object>();
params.put("user_api_token", user_api_token);
params.put("credit_card_token", "tok_19DrscB8MXWbQJDjXlIKkc06");
params.put("first6", "424242");
params.put("last4", "4242");
Card card = Card.add(params);
System.out.println("Added card: ");
System.out.println(card.getCardId());
System.out.println(card.getExpMonth());
System.out.println(card.getExpYear());
System.out.println(card.getCardCountry());
System.out.println(card.getCardType());
System.out.println(card.getLast4());
System.out.println(card.getIsDefault());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"card_id": "card_197O8yI7jGeCrIKDeI6SexB6",
"last_4": "4242",
"card_type": "Visa",
"card_country": "US",
"exp_yr": "2022",
"exp_month": "3",
"is_default": false
}
The following request will allow you to add a credit card to your connected user.
POST https://sandbox.xfers.io/api/v3/cards
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
user_api_token | string | required | Buyer’s api token obtain via Connect’s get user token API. | osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ |
credit_card_token | string | required | Tokenized credit card from Xfers Tokenize | tok_197O8gB8MXWbQJDjPMILsIr6 |
first6 | string | required | First 6 digits of credit card. Returned via Xfers Tokenize | 424242 |
last4 | string | required | Last 4 digits of credit card. Returned via Xfers Tokenize | 4242 |
Response
An Xfers Card object.
Name | Type | Description |
---|---|---|
card_id | string | The id of the card added |
last_4 | string | Last 4 digits of credit card |
card_type | string | Card brand. Can be Visa, American Express, MasterCard, Discover, JCB, Diners Club, or Unknown |
card_country | string | Two-letter ISO code representing the country of the card. You could use this attribute to get a sense of the international breakdown of cards you’ve collected |
exp_yr | string | Credit card year |
exp_month | string | Credit card expiry month |
is_default | boolean | Is this the default card to be charged |
List Cards
curl "https://sandbox.xfers.io/api/v3/cards?user_api_token=osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ" \
-H "X-XFERS-USER-API-KEY: WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o');
\Xfers\Xfers::setSGSandbox();
// Get the following user_api_token from http://docs.xfers.io/#xfers-connect
// you should have one user_api_token for every user you wish to add a credit card to.
$user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ';
try {
echo "Listing all cards\n";
$resp = \Xfers\Card::listAll($user_api_token);
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcard
from xfers import error
xfers.api_key = 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
xfers.set_sg_sandbox()
# Get the following user_api_token from http://docs.xfers.io/#xfers-connect
# you should have one user_api_token for every user you wish to add a credit card to.
user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ'
try:
print 'Listing all cards...'
cards = xfcard.list_all(user_api_token)
for card in cards:
print 'Card: {}'.format(card)
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
Xfers.set_sg_sandbox
# Get the following user_api_token from http://docs.xfers.io/#xfers-connect
# you should have one user_api_token for every user you wish to add a credit card to.
user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ'
begin
puts 'Listing all cards...'
cards = Xfers::Card.list_all user_api_token
cards.each { |card|
puts card
}
rescue Xfers::XfersError => e
puts e.to_s
end
Xfers.apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
String user_api_token = "osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ";
try {
System.out.println("Listing cards");
List<Card> cards = Card.listAll(user_api_token);
System.out.println("There are " + cards.size() + " cards");
for (Card card : cards) {
System.out.println(card.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
Response:
[
{
"card_id":"card_196hygI7jGeCrIKDAwXhGcHm",
"last_4":"4242",
"card_type":"Visa",
"card_country":"US",
"exp_yr":"2022",
"exp_month":"3",
"is_default":true
},
{
"card_id":"card_196kFHI7jGeCrIKD7HxYauMv",
"last_4":"4444",
"card_type":"MasterCard",
"card_country":"US",
"exp_yr":"2022",
"exp_month":"5",
"is_default":false
}
]
The following request will allow you to list all credit cards added to a user
GET https://sandbox.xfers.io/api/v3/cards
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
user_api_token | string | required | Buyer’s api token obtain via Connect’s get user token API. | osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ |
Set Default Card
curl "https://sandbox.xfers.io/api/v3/cards/<the_card_id>/set_default" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{ "user_api_token": "osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o');
\Xfers\Xfers::setSGSandbox();
// Get the following user_api_token from http://docs.xfers.io/#xfers-connect
// you should have one user_api_token for every user you wish to add a credit card to.
$user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ';
try {
echo "Setting default card\n";
$card_id = 'card_196iRQI7jGeCrIKDl5hrCmxE';
$resp = \Xfers\Card::setDefault($card_id, $user_api_token);
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcard
from xfers import error
xfers.api_key = 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
xfers.set_sg_sandbox()
# Get the following user_api_token from http://docs.xfers.io/#xfers-connect
# you should have one user_api_token for every user you wish to add a credit card to.
user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ'
try:
print 'Setting default card'
card_id = 'card_196kDPI7jGeCrIKDlgVDBvER'
resp = xfcard.set_default(card_id, user_api_token)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
Xfers.set_sg_sandbox
# Get the following user_api_token from http://docs.xfers.io/#xfers-connect
# you should have one user_api_token for every user you wish to add a credit card to.
user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ'
begin
puts 'Setting default card'
card_id = 'card_196iRQI7jGeCrIKDl5hrCmxE'
resp = Xfers::Card.set_default card_id, user_api_token
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
Xfers.apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
String user_api_token = "osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ";
try {
System.out.println("Setting default card");
String cardId = "card_19C2JSI7jGeCrIKD0nVdiCHp";
Card card = Card.setDefault(cardId, user_api_token);
System.out.println("Default card: " + card.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"card_id": "card_197O8yI7jGeCrIKDeI6SexB6",
"last_4": "4242",
"card_type": "Visa",
"card_country": "US",
"exp_yr": "2022",
"exp_month": "3",
"is_default": true
}
The following request will allow you to set a default credit card for your connected user.
POST https://sandbox.xfers.io/api/v3/cards/<the_card_id>/set_default
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
user_api_token | string | required | Buyer’s api token obtain via Connect’s get user token API. | osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ |
Delete Card
curl -X DELETE "https://sandbox.xfers.io/api/v3/cards/<the_card_id>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{ "user_api_token": "osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o');
\Xfers\Xfers::setSGSandbox();
// Get the following user_api_token from http://docs.xfers.io/#xfers-connect
// you should have one user_api_token for every user you wish to add a credit card to.
$user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ';
try {
echo "Deleting card\n";
$card_id = 'card_196hygI7jGeCrIKDAwXhGcHm';
$resp = \Xfers\Card::delete($card_id, $user_api_token);
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcard
from xfers import error
xfers.api_key = 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
xfers.set_sg_sandbox()
# Get the following user_api_token from http://docs.xfers.io/#xfers-connect
# you should have one user_api_token for every user you wish to add a credit card to.
user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ'
try:
print 'Deleting card'
card_id = 'card_19BhF9I7jGeCrIKD1ICQ6snN'
resp = xfcard.delete(card_id, user_api_token)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
Xfers.set_sg_sandbox
# Get the following user_api_token from http://docs.xfers.io/#xfers-connect
# you should have one user_api_token for every user you wish to add a credit card to.
user_api_token = 'osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ'
begin
puts 'Deleting card'
card_id = 'card_19C2JSI7jGeCrIKD0nVdiCHp'
resp = Xfers::Card.delete card_id, user_api_token
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
Xfers.apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
String user_api_token = "osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ";
try {
System.out.println("Deleting card");
String cardId = "card_196kDPI7jGeCrIKDlgVDBvER";
Card card = Card.delete(cardId, user_api_token);
System.out.println("Deleted card: " + card.toString());
System.out.println(card.getCardId());
System.out.println(card.getDeleted());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"card_id": "card_197O8yI7jGeCrIKDeI6SexB6",
"deleted": true
}
The following request will allow you to delete your user’s credit card.
DELETE https://sandbox.xfers.io/api/v3/cards/<the_card_id>
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
user_api_token | string | required | Buyer’s api token obtain via Connect’s get user token API. | osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ |
Charge Guest Card
curl "https://sandbox.xfers.io/api/v3/credit_card_charges/charge_card_guest" \
-H "Content-Type: application/json" \
-d '{ "txn_id": "<charge_id>", "credit_card_token":"tok_197O8gB8MXWbQJDjPMILsIr6", "first6": "424242", "last4": "4242"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setSGSandbox();
try {
echo "Charge guest card\n";
$chargeId = '051ac2fe464d45b19ec736cf04d66653'; // you must create a charge first
$params = array(
'txn_id' => $chargeId,
'credit_card_token' => 'tok_19BhUlB8MXWbQJDjOrDecHN6', // gotten from http://docs.xfers.io/#xfers-tokenize
'first6' => '424242',
'last4' => '4242'
);
$resp = \Xfers\Card::chargeGuest($params);
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
try:
print 'Charge guest card'
charge_id = 'f0fbdd1c16b44deba3f15cc11a29fefc' # you must create a charge first
params = {
'txn_id': charge_id,
'credit_card_token': 'tok_19C5hlB8MXWbQJDjT6HAsM3A', # gotten from http://docs.xfers.io/#xfers-tokenize
'first6': '424242',
'last4': '4242'
}
resp = xfcard.charge_guest(params)
print resp
except error.XfersError as e:
print str(e)
begin
puts 'Charge guest card'
charge_id = '54539f543f33456a98495bda4bc33abe'
params = {
'txn_id' => charge_id,
'credit_card_token' => 'tok_19GijKB8MXWbQJDjKCniMsgn', # gotten from http://docs.xfers.io/#xfers-tokenize
'first6' => '424242',
'last4' => '4242'
}
resp = Xfers::Card.charge_guest params
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
try {
System.out.println("Charge guest card");
String chargeId = "ae9647515a234b95919ce5dbd6e073e8";
Map<String, Object> params = new HashMap<String, Object>();
params.put("txn_id", chargeId);
params.put("credit_card_token", "tok_19DrtcB8MXWbQJDjjTYpBAsJ");
params.put("first6", "424242");
params.put("last4", "4242");
Response res = Card.chargeGuest(params);
System.out.println("Charge guest card success " + res.getSuccess());
System.out.println("Charge guest card return url " + res.getReturnUrl());
System.out.println("Charge guest card response " + res.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"success": true,
"return_url": "https://www.yoursite.com"
}
The following request will allow you to charge a newly obtained credit card token from Xfers Tokenize. This credit card charge is not linked to any user, so you will not be able to save the token for reuse. Note that each credit card token can only be used once - either charge it directly with this endpoint, or add the token to a user.
One use case is to be able to charge a credit card without the user having to go through OTP, since no Xfers account needs to be created (usually because it is a guest user on your platform and you want to speed up the checkout process).
No API key authentication is needed. Instead, we will only charge a card if a valid charge id is found together with a valid credit card token.
POST https://sandbox.xfers.io/api/v3/credit_card_charges/charge_card_guest
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
txn_id | string | required | The id of the created charge | b840cc9fc5a359c22ed2ccef3427aacd |
credit_card_token | string | required | Tokenized credit card from Xfers Tokenize | tok_197O8gB8MXWbQJDjPMILsIr6 |
first6 | string | required | First 6 digits of credit card | 424242 |
last4 | string | required | Last 4 digits of credit card | 4242 |
Charge Existing Card
curl "https://sandbox.xfers.io/api/v3/credit_card_charges/charge_card" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{ "txn_id": "<charge_id>"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o');
\Xfers\Xfers::setSGSandbox();
try {
echo "Charge existing card\n";
// You must add a credit card with Xfers\Card::add before this
$chargeId = 'ae9647515a234b95919ce5dbd6e073e8'; // you must create a charge with user_api_token of your user passed in
$resp = \Xfers\Card::chargeExisting($chargeId);
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcard
from xfers import error
xfers.api_key = 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
xfers.set_sg_sandbox()
try:
print 'Charge existing card'
# You must add a credit card with xfcard.add before this
charge_id = '59290c99da0044b398445c24a63d5cf7' # you must create a charge first with user_api_token of your user
resp = xfcard.charge_existing(charge_id)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key 'WuTp3zM7UEpmUkeAyGPxRHmnXAx-hXJ7jzdqmxY6S1o'
Xfers.set_sg_sandbox
begin
puts 'Charge existing card'
charge_id = '9cfaac1c8d8a47d18540a87f4c1e711b'
resp = Xfers::Card.charge_existing charge_id
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
Xfers.apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
String user_api_token = "osEdbc8uzxY5vaXA-oe-7E86sVWCYTCVPuHQyFQ-uPQ";
try {
System.out.println("Charge existing card");
String chargeId = "3115641fa59e45f1b31e0f60f059b3ef";
Response res = Card.chargeExisting(chargeId);
System.out.println("Charge existing card success " + res.getSuccess());
System.out.println("Charge existing card return url " + res.getReturnUrl());
System.out.println("Charge existing card response " + res.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"success": true,
"return_url": "https://www.yoursite.com"
}
The following request will allow you to charge a user with his existing default card. Before this, the Charge must be created with user_api_token
of your user passed in.
POST https://sandbox.xfers.io/api/v3/credit_card_charges/charge_card
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
txn_id | string | required | The id of the created charge | b840cc9fc5a359c22ed2ccef3427aacd |
Payouts
Xfers Payout allows you transfer money between Xfers Wallets with your Xfers balance via their phone no or email address. You need to have sufficient available balance in your account to cover the amount + fees required for the payout.
Creating a Payout
curl "https://sandbox.xfers.io/api/v3/payouts" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-d '{"amount": "150.00", "invoice_id": "AZ0001", "descriptions": "Payment for Rent for July", "recipient": "+65XXXXXXXX"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\Payout::create(array(
'amount' => '150.00',
'invoice_id' => 'AZ0001',
'descriptions' => 'Payment for Rent for July',
'recipient' => '+65XXXXXXXX'
));
print_r($resp);
echo $resp["id"] . "\n";
echo $resp["recipient"] . "\n";
echo $resp["invoice_id"] . "\n";
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught invalid request exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfpayout
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Creating payout...'
params = {
'amount': '150.00',
'invoice_id': 'AZ0001',
'descriptions': 'Payment for Rent for July',
'recipient': '+65XXXXXXXX'
}
resp = xfpayout.create(params)
payout_id = resp['id']
print payout_id
print resp['recipient']
print resp['invoice_id']
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Creating payout...'
params = {
'amount' => '150.00',
'invoice_id' => 'AZ0001',
'descriptions' => 'Payment for Rent for July',
'recipient' => '+65XXXXXXXX'
}
resp = Xfers::Payout.create params
payout_id = resp[:id]
puts resp[:recipient]
puts resp[:invoice_id]
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Creating a payout");
Map<String, Object> params = new HashMap<String, Object>();
params.put("amount", "150.00");
params.put("invoice_id", "AZ0001");
params.put("recipient", "+65XXXXXXXX");
params.put("descriptions", "Payment for Rent for July");
Payout payout = Payout.create(params,apiKey);
payoutId = payout.getId();
System.out.println(payout.getId());
System.out.println(payout.getRecipient());
System.out.println(payout.getAmount());
System.out.println(payout.getCurrency());
System.out.println(payout.getDescriptions());
System.out.println(payout.getBank());
System.out.println(payout.getBankAccountNo());
System.out.println(payout.getCreatedDate());
System.out.println(payout.getCompletedDate());
System.out.println(payout.getStatus());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "6fa51cd08c8ae115f858593412bb72c8",
"recipient" : "+65XXXXXXXX",
"invoice_id" : "AZ0001",
"amount" : 150.00,
"currency" : "SGD",
"descriptions" : "Payment for Rent for July",
"bank" : "",
"bank_account_no" : "",
"created_date" : "2015-07-01T19:01:25Z",
"completed_date" : "",
"status" : "completed",
"meta_data" : "Liu Tianwei"
}
The following request will allow you to make a payout to the recipient.
POST https://sandbox.xfers.io/api/v3/payouts
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
amount | float | required | Total value for items. | 150.00 |
invoice_id | string | required | Unique ref no provided by merchant. This will need to be unique or the payout request will be considered a duplicate and ignored. | AZ0001 |
recipient | string | optional (either recipient or user_api_token required) | Email or Mobile Phone No of the recipient for this payout. | +659728860 |
user_api_token | string | optional (either recipient or user_api_token required) | user’s api token obtain via Connect’s get user token APIs. When this is provided, it will replace the recipient param as the payout target | |
currency | string | optional | 3-letter ISO code for currency | Default to ‘SGD’ |
descriptions | string | optional | A short description for this payout. This will be part of the email/SMS that the recipient will be receiving from Xfers. | Payment for Rent for July |
wallet_id | integer | optional | Coming Soon | Default to XFERS Wallet |
meta_data | string | optional | An internal description that you can attach to a payout. It can be useful for storing additional information about the customer in a structured format. You will be provided with these meta_data in your queries for payouts. | Liu Tianwei |
Payout Response Status
The below are the possible response status and their meaning.
Name | Description |
---|---|
completed | Payout has been completed. Existing Xfers user and payout has been credited to his account. |
Retrieve a Payout
curl "https://sandbox.xfers.io/api/v3/payouts/<id>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\Payout::retrieve("<id>");
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught invalid request exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfpayout
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Retrieving payout {}...'.format('<id>')
resp = xfpayout.retrieve('<id>')
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Retrieving payout...'
resp = Xfers::Payout.retrieve '<id>'
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Retrieving a payout");
Payout payout = Payout.retrieve("<id>", apiKey);
System.out.println(payout.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "6fa51cd08c8ae115f858593412bb72c8",
"recipient" : "+65XXXXXXXX",
"invoice_id" : "AZ0001",
"amount" : 150.00,
"currency" : "SGD",
"descriptions" : "Payment for Rent for July",
"bank" : "",
"bank_account_no" : "",
"created_date" : "2015-07-01T19:01:25Z",
"completed_date" : "",
"status" : "completed",
"meta_data" : "Liu Tianwei"
}
Retrieves the details of a payout that has previously been created. Supply the unique payout ID that was returned from your previous request, and Xfers will return the corresponding payout information.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/payouts/<id>
The below is a list of payout status and their respective meanings.
Payout Status
Name | Description |
---|---|
completed | Payout has been completed. |
cancelled | Payout has been cancelled. |
List all Payouts
curl "https://sandbox.xfers.io/api/v3/payouts?limit=1" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
$resp = \Xfers\Payout::listAll(array(
'limit' => '1'
));
print_r($resp);
import xfers
from xfers import xfpayout
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Listing all payouts...'
params = {
'recipient': '+65XXXXXXXX'
}
payouts = xfpayout.list_all(params)
for payout in payouts:
print 'Payout: {}'.format(payout)
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Listing all payouts...'
params = {
'recipient'=> '+65XXXXXXXX'
}
payouts = Xfers::Payout.list_all params
payouts.each { |payout|
puts payout
}
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Listing payouts");
Map<String, Object> params = new HashMap<String, Object>();
params.put("recipient", "+65XXXXXXXX");
List<Payout> payouts = Payout.listAll(params, apiKey);
for (Payout payout : payouts) {
System.out.println(payout.getId());
System.out.println(payout.getInvoiceId());
System.out.println(payout.getRecipient());
System.out.println(payout.getAmount());
System.out.println(payout.getCurrency());
System.out.println(payout.getDescriptions());
System.out.println(payout.getBank());
System.out.println(payout.getBankAccountNo());
System.out.println(payout.getCreatedDate());
System.out.println(payout.getCompletedDate());
System.out.println(payout.getStatus());
}
} catch (Exception e) {
e.printStackTrace();
}
Response:
[
{
"id": "6fa51cd08c8ae115f858593412bb72c8",
"recipient" : "+65XXXXXXXX",
"invoice_id" : "AZ0001",
"amount" : 150.00,
"currency" : "SGD",
"descriptions" : "Payment for Rent for July",
"bank" : "",
"bank_account_no" : "",
"created_date" : "2015-07-01T19:01:25Z",
"completed_date" : "",
"status" : "completed",
"meta_data" : "Liu Tianwei"
}
]
Returns a list of payouts you’ve previously created. The payouts are returned in sorted order, with the most recent charges appearing first.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/payouts
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
recipient | string | optional | Only return charges for the recipient(email for phone no) specified by this recipient ID. | +65XXXXXXXX |
ending_before | string | optional | A cursor for use in pagination. ending_before is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, starting with obj_bar, your subsequent call can include ending_before=obj_bar in order to fetch the previous page of the list. | 6fa51cd08c8ae115f858593412bb72c8 |
limit | integer | optional | A limit on the number of objects to be returned. Limit can range between 1 and 50 items. | Default to 10 |
starting_after | string | optional | A cursor for use in pagination. starting_after is an object ID that defines your place in the list. For instance, if you make a list request and receive 100 objects, ending with obj_foo, your subsequent call can include starting_after=obj_foo in order to fetch the next page of the list. | 6fa51cd08c8ae115f858593412bb72c8 |
Refunds
The following APIs allow you to refund a charge that has previously been created and paid by your buyer.
For bank transfer transaction, funds will be refunded to the buyer’s Xfers account. The fees you were originally charged are also refunded.
For credit card (SG) transaction, refund will be done directly to the credit card account and customer will be able to see it in 5-10 business days. Once issued, credit card refund cannot be canceled.
For credit card (ID) transaction, refund is not yet available.
Creating a Refund
curl "https://sandbox.xfers.io/api/v3/charges/<id>/refunds" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
-X POST
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\Charge::refund("<id>");
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfcharge
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
charge_id = '<id>'
print 'Refunding charge {}...'.format(charge_id)
resp = xfcharge.refund(charge_id)
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
charge_id = '<id>'
puts "Refunding charge... #{charge_id}"
resp = Xfers::Charge.refund charge_id
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Refunding a charge");
Charge charge = Charge.refund("<id>", apiKey);
System.out.println(charge.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "6fa51cd08c8ae115f858593412bb72c8",
"checkout_url" : "https://sandbox.xfers.io/checkout_transaction/b840cc9fc5a359c22ed2ccef3427aacd",
"notify_url" : "https://mysite.com/payment_notification",
"return_url" : "https://mysite.com/return",
"cancel_url" : "https://mysite.com/cancel",
"object" : "charge",
"amount" : 9.99,
"currency" : "SGD",
"customer" : "",
"order_id" : "A012312",
"capture" : true,
"description" : "Carousell user - Konsolidate",
"items" : [
{
"description": "Red Dress Size M",
"name": "Red dress",
"quantity": "1.00",
"price": 9.99,
"item_id": ""
}
],
"statement_descriptor" : "",
"receipt_email" : "",
"shipping" : 2.50,
"tax" : 0.00,
"total_amount" : 12.49,
"status" : "refunded",
"meta_data" : {
"key1":"value1",
"key2": "value2"
}
}
When you create a new refund, you must specify a charge to create it on. If you intend to refund a charge immediately upon creation, please minimally wait for 2 minutes. This is due to the delay in the status transition for charge. You cannot refund a charge that’s still in processing state.
Creating a new refund will refund a charge that has previously been created and paid but not yet refunded. Funds will be refunded to the buyer Xfers account available balance. The fees you were originally charged are also refunded.
Please input the merchant/seller’s API key for this endpoint
HTTPS Request
POST https://sandbox.xfers.io/api/v3/charges/<id>/refunds
Intents
The Intent API serve two purposes.
- It allow Xfers to generate unique transfer amount to better identity the owner of incoming transfer when non virtual account system is being used.
- It allow developers to register for a callback notification when user fund their Xfers wallet.
For user case 1:
when a user is performing a top up via GET /transfer_info, they might forget to enter their contact number which is needed for our system to identify them.
The Intents API solves this issue by requiring the user to transfer a unique amount to Xfers which will be used to identify them. The difference between the unique_amount
and the actual amount
will be very small, and Xfers provides the difference for free to the user.
Note that this only acts as a backup, and the user should enter his contact number in the comments section when doing a bank transfer whenever possible.
Example:
Jane wishes to transfer 5000 Indonesian Rupiah via /intents
.
- She makes a HTTP GET request to
/user/transfer_info
to get the correct Xfers bank to transfer to (we have many banks!). The response tells her to transfer to Bank Central Asia (BCA). - She makes a HTTP POST request to create an intent. The response tells her to make a bank transfer of 4999 to Xfers.
- Jane makes a transfer of 4999 to Xfers BCA. Within a few minutes, Xfers detects the transfer and tops up Jane’s Xfers account with 5000. Xfers absorbs the difference for free.
- If
notify_url
is given, Xfers will send a callback to this url.
For user case 2:
Intent can also be use a means to get callback notifications from Xfers when a user successfully fund their virtual account on Xfers.
Example:
Jane wishes to transfer 5000 Indonesian Rupiah via /intents
to her virtual Xfers account and get a callback notification when it successful
- She makes a HTTP POST request to create an intent with disable_va set to false(default) and provide a
notify_url
. The response will provide a list of virtual account nos she can fund her account with from a list of bank that Xfers support. - Jane makes a transfer of 500 to the Xfers BCA Virtual account that the intent api provide. Within a few minutes, Xfers detects the transfer and tops up Jane’s Xfers account with 5000.
- Since
notify_url
is provided, Xfers will send a callback to this url.
Creating an Intent
curl "https://sandbox.xfers.io/api/v3/intents" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
-H "Content-Type: application/json" \
-d '{ "amount": "5000", "currency": "SGD", "bank": "BCA", "request_id" : "AZ0001", "notify_url" : "https://mysite.com/topup_notification"}'
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\Intent::create(array(
'amount' => '5000',
'currency' => 'SGD',
'bank' => 'BCA',
'request_id' => 'AZ0001',
'notify_url' => 'https://mysite.com/topup_notification'
));
$intentId = $resp["id"];
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfintent
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Creating intent...'
params = {
'amount': '5000',
'currency': 'SGD',
'bank': 'BCA',
'request_id': 'AZ0001',
'notify_url': 'https://mysite.com/topup_notification'
}
resp = xfintent.create(params)
intent_id = resp['id']
print intent_id
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Creating intent...'
params = {
'amount' => '5000',
'currency' => 'SGD',
'bank' => 'BCA',
'request_id' => 'AZ0001',
'notify_url' => 'https://mysite.com/topup_notification'
}
resp = Xfers::Intent.create params
intent_id = resp[:id]
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Creating an intent");
Map<String, Object> params = new HashMap<String, Object>();
params.put("amount", "5000");
params.put("currency", "SGD");
params.put("bank", "BCA");
params.put("request_id", "AZ0001");
params.put("notify_url", "https://mysite.com/topup_notification");
Intent intent = Intent.create(params, apiKey);
System.out.println(intent.getId());
System.out.println(intent.getAmount());
System.out.println(intent.getCurrency());
System.out.println(intent.getBankName());
System.out.println(intent.getBankAbbrev());
System.out.println(intent.getBankAccountNo());
System.out.println(intent.getRequestId());
System.out.println(intent.getNotifyUrl());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "a975f036cb4b43f3b2d1ff90040ec292",
"request_id": "AI1001",
"amount": "30000.0",
"currency": "IDR",
"unique_amount": "29999",
"bank_abbrev": "MANDIRI",
"bank_name": "Bank Mandiri",
"account_name": "PT Media Indonusa",
"bank_account_no": "8855845678901235",
"notify_url": "https://mysite.com/topup_notification",
"expiration_date": "2017-06-01T07:46:40Z",
"status": "pending",
"transfer_info_array":
[
{
"bank_name_full": "Bank Central Asia",
"bank_name_abbreviation": "BCA",
"bank_account_no": "1063003003",
"bank_code": "",
"branch_code": "",
"branch_area": "",
"unique_id": "97266867",
"img_src": "https://www.xfers.io/images/bankLogos/bank-logo-bca.png"
},
{
"bank_name_full": "Bank Mandiri",
"bank_name_abbreviation": "MANDIRI",
"bank_account_no": "8855845678901235",
"bank_code": "",
"branch_code": "",
"branch_area": "",
"unique_id": "97266867",
"img_src": "https://www.xfers.io/images/bankLogos/bank-logo-mandiri.png"
}
]
}
The following request will allow you to create a intent for a transfer and register a callback notification once a transfer has be received or expired(all intents expires in 72 hours.)
User should be prompted to transfer unique_amount
amount to the bank_account_no
and bank_name
provided. Once the user deposits with unique_amount
, the full amount will be credited to his account.
POST https://sandbox.xfers.io/api/v3/intents
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
amount | float | required | Amount that user intends to transfer | 5000 |
currency | string | required | 3-letter ISO code for currency(IDR/SGD) | |
request_id | string | required | Unique ref no provided by requester. This will need to be unique or the intent request will be considered a duplicate and ignored. | AZ0001 |
bank | string | optional | bank abbreviation (BCA, UOB, MANDIRI) | BCA |
notify_url | string | optional | URL to receive callback notifications when transfer is received | https://mysite.com/payment_notification |
disable_va | boolean | optional | If true, does not return a Virtual Account for this intent | Defaults to false |
Intent Notifications
After intent has been verified(transfer processed)/expired by Xfers, Xfers will send a callback to the notify_url
you provided. This is a server to server HTTPS POST and you will need to acknowledge the callback by providing a HTTP 200 status.
POST https://mysite.com/topup_notification
The following parameters will be part of the HTTPS POST:
Name | Type | Description | Value |
---|---|---|---|
intent_id | string | Xfers’s id unique to each intent | 6f5f85859a51cd08c8ae113412bb72c8 |
request_id | string | Unique ref no provided by your during your intent call | A012312 |
amount | float | 3000 | Amount that user intented to transfer. |
currency | string | required | 3-letter ISO code for currency(IDR/SGD) |
status | string | Transfer status. | “expired” or “completed” |
Cancel a Intent
curl "https://sandbox.xfers.io/api/v3/intent/<INTENT_ID>/cancel" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
-X POST
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
try {
$resp = \Xfers\Intent::cancel('<INTENT_ID>');
print_r($resp);
} catch (\Xfers\Error\InvalidRequest $e) {
echo 'Caught InvalidRequest exception: ', $e->getMessage(), "\n";
}
import xfers
from xfers import xfintent
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Cancelling intent {}...'.format('<INTENT_ID>')
resp = xfintent.cancel('<INTENT_ID>')
print resp
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Cancelling intent...'
resp = Xfers::Intent.cancel '<INTENT_ID>'
puts resp
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Cancelling an intent");
Intent intent = Intent.cancel("<INTENT_ID>", apiKey);
System.out.println(intent.toString());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "6f5f85859a51cd08c8ae113412bb72c8",
"request_id" : "AZ0001",
"amount" : "5000",
"currency" : "IDR",
"amount_to_transfer" : "4999",
"bank_name" : "Bank Central Asia",
"bank_abbrev" : "BCA",
"account_name" : "Xveria Media Indonesia",
"bank_account_no" : "0124121241",
"notify_url" : "https://mysite.com/topup_notification",
"expiration_date" : "2016-09-09T17:55:51Z",
"status" : "pending"
}
Cancelling a intent that has been previously created by not yet completed.
HTTPS Request
POST https://sandbox.xfers.io/api/v3/intent/<INTENT_ID>/cancel
List current Intent
curl "https://sandbox.xfers.io/api/v3/intents" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
<?php
require_once('vendor/autoload.php');
\Xfers\Xfers::setApiKey('2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk');
\Xfers\Xfers::setSGSandbox();
$resp = \Xfers\Intent::retrieve();
print_r($resp);
import xfers
from xfers import xfintent
from xfers import error
xfers.api_key = '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
xfers.set_sg_sandbox()
try:
print 'Current intent...'
intent = xfintent.retrieve()
print 'Intent: {}'.format(intent)
except error.XfersError as e:
print str(e)
require 'xfers'
Xfers.set_api_key '2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk'
Xfers.set_sg_sandbox
begin
puts 'Current intent...'
intent = Xfers::Intent.retrieve
puts intent
rescue Xfers::XfersError => e
puts e.to_s
end
String apiKey = "2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk";
Xfers.setSGSandbox();
try {
System.out.println("Retrieving latest intent");
Intent intent = Intent.retrieve(apiKey);
System.out.println(intent.getId());
System.out.println(intent.getAmount());
System.out.println(intent.getCurrency());
System.out.println(intent.getBankName());
System.out.println(intent.getBankAbbrev());
System.out.println(intent.getBankAccountNo());
System.out.println(intent.getRequestId());
System.out.println(intent.getNotifyUrl());
} catch (Exception e) {
e.printStackTrace();
}
Response:
{
"id": "6f5f85859a51cd08c8ae113412bb72c8",
"request_id" : "AZ0002",
"amount" : "4000",
"currency" : "IDR",
"amount_to_transfer" : "3999",
"bank_name" : "Bank Central Asia",
"bank_abbrev" : "BCA",
"account_name" : "Xveria Media Indonesia",
"bank_account_no" : "0124121241",
"notify_url" : "https://mysite.com/topup_notification",
"expiration_date" : "2016-09-09T17:55:51Z",
"status" : "pending",
"transfer_info_array": [
{
"bank_name_full" : "Bank Central Asia",
"bank_name_abbreviation" : "BCA",
"bank_account_no" : "1063003003",
"bank_code" : "",
"branch_code" : "",
"branch_area" : "",
"unique_id" : "XXXXXXXX",
"img_src": "https://xfers.com/bank-logo-bca.png"
},
{
"bank_name_full" : "Bank Mandiri",
"bank_name_abbreviation" : "MANDIRI",
"bank_account_no" : "1190006792749",
"bank_code" : "",
"branch_code" : "",
"branch_area" : "",
"unique_id" : "XXXXXXXX",
"img_src": "https://xfers.com/bank-logo-mandiri.png"
},
{
"bank_name_full" : "Bank Negara Indonesia",
"bank_name_abbreviation" : "BNI",
"bank_account_no" : "8000067885",
"bank_code" : "",
"branch_code" : "",
"branch_area" : "",
"unique_id" : "XXXXXXXX",
"img_src": "https://xfers.com/bank-logo-bni.png"
}
]
}
Returns the current pending intent of the user. If multiple intents are created, only the last one is returned.
transfer_info_array
is returned so you can display a list of all Xfers banks to transfer to.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/intents
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
disable_va | boolean | optional | If true, does not return a Virtual Account for intent | Defaults to false |
OTP
Mock OTP
curl "https://sandbox.xfers.io/api/v3/authorize/get_mock_otp?phone_no=83999455" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
Response:
{
"otp": "039087"
}
This endpoint allows you to retrieve the OTP of a number when doing testing on sandbox. It is NOT available in production. For international number, you can use ’%2B’ to replace the plus(’+’) sign. (i.e. use %2B6287785725657 instead of +6287785725657)
GET https://sandbox-id.xfers.com/api/v3/authorize/get_mock_otp
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
phone_no | string | required | Phone number for the otp you want to retrieve | 83999455 |
Resend OTP
curl "https://sandbox.xfers.io/checkout_transaction/request_otp" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk" \
-H "Content-Type: application/json" \
-X PUT \
-d '{"phoneNumber": "85993955", "trans_id": "b840cc9fc5a359c22ed2ccef3427aacd"}'
Response:
{
"number_valid": "true"
}
This endpoint allows you to resend the OTP to a phone. This is only used for charge with parameter “user_phone_no” inputted to it.
URL Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
phoneNumber | string | required | Phone number to resend to. If it is a registered user, please use their email instead. | 83999455 |
trans_id | string | required | ID of the transaction (charge) | b840cc9fc5a359c22ed2ccef3427aacd |
Support
The following APIs allow you to integrate payment support functionality directly into your app.
Creating a Support Ticket
curl "https://sandbox.xfers.io/api/v3/support" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
-H "Content-Type: application/json" \
-d '{ "file": "bank_transfer_receipt.jpg", "intent_id": "6f5f85859a51cd08c8ae113412bb72c8", "description": "Transferred an hour ago but money still not credited", "email": "bobby@gmail.com", "amount": 5.89, "date": "13/02/2017", "time": "23:59"}'
Response:
{
"support_id": "35331",
"intent_id": "b840cc9fc5a359c22ed2ccef3427aacd",
"date": "2016-08-13",
"time": "3:39",
"account_holder_name": "Tian Wei",
"bank_abbrev": "BCA",
"account_no": "0124121241",
"amount": 132549,
"currency": "IDR",
"status": "processing"
}
Create a support ticket to be processed by Xfers Customer Support team.
You can use either application/x-www-form-urlencoded
(HTTP URL to file) or multipart/form-data
(file upload) Content-Types.
POST https://sandbox.xfers.io/api/v3/support
Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
description | string | required | Any additional information | I submitted without contact number in the initial/comments section |
date | string | required | Date the transfer was made (DD/MM/YYYY) | 13/08/2017 |
time | string | required | Approximate time the transfer was made (HH:MM) | 21:30 |
string | required | User’s email so we can get back to them | bobby@gmail.com | |
amount | float | required | Amount user transferred | 5.89 |
file | string | required | File or URL of the receipt image | bank_transfer_receipt.jpg |
charge_id | string | Either charge or intent required | ID of the charge | b840cc9fc5a359c22ed2ccef3427aacd |
intent_id | string | Either charge or intent required | ID of the intent | b840cc9fc5a359c22ed2ccef3427aacd |
Retrieve Support Ticket
curl "https://sandbox.xfers.io/api/v3/support/<SUPPORT_ID>" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
Processing Response:
{
"support_id": "35331",
"intent_id": "b840cc9fc5a359c22ed2ccef3427aacd",
"date": "2016-08-13",
"time": "3:39",
"account_holder_name": "Tian Wei",
"bank_abbrev": "BCA",
"account_no": "0124121241",
"amount": 132549,
"currency": "IDR",
"status": "processing"
}
Resolved Response:
{
"support_id": "35331",
"intent_id": "b840cc9fc5a359c22ed2ccef3427aacd",
"date": "2016-08-13",
"time": "3:39",
"account_holder_name": "Tian Wei",
"bank_abbrev": "BCA",
"account_no": "0124121241",
"status": "resolved",
"amount": 132549,
"currency": "IDR",
"msg": "The bank transfer of Rp 132549 has been detected and credited into tianwei@xfers.io's account"
}
Attention Response:
{
"support_id": "35331",
"intent_id": "b840cc9fc5a359c22ed2ccef3427aacd",
"date": "2016-08-13",
"time": "3:39",
"account_holder_name": "Tian Wei",
"bank_abbrev": "BCA",
"account_no": "0124121241",
"status": "attention",
"msg": "We are unable to find a matching bank transfer. Please contact support@xfers.io."
}
Returns a particular support ticket.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/support/<SUPPORT_ID>
List all Support Tickets
curl "https://sandbox.xfers.io/api/v3/support" \
-H "X-XFERS-USER-API-KEY: 2zsujd47H3-UmsxDL784beVnYbxCYCzL4psSbwZ_Ngk"
Response:
[
{
"support_id": "35331",
"intent_id": "b840cc9fc5a359c22ed2ccef3427aacd",
"date": "2016-08-13",
"time": "3:39",
"account_holder_name": "Tian Wei",
"bank_abbrev": "BCA",
"account_no": "0124121241",
"amount": 132549,
"currency": "IDR",
"status": "processing"
},
{
"support_id": "40000",
"intent_id": "94b72ef0fbdb4d55a26c581a8b1a2451",
"date": "2016-08-22",
"time": "23:45",
"account_holder_name": "Ying Ling",
"bank_abbrev": "MANDIRI",
"account_no": "038838383884",
"amount": 48854,
"currency": "IDR",
"status": "resolved"
}
]
List all support tickets linked to your platform.
HTTPS Request
GET https://sandbox.xfers.io/api/v3/support
Parameters
Name | Type | Required | Description | Value |
---|---|---|---|---|
status | string | optional | Filter by status | ‘resolved’ or 'attention’ or 'processing’ |
Xfers Tokenize
Tokenized credit card response
{
"first6": "424242",
"last4": "4242",
"credit_card_token": "tok_197O8gB8MXWbQJDjPMILsIr6"
}
Xfers Tokenize is a set of SDKs that allow you to collect credit card details without having the sensitive information touch your server. By doing this, you do not have to deal with PCI compliance issues.
Credit card tokenization is the process of sending the credit card information to a PCI compliant party which will store the credit card details on your behalf and return a credit card token. This token can then be used to charge the credit card or to save the card with a user.
Singapore
There are two ways of doing this tokenization:
- After creating a Charge, a
checkout_url
is returned. Ifuser_api_token
andcard_only
params are used, thecheckout_url
will lead directly to the credit card form. You can either redirect the user to that page, or embed it as a webview (usually for mobile apps). Thus you are in control of all aspects of the UI except for the credit card form. - Use Xfers Tokenize to return a credit card token which you can use to complete a credit card charge, or to add the credit card to your user’s account. Xfers Tokenize will make use of the form you created to collect credit card details, so the styling is entirely in your control.
As you can see, the two ways have a tradeoff between UI/UX customization and the amount of technical integration required on your end.
There are two ways of using the tokenized credit card response.
- Use Charge Guest Card to charge this credit card for guest user. This can be done on the client side and does not need API key authentication
- Send the response to your server and add the card to your user
Web
Singapore Xfers.js is our client-side Javascript library for credit card tokenization. Indonesia Xfers.js is our client-side Javascript library for credit card tokenization.
Testing
We’ve made a testing guide at https://www.xfers.com/sg/developers/getting-started-with-testing/ for you to easily get started!
Errors
Xfers API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request – Your request is invalid or has errors. |
401 | Unauthorized – Your API key is incorrect. |
404 | Not Found – The specified request could not be found |
408 | Request Timeout – Our website or corresponding site takes too much time to handle. Try again later. |
409 | API Conflict – We received the similar request within close time of the last request. |
429 | Too Many Requests – You are making too many request too quickly. |
500 | Internal Server Error – We had a problem with our server. Contact support@xfers.io and try again later. |
503 | Service Unavailable – We’re temporarially offline for maintanance. Please try again later. |
Changelog
=================== 9 November, 2018 ===================
Summary Add Java SDK for get_withdrawal_request
=================== 25 September, 2018 ===================
Summary
Added KTP-specific request body and possible values in update_account_info
.
Add id in withdrawal_notification =================== 10 September, 2018 ===================
Summary
Added id in user get_account_info
, update_account_info
, and verify_user
API.
=================== 31 August, 2018 ===================
Summary
Changing the callback body of update_account_info
.
=================== 27 August, 2018 ===================
Summary Added feature to authorize charge by Google Auth instead of phone SMS OTP
- Call get account info API to check whether user has enabled Google Auth 2FA from the
google_auth_enabled
flag.
If google_auth_enabled
is false
, direct users to Xfers 2FA setup page
Create charge by passing in
user_phone_no
, settinggoogle_auth
to betrue
.Authorize charge by passing in
google_auth_code
=================== 15 August, 2018 ===================
Summary Get activities API now accepts dates in ISO8601 format.
=================== 14 August, 2018 ===================
Summary
Feature added to filter get account activities by transaction type by passing in the types
parameter.
Only “Credit Card”, “Charge”, “Payout”, “Deposit”, “Withdrawal” allowed. You can add additional types by separating with a comma.
Feature added to filter get account activities by transaction status by passing in the status
parameter.
Only “completed”, “refunded”, “expired”, “cancelled”, “pending”, “accepted”, “on_hold” allowed. You can add additional statuses by separating with a comma.
Refer to Get Account Activities API
=================== 7 August, 2018 ===================
Summary [Breaking change for Get Account Activities API]
New feature added for pagination. API response updated.
New parameters:
start_date
, end_date
, offset
New response: Refer to Get Account Activities API
=================== 6 August, 2018 ===================
Summary
Add response body in Verify User Account
=================== 3 August, 2018 ===================
Summary
Add Verify User Account in Xfers Core - User Account
=================== 2 August, 2018 ===================
Summary
Only returning the affected bank_account in add_bank_account and update_account_info API
=================== 26 July, 2018 ===================
Summary
Add callback_url field in update_account_info API.
=================== 23 July, 2018 ===================
Summary
Removal of Singapore-specific fields and addition of Indonesia-specific fields in response examples for Get Account Info and Update Account Info for Indonesia
=================== 6 July, 2018 ===================
Summary
Addition of Indonesia required field in update_account_info
=================== 13 June, 2018 ===================
Summary
Addition of integration guide documentation.
=================== 11 June, 2018 ===================
Summary
Improvements to Get Account Activities API privacy controls.
Features
Get Account Activities API now only returns a particular merchant’s transactions and not every merchant’s transactions for connected users.
If you are a merchant A and you have a connected user X, you will not be able to see user X’s transactions with other merchants.
=================== 5 June, 2018 ===================
Summary
Transactional charges now supported for selected merchants See more info.
Features
Create a transactional charge by setting the transactional_only
flag when creating a charge to true
.