FTN19.3: FutoIn Interface - Transaction Engine - Accounts Version: 1.0DV Date: 2017-12-24 Copyright: 2017 FutoIn Project (http://futoin.org) Authors: Andrey Galkin
This is sub-specification of main FTN19: Transaction Engine.
Each account must have the following properties:
Currency
Balance
Reservation
Overdraft
The following types of accounts are assumed:
System
- internal source & sink which have no limit restrictionsRegular
- used for accumulation of funds, supports operation limitsTransit
- similar to Regular, but forbids direct operations by account holderExternal
- similar to Transit, but used for accounting of external systemsBonus
- a temporary account used for bonus amounts processingACCT_NEW
- on account being createdACCT_UPD
- on account information being updated, but not balanceACCT_BAL
- on account balance changeACCT_CONV
- on account currency being converted to another oneACCT_CLOSE
- on account being closedThere is strict Know Your Customer (KYC) and related limit requirements for financial systems in scope of AML/CTF efforts. It's the primary reason to introduce such entity.
As account holder information varies across the Globe, it should be abstract enough to hold arbitrary data provided by actual implementation.
However, if data type is already defined as part of spec - it must be used instead of optional extensions.
All data may be in national Unicode format. However, some fields may have restrictions.
full_name
other_names
= {} - other names, if applicablefirst
last
middle
father
latin_first
- first name in latin as in ICAO IDlatin_last
- last name in latin as in ICAO IDdob
- date of birthsex
= [M, F, O] - Male, Female, Othertitle
- arbitrary string like 'Mr.', 'Dr.', 'Sir', etc.citizenship
= [] - Country Listresident
= [] - Country Listhome_address
= {} - primary contact addresscountry
region
= null - state, province, etc. if applicablecity
street
building
room
other_addresses
= [ {} ] - list of other contact addressesmain_email
- primary contact emailother_emails
= [] - list of contact emailsmain_phone
- primary contact phoneother_phones
= [] - list of contact phonesids
= [ {}, ... ] - list of IDstype
- arbitrary stringICAO
- ICAO-compliant ID/passportNATID
- national IDDL
- Driver Licensenum
- arbitrary string identifying document IDcountry
- the country issued the documentissuer
iss_date
- date issuedexp_date
- valid through datedoc_ids
= [] - list of associated uploaded documentscomment
- user supplied commenttax_id
api
- define peer API configuration{iface}
- interface name without version as keyflavour=default
- custom implementationversion={latest}
- assume latest known version of interfaceendpoint
- endpoint URLcredentials=null
- credentials stringoptions={}
- any options to pass for registrationAH_NEW
- new account holderAH_UPD
- update of account holderAH_BLOCK
- on account holder being blockedAccount management API for internal use only.
Merge functionality should be rarely used to workaround multiple registrations per single person which may happen in some scenarios.
It's assumed there is a unique Account Alias per Account Holder - it should be used to create accounts and prevent duplicates.
External Account ID is optional, but can be set only at creation time.
Transit and Bonus account types must have related External accounts. Related account can be set only at creation time with exception below.
When bonus account is closed all out-of-band cancels and wins gets redirected to related account. Therefore, when bonus amount is released. The main Regular account becomes related.
{
"iface" : "futoin.xfer.accounts",
"version" : "{ver}",
"ftn3rev" : "1.7",
"imports" : [
"futoin.ping:1.0",
"futoin.xfer.types:{ver}"
],
"types" : {
"AccountType" : {
"type" : "enum",
"items": [
"System",
"Regular",
"Transit",
"External",
"Bonus"
]
},
"RelatedAccountID" : [
"AccountID",
"boolean"
],
"AccountHolderData" : {
"type" : "map"
},
"AccountHolderInternalData" : {
"type" : "map"
},
"AccountHolderInfo" : {
"type" : "map",
"fields" : {
"id" : "AccountHolderID",
"ext_id" : "AccountHolderExternalID",
"group" : "LimitGroup",
"enabled" : "boolean",
"kyc" : "boolean",
"data" : "AccountHolderData",
"internal" : "AccountHolderInternalData",
"created" : "XferTimestamp",
"updated" : "XferTimestamp"
}
},
"AccountInfo" : {
"type" : "map",
"fields" : {
"id" : "AccountID",
"holder" : "AccountHolderID",
"type" : "AccountType",
"currency" : "CurrencyCode",
"alias" : "AccountAlias",
"enabled" : "boolean",
"balance" : "Balance",
"reserved" : "Amount",
"overdraft" : "Amount",
"ext_id" : {
"type" : "AccountExternalID",
"optional" : true
},
"rel_id" : {
"type" : "RelatedAccountID",
"optional" : true
},
"created" : "XferTimestamp",
"updated" : "XferTimestamp"
}
},
"AccountInfoList" : {
"type" : "array",
"elemtype" : "AccountInfo"
}
},
"funcs" : {
"addAccount" : {
"params" : {
"holder" : "AccountID",
"type" : "AccountType",
"currency" : "CurrencyCode",
"alias" : "AccountAlias",
"enabled" : {
"type" : "boolean",
"default" : true
},
"ext_id" : {
"type" : "AccountExternalID",
"default" : null
},
"rel_id" : {
"type" : "RelatedAccountID",
"default" : null
}
},
"result" : "AccountExternalID",
"throws" : [
"UnknownHolderID",
"UnknownCurrency",
"Duplicate"
]
},
"updateAccount" : {
"params" : {
"id" : "AccountID",
"alias" : {
"type" : "AccountAlias",
"default" : null
},
"enabled" : {
"type" : "boolean",
"default" : null
}
},
"result" : "boolean",
"throws" : [
"UnknownAccountID",
"Duplicate"
]
},
"setOverdraft" : {
"params" : {
"id" : "AccountID",
"currency" : "CurrencyCode",
"overdraft" : "Amount"
},
"result" : "boolean",
"throws" : [
"UnknownAccountID",
"CurrencyMismatch"
]
},
"getAccount": {
"params" : {
"id" : "AccountID"
},
"result" : "AccountInfo",
"throws" : [
"UnknownAccountID"
]
},
"getAccountExt": {
"params" : {
"holder" : "AccountID",
"ext_id" : "AccountExternalID"
},
"result" : "AccountInfo",
"throws" : [
"UnknownAccountID"
]
},
"listAccounts": {
"params" : {
"holder" : "AccountHolderID"
},
"result" : "AccountInfoList",
"throws" : [
"UnknownHolderID"
]
},
"convertAccount" : {
"params" : {
"id" : "AccountID",
"currency" : "CurrencyCode"
},
"result" : "boolean",
"throws" : [
"UnknownHolderID",
"UnknownCurrency"
],
"desc" : "For rare cases when some currency needs to be disabled"
},
"addAccountHolder" : {
"params" : {
"ext_id" : "AccountHolderExternalID",
"group" : "LimitGroup",
"enabled" : "boolean",
"kyc" : "boolean",
"data" : "AccountHolderData",
"internal" : "AccountHolderInternalData"
},
"result" : "AccountHolderID",
"throws" : [
"UnknownLimitGroup",
"DuplicateExtID"
]
},
"updateAccountHolder" : {
"params" : {
"id" : "AccountHolderID",
"group" : {
"type" : "LimitGroup",
"default" : null
},
"enabled" : {
"type" : "boolean",
"default" : null
},
"kyc" : {
"type" : "boolean",
"default" : null
},
"data" : {
"type" : "AccountHolderData",
"default" : null
},
"internal" : {
"type" : "AccountHolderInternalData",
"default" : null
}
},
"result" : "boolean",
"throws" : [
"UnknownHolderID",
"UnknownLimitGroup"
]
},
"getAccountHolder" : {
"params" : {
"id" : "AccountHolderID"
},
"result" : "AccountHolderInfo",
"throws" : [
"UnknownHolderID"
]
},
"getAccountHolderExt" : {
"params" : {
"ext_id" : "AccountHolderExternalID"
},
"result" : "AccountHolderInfo",
"throws" : [
"UnknownHolderID"
]
},
"mergeAccountHolders" : {
"params" : {
"id" : "AccountHolderID",
"other_id" : "AccountHolderID"
},
"result" : "boolean",
"throws" : [
"UnknownHolderID"
]
},
"getLimitStats" : {
"params" : {
"holder" : "AccountHolderID",
"domain" : "LimitDomain"
},
"result" : {
"currency" : "CurrencyCode",
"stats" : "LimitValues"
},
"throws" : [
"UnknownHolderID"
]
}
},
"requires" : [ "SecureChannel" ]
}
=END OF SPEC=