NAV
shell php python ruby java

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:

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

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.

XFERS-API-KEYS

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

  1. Decide on number of entries per page (e.g. 100 for this example). Set the limit as this
  2. First page: Offset 0. The latest 100 entries, 1-100, will be returned.
  3. Second page: Offset 100. The next 100 entries, 101-200, will be returned.
  4. 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.

  1. It allow Xfers to generate unique transfer amount to better identity the owner of incoming transfer when non virtual account system is being used.
  2. 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.

  1. 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).
  2. She makes a HTTP POST request to create an intent. The response tells her to make a bank transfer of 4999 to Xfers.
  3. 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.
  4. 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

  1. 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.
  2. 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.
  3. 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
email 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:

  1. After creating a Charge, a checkout_url is returned. If user_api_token and card_only params are used, the checkout_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.
  2. 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.

  1. 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
  2. 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

  1. 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

  1. Create charge by passing in user_phone_no, setting google_auth to be true.

  2. 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.