OpenAPI Specification
openapi: 3.0.0
info:
description: Welcome to Xfers' API documentation. You can find information on our API endpoint specific to your country.
version: '3'
title: Xfers Bank Account Registration API
contact:
name: Contact us through our help desk
url: https://bit.ly/XfersSupport
servers:
- description: Indonesia Production
url: https://id.xfers.com/api
- description: Indonesia Sandbox for testing
url: https://sandbox-id.xfers.com/api
tags:
- name: Registration
description: Register and verify new users.
paths:
/v3/authorize/signup_login:
post:
tags:
- Registration
x-code-samples:
- lang: Shell
source: "curl --location --request POST \"$BASE_URL/v3/authorize/signup_login\" \\\r\n --header \"X-XFERS-APP-API-KEY: $MERCHANT_APP_KEY\" \\\r\n --header \"Content-Type: application/json\" \\\r\n --data \"{\\\"phone_no\\\" : \\\"+6287785725657\\\", \\\"signature\\\" : \\\"5488737c67d790565a15a2dbc3c98bf778aac2c0\\\"}\""
operationId: signUpLogin
summary: Sign Up Account/Trigger OTP
description: 'This API is used to start user registration by inputting phone number.
After this API is called, an OTP SMS will be sent to that number.
You can re-trigger this API to re-send OTP to the same phone number after 1 minute.
This OTP will expire in 10 minutes.
The SMS format will be:
```
[XFERS] Your OTP is 123456. This is to set up payments for `merchant_name` . If this is not done by you, please report to http://bit.ly/XfersSupport
```
This API uses a pair of public key and secret key.
The header of this API uses public key called `X-XFERS-APP-API-KEY`.
You will need `X-XFERS-APP-SECRET-KEY` to generate signature in the request body.
'
security:
- X-XFERS-APP-API-KEY: []
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
properties:
phone_no:
description: User mobile no. It should follow International format.
type: string
example: '+6287785725657'
signature:
description: SHA1-hex of (phone_no + X-XFERS-APP_SECRET_KEY). More information on generating SHA1 here http://www.sha1-online.com/
type: string
example: 5488737c67d790565a15a2dbc3c98bf778aac2c0
required:
- phone_no
- signature
responses:
'200':
description: Success
content:
application/json:
example:
msg: success
4XX:
$ref: '#/components/responses/v3Error:4XX'
/v3/authorize/private_wallet:
post:
operationId: privateWallet
x-code-samples:
- lang: Shell
source: "curl --location --request POST \"{base_url}/api/v3/authorize/private_wallet\" \\\r\n --header \"X-XFERS-APP-API-KEY: TjETqu8GsJPGgbxEN85jw8cBcEFs8p6HqsQ3dEcDgDw\" \\\r\n --header \"Content-Type: application/json\" \\\r\n --data \"{\\\"phone_no\\\" : \\\"+6287785725657\\\", \\\"signature\\\" : \\\"0218525f26d5d248d2ca835036dac2f3ecef3c85\\\"}\""
tags:
- Registration
summary: Register Account
description: "This API is used to start private ledger registration by inputting phone number.\n\n This API uses a pair of public key and secret key.\n\nThe header of this API uses public key called `X-XFERS-APP-API-KEY`. You will need `X-XFERS-APP-SECRET-KEY` to generate signature in the request body.\n\nPlease make use of Pre-request Script to test this API in postman"
security:
- X-XFERS-APP-API-KEY: []
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
properties:
phone_no:
description: User mobile no. It should follow International format.
type: string
example: '+6287785725657'
signature:
description: SHA1-hex of (phone_no + X-XFERS-APP_SECRET_KEY). More information on generating SHA1 here http://www.sha1-online.com/
type: string
example: 5488737c67d790565a15a2dbc3c98bf778aac2c0
required:
- phone_no
- signature
responses:
'200':
description: Success
content:
application/json:
example:
msg: success
4XX:
description: List of possible errors
content:
application/json:
schema:
$ref: '#/components/schemas/error_response'
examples:
Missing Api Key:
summary: Missing API KEY in header
value:
error: Missing API KEY in header
Invalid Api Key:
summary: Invalid API KEY
value:
error: Invalid API KEY
Invalid signature:
summary: Invalid api_key/signature
value:
error: Invalid api_key/signature
Invalid phone no provided:
summary: Invalid phone no provided
value:
error: Invalid phone no provided.
error_code: XFE12
error_handling: Make sure you entered the correct parameters.
/v3/authorize/get_token:
get:
tags:
- Registration
x-code-samples:
- lang: Shell
source: "curl --location --request GET \"$BASE_URL/v3/authorize/get_token?otp=541231&phone_no=%2B65XXXXXXXX&signature=bdc26373b3a78dd11dc840a1b7973f197cf34c91\" \\\r\n --header \"X-XFERS-APP-API-KEY: $MERCHANT_APP_KEY\" \\\r\n --header \"Content-Type: application/x-www-form-urlencoded\""
operationId: getToken
summary: Get User API Token / Submit OTP
description: 'After user receives the OTP SMS, merchant''s app should capture the OTP and pass it to Xfers via this API.
This API will finish the registration and returns user_api_token. user_api_token is used to control the user''s account.
You should save the user_api_token for future usage. (to be put in the `X-XFERS-USER-API-KEY` in headers of other APIs)
It will also return a is_fully_verified if they already have an Xfers account and have completed our KYC process.
This API uses a pair of public key and secret key.
The header of this API uses public key called `X-XFERS-APP-API-KEY`. You will need `X-XFERS-APP-SECRET-KEY` to generate signature in the request body.'
security:
- X-XFERS-APP-API-KEY: []
parameters:
- name: otp
in: query
description: User mobile no. It should follow International format.
required: true
explode: true
schema:
type: string
example: '541231'
- name: phone_no
in: query
description: User mobile no. It should follow International format.
required: true
explode: true
schema:
type: string
example: '+6287785725657'
- name: signature
in: query
description: SHA1-hex of (phone_no + OTP + APP_SECRET_KEY). More information on generating SHA1 here http://www.sha1-online.com/
required: true
explode: true
schema:
type: string
example: 71b72cb775fa0e52d815279c74964f5be18a88b8
- name: return_url
in: query
x-custom-params:
- Singapore
description: Url that new user will be redirected after they completed Xfers account registration at `sign_up_url` provided.
required: false
explode: true
schema:
type: string
example: 71b72cb775fa0e52d815279c74964f5be18a88b8
default: <Endpoint>/v3/account_registration/completed
responses:
'200':
description: Success
content:
application/json:
example:
msg: success
id: user_csn7v5lyn4a6
user_api_token: A-Bm4vmjmGyhRaMEoxqBGeoXCEQwJYksrTXc6-ypsyk
currency: idr
is_fully_verified: true
4XX:
$ref: '#/components/responses/v3Error:4XX'
/v3/user:
put:
operationId: submitKYC
tags:
- Registration
x-code-samples:
- lang: Shell
source: "curl --location --request PUT \"{base_url}/user\" \\\r\n --header \"X-XFERS-USER-API-KEY: Qh9fors4WmjTfeisB9qEAdsAzEXgeHVQF3-NsE5yi-c\" \\\r\n --header \"Content-Type: application/json\" \\\r\n --data \"{\\\"mother_maiden_name\\\": \\\"Luna\\\", \\\"id_front_url\\\": \\\"http://res.freestockphotos.biz/pictures/8/8453-a-blue-sky-with-white-clouds-pv.jpg\\\", \\\"selfie_2id_url\\\": \\\"http://res.freestockphotos.biz/pictures/8/8453-a-blue-sky-with-white-clouds-pv.jpg\\\",\r\n\t\\\"callback_url\\\":\\\"https:/www.example.com/update\\\"}\r\n\r\n\""
summary: Submit KYC Data
description: "To provide KYC data in order to change user from unverified status into fully verified status. \n\nThe image/document provided us must be hosted in a URL then pass the URL to Xfers via this API. \nMake sure data type for your image is jpeg / png. \nMaximum size of the image/ document is 10 MB. \n\nAfter this data is sent, we will do some verifications on our side and may take some time before user gets fully verified. In Indonesia, fully verified user will be backed by a savings account.\r\nThus, there are required parameters which are mother_maiden_name, id_front_url, selfie_2id_url.\r\nAdditional data will speed up the KYC process."
security:
- user-api-token: []
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
x-custom-params-requirements:
Indonesia:
- id_front_url
- selfie_2id_url
- full_name
- identity_no
- gender
- mother_maiden_name
- date_of_birth
- place_of_birth
- marital_status
- occupation
- city
- state
- postal_code
- address_line_1
properties:
id_front_url:
type: string
description: URL storing the front image of user identity card
selfie_2id_url:
type: string
description: URL storing the selfie of user holding their id card
fullname:
type: string
description: Account holder full name
mother_maiden_name:
type: string
description: Name of Mother
first_name:
type: string
description: Account holder firstname
last_name:
type: string
description: Account holder lastname
email:
type: string
description: User email
date_of_birth:
type: string
description: ' Date of birth for account holder in yyyy-mm-dd'
gender:
type: string
description: 'Gender. Possible values: male / female'
address_line_1:
type: string
description: Address line 1
address_line_2:
type: string
description: Address line 2
nationality:
type: string
description: Account holder nationality
postal_code:
type: string
description: Address postal code
identity_no:
type: string
description: Account holder national identity number or, KTP number of Indonesian.
country:
type: string
description: Account holder country of residence.
city:
type: string
description: Account holder city of residence.
annual_income:
type: integer
description: Annual income of user in the local currency (SGD/IDR)
id_back_url:
type: string
description: URL storing the back of the user id card
proof_of_address_url:
type: string
description: URL storing the proof of address
meta_data:
type: string
description: Addtional data like Jumio info dump.
place_of_birth:
type: string
description: Account holder’s birth place.
blood_type:
type: string
description: ' Account holder’s blood type, without rhesus. Possible values: ‘A’, ‘B’, ''AB’, or ''O’'
rt:
type: string
x-custom-params:
- Indonesia
description: Only Indonesia. Account holder’s RT according to his/her KTP. Leading zero is optional.
rw:
type: string
x-custom-params:
- Indonesia
description: Account holder’s RW according to his/her KTP. Leading zero is optional.
administrative_village:
type: string
x-custom-params:
- Indonesia
description: Account holder’s administrative_village address. In KTP, it is called Kelurahan or Desa.
state:
type: string
x-custom-params:
- Indonesia
description: Account holder’s state of residence. In KTP, it is called Provinsi.
district:
type: string
x-custom-params:
- Indonesia
description: Only Indonesia. Account holder’s district address. In KTP, it is called Kecamatan.
religion:
type: string
x-custom-params:
- Indonesia
description: 'Only Indonesia. Account holder’s religion according to his/her KTP. Possible Values: ''Islam’, ''Katholik’, ''Kristen Protestan’, ''Hindu’, ''Budha’, ''Kong Hu Cu’, or ''Aliran Kepercayaan’'
marital_status:
type: string
description: 'Only Indonesia. Account holder’s marital status according to his/her KTP. Possible Values: ''Belum Kawin’, ''Kawin’, ''Janda’, or ''Duda’'
occupation:
type: string
x-custom-params:
- Indonesia
description: Only Indonesia. Account holder’s occupation according to his/her KTP.
required:
- id_front_url
- selfie_2id_url
- full_name
- identity_no
- gender
- mother_maiden_name
- date_of_birth
- place_of_birth
- marital_status
- occupation
- city
- state
- postal_code
- address_line_1
responses:
'200':
description: Success
content:
application/json:
example:
available_balance: '0.32'
ledger_balance: '0.32'
bank_transfer_rates: '0.0'
bank_transfer_fees: '0.45'
first_name: Winston
last_name: Andersen
date_of_birth: '1986-02-27'
country_of_birth: ''
gender: male
email: winston@xfers.com
country: id
nationality: Indonesian
address_line_1: Blk 712 loyang Avenue 5
address_line_2: '#01-41'
postal_code: '340712'
nric_type: ''
identity_no: '317201180894005'
nric_issue_date: ''
phone_no: '+6287785725657'
bank_accounts:
- id: 69
account_no: '1150006390175'
account_holder_name: PROD ONLY
detected_name: PROD ONLY
verification_status: pending
verified: true
bank_abbrev: BCA
usage: all
- id: 175
account_no: '1680366060'
account_holder_name: PROD ONLY
detected_name: PROD ONLY
verification_status: pending
verified: true
bank_abbrev: BCA
usage: all
- id: 177
account_no: '1150006390175'
account_holder_name: PROD ONLY
detected_name: PROD ONLY
verification_status: pending
verified: true
bank_abbrev: MANDIRI
usage: all
- id: 207
account_no: '1234567890'
account_holder_name: Some Name
detected_name: PROD ONLY
verification_status: pending
verified: true
bank_abbrev: BCA
usage: all
annual_income: ''
id_front: 15332940588453-a-blue-sky-with-white-clouds-pv.jpg
id_front_url: https://sandbox-xfers-id.s3-ap-southeast-1.amazonaws.com/users/nric_fronts/000/000/374/original/15332940588453-a-blue-sky-with-white-clouds-pv.jpg?AWSAccessKeyId=REDACTED-EXAMPLE&Expires=1533297752&Signature=REDACTED-EXAMPLE
selfie_2id: 15332940588453-a-blue-sky-with-white-clouds-pv.jpg
selfie_2id_url: https://sandbox-xfers-id.s3-ap-southeast-1.amazonaws.com/users/nric_selfies/000/000/374/original/15332940588453-a-blue-sky-with-white-clouds-pv.jpg?AWSAccessKeyId=REDACTED-EXAMPLE&Expires=1533297752&Signature=REDACTED-EXAMPLE
account_locked: false
kyc_verified: true
meta_data: ''
place_of_birth: null
blood_type: null
rt_rw: null
administrative_village: null
district: null
religion: null
marital_status: null
occupation: null
mother_maiden_name: Luna
4XX:
$ref: '#/components/responses/v3Error:4XX'
components:
examples:
XFE403:
summary: XFE403 - ...
value:
error: string
error_code: XFE403
error_handling: '...'
XFE111:
summary: XFE1 - Duplicate credentials
value:
error: string
error_code: XFE111
error_handling: Particulars already exist. Please make sure you entered the correct parameters.
XFE3:
summary: XFE3 - Internal Error
value:
error: string
error_code: XFE3
error_handling: Unexpected error. Try again later or contact customer support at https://bit.ly/XfersSupport.
XFE312:
summary: XFE312 - Conditions not met to close account
value:
error: string
error_code: XFE312
error_handling: Invalid request to close account. Follow instruction in the response.
XFE1:
summary: XFE1 - Server busy
value:
error: string
error_code: XFE1
error_handling: Follow instructions in the response.
XFE311:
summary: XFE311 - Cannot be different wallet type
value:
error: string
error_code: XFE311
error_handling: Follow instruction in response or contact customer support at https://bit.ly/XfersSupport.
XFE301:
summary: XFE301 - Account locked
value:
error: string
error_code: XFE301
error_handling: Request not available. Please contact customer support at https://bit.ly/XfersSupport.
XFE108:
summary: XFE108 - More user information required
value:
error: string
error_code: XFE108
error_handling: Follow instructions in the response.
XFE107:
summary: XFE107 - Only enter one auth_code
value:
error: string
error_code: XFE107
error_handling: Do not enter both OTP or Google Auth OTP. Only need to enter one.
XFE402:
summary: XFE402 - Cannot use placeholder account
value:
error: string
error_code: XFE402
error_handling: Follow instructions in response.
XFE502:
summary: XFE502 - Unexpected BANK API error
value:
error: string
error_code: XFE502
error_handling: Try again later or contact customer support at https://bit.ly/XfersSupport.
XFE106:
summary: XFE106 - No auth_code provided
value:
error: string
error_code: XFE106
error_handling: Enter either phone OTP or Google Auth OTP
XFE407:
summary: XFE407 - Conditions to charge card not met
value:
error: string
error_code: XFE407
error_handling: Invalid request for this transaction. Make sure you entered the correct txn_id.
XFE409:
summary: XFE409 - Order id exist
value:
error: string
error_code: XFE409
error_handling: Please enter another order_id.
XFE105:
summary: XFE105 - Captcha error
value:
error: string
error_code: XFE1
error_handling: Follow instructions in the response.
XFE404:
summary: XFE404 - Forex not supported
value:
error: string
error_code: XFE404
error_handling: Make sure you call the correct API or contact customer support at https://bit.ly/XfersSupport.
XFE102:
summary: XFE102 - Entered value is less than minimum
value:
error: string
error_code: XFE102
error_handling: Make sure you entered the correct number.
XFE109:
summary: XFE109 - Invalid credentials
value:
error: string
error_code: XFE109
error_handling: Make sure you entered the correct credentials.
XFE104:
summary: XFE104 - Media provided too large
value:
error: string
error_code: XFE104
error_handling: Media too big. Follow the guidelines in the response.
XFE15:
summary: XFE15 - Required parameter empty
value:
error: string
error_code: XFE15
error_handling: Make sure you entered the correct required parameter.
XFE14:
summary: XFE14 - API only allowed for fully verified user
value:
error: string
error_code: XFE14
error_handling: Please submit KYC data to get your account fully verified.
XFE2:
summary: XFE2 - Access denied
value:
error: string
error_code: XFE2
error_handling: Make sure you call the correct API or contact customer support at https://bit.ly/XfersSupport.
XFE506:
summary: XFE506 - Bank account already taken
value:
error: string
error_code: XFE506
error_handling: Please use another bank account.
XFE309:
summary: XFE309 - Cannot use same account
value:
error: string
error_code: XFE309
error_handling: Follow instructions in the response.
XFE13:
summary: XFE13 - Record not found
value:
error: string
error_code: XFE13
error_handling: Please check that you provided the correct API Key and the correct parameters.
XFE8:
summary: XFE8 - Cannot retrieve media
value:
error: string
error_code: XFE8
error_handling: Cannot retrieve media. Please enter a new URL or try again later.
XFE7:
summary: XFE7 - Database error
value:
error: string
error_code: XFE7
error_handling: Follow instructions in the response.
XFE408:
summary: XFE408 - Invalid charge request
value:
error: string
error_code: XFE408
error_handling: Invalid request. Please follow instructions in response or contact customer support at https://bit.ly/XfersSupport.
XFE302:
summary: XFE302 - Account deleted
value:
error: string
error_code: XFE302
error_handling: Request not available. Please contact customer support at https://bit.ly/XfersSupport.
XFE201:
summary: XFE201 - Not yet a merchant
value:
error: string
error_code: XFE201
error_handling: Please verify your merchant or business account.
XFE103:
summary: XFE103 - ...
value:
error: string
error_code: XFE103
error_handling: Follow instructions in the response.
XFE406:
summary: XFE406 - Cannot refund prepaid transaction
value:
error: string
error_code: XFE406
error_handling: Please choose another transaction to refund.
XFE401:
summary: XFE401 - Cannot refund charge
value:
error: string
error_code: XFE401
error_handling: Invalid request. Please call another API or Contact customer support at https://bit.ly/XfersSupport.
XFE503:
summary: XFE503 - Failed name check
value:
error: string
error_code: XFE503
error_handling: Bank account name and name provided have to be similar.
XFE410:
summary: XFE410 - Invalid application fee
value:
error: string
error_code: XFE410
error_handling: Invalid request. Please make changes to the parameters as stated in the response.
XFE304:
summary: XFE304- Account closed
value:
error: string
error_code: XFE304
error_handling: Request not available. Please contact customer support at https://bit.ly/XfersSupport.
XFE110:
summary: XFE110 - Cannot sign up twice
value:
error: string
error_code: XFE110
error_handling: Please sign in instead
XFE504:
summary: XFE504 - Maximum number of bank account
value:
error: string
error_code: XFE504
error_handling: Delete existing bank accounts.
XFE16:
summary: XFE16 - Invalid request
value:
error: string
error_code: XFE16
error_handling: API request not supported. Make sure you entered the correct API key or contact customer support at https://bit.ly/XfersSupport.
XFE310:
summary: XFE310 - Cannot use same account
value:
error: string
error_code: XFE310
error_handling: Follow instructions in the response.
XFE9:
summary: XFE9 - ....
value:
error: string
error_code: XFE9
error_handling: '...'
XFE601:
summary: XFE601 - Conditions to withdraw not met. Can be solved by changing amount
value:
error: string
error_code: XFE601
error_handling: Your withdrawal does not meet the conditions required. Please follow the instructions in the response.
XFE10:
summary: XFE10 - Invalid environment
value:
error: string
error_code: XFE10
error_handling: Request not supported for this environment.
XFE4:
summary: XFE4 - Authentication field empty
value:
error: string
error_code: XFE4
error_handling: Follow instructions in the response.
XFE307:
summary: XFE307 - ...
value:
error: string
error_code: XFE307
error_handling: '...'
XFE303:
summary: XFE303 - Account terminated
value:
error: string
error_code: XFE303
error_handling: Request not available. Please contact customer support at https://bit.ly/XfersSupport.
XFE101:
summary: XFE101 - Not local number
value:
error: string
error_code: XFE101
error_handling: Follow instructions in the response.
XFE405:
summary: XFE405 - Charge cannot be refunded
value:
error: string
error_code: XFE405
error_handling: Only completed contract can be refunded.
XFE505:
summary: XFE505 - Bank abbrev provided invalid
value:
error: string
error_code: XFE505
error_handling: Use GET {{base-api-url}}api/v3/banks to get the correct bank abbrev.
XFE6:
summary: XFE6 - Invalid signature
value:
error: string
error_code: XFE6
error_handling: Follow instructions in the response.
XFE5:
summary: XFE5 - Api key is invalid
value:
error: string
error_code: XFE5
error_handling: Make sure you entered the correct API key or contact customer support at https://bit.ly/XfersSupport
XFE603:
summary: XFE603 - Not allowed to carry out request
value:
error: string
error_code: XFE603
error_handling: Invalid request. Please call another API or contact customer support at https://bit.ly/XfersSupport.
XFE12:
summary: XFE12 - Invalid parameter
value:
error: string
error_code: XFE12
error_handling: Make sure you entered the correct parameters.
XFE306:
summary: XFE306 - ...
value:
error: string
error_code: XFE306
error_handling: '...'
XFE602:
summary: XFE602 - Server busy
value:
error: string
error_code: XFE602
error_handling: Your withdrawal exceeds the limit for the time period. Please change the amount or verify your account.
XFE11:
summary: XFE11 - Timeout
value:
error: string
error_code: XFE11
error_handling: Please try again later.
XFE308:
summary: XFE308 - ...
value:
error: string
error_code: XFE308
error_handling: '...'
XFE501:
summary: XFE501 - Expected Bank API error
value:
error: string
error_code: XFE501
error_handling: Try again later or contact customer support at https://bit.ly/XfersSupport.
XFE112:
summary: XFE112 - Repeat request
value:
error: string
error_code: XFE112
error_handling: API request has already been made. Please follow the instructions in the response or call aother API.
XFE305:
summary: XFE305 - ....
value:
error: string
error_code: XFE305
error_handling: '...'
schemas:
error_response:
type: object
properties:
error:
description: Error Message
type: string
error_code:
description: Xfers' error code XFEXXX
type: string
error_handling:
description: Instruction on how to handle error. Refer to Error Codes tag for more information.
type: string
responses:
v3Error:4XX:
description: List of possible errors
content:
application/json:
schema:
$ref: '#/components/schemas/error_response'
examples:
XFE1:
$ref: '#/components/examples/XFE1'
XFE2:
$ref: '#/components/examples/XFE2'
XFE3:
$ref: '#/components/examples/XFE3'
XFE4:
$ref: '#/components/examples/XFE4'
XFE5:
$ref: '#/components/examples/XFE5'
XFE6:
$ref: '#/components/examples/XFE6'
XFE7:
$ref: '#/components/examples/XFE7'
XFE8:
$ref: '#/components/examples/XFE8'
XFE9:
$ref: '#/components/examples/XFE9'
XFE10:
$ref: '#/components/examples/XFE10'
XFE11:
$ref: '#/components/examples/XFE11'
XFE12:
$ref: '#/components/examples/XFE12'
XFE13:
$ref: '#/components/examples/XFE13'
XFE14:
$ref: '#/components/examples/XFE14'
XFE15:
$ref: '#/components/e
# --- truncated at 32 KB (35 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/xfers/refs/heads/main/openapi/xfers-registration-api-openapi.yml