FTN20: FutoIn Interface - Payment Service Provider Version: 0.1DV Date: 2017-12-16 Copyright: 2017 FutoIn Project (http://futoin.org) Authors: Andrey Galkin
There is a demand for common Payment Service Provider (PSP) interface to unify uncountable numbers of protocols in the market.
The priorities are payment industry grade transaction consistency control and reliable automatic error recovery.
The specifications covers interface between merchant and PSP. Therefore, it also coveres PSP-to-PSP cases when one of PSP acts on behalf of merchant.
This PSP interface is heavily based on assumptions and types of FTN19: FutoIn Interface - Transaction Engine.
There are several areas related to PSP, but those can separated into inbound and outbound transactions.
Unlike many protocols in the market, there are no callbacks from PSP allowed as merchant's system code quality is quite low in many cases by fact. So, there is a large security problem due to incorrect request handling.
However, in many cases users are required to be redirected to PSP or owm bank page for secure authorization of payments. As it's unavoidable that user gets redirected to another page or application, it the information passed through user (app/browser) should be minimized to related transaction ID and other not essential data. It must be impossible for user to alter even encrypted/signed data the way it would affect transaction processing.
Very often old world order imposes different restrictions and sanctions for doing business and processing of financial transfers. Therefore, PSP protocol has to reflect them as well.
Protocols refers to regions with the following prefixes: * "I:" - ISO 3166-1 alpha-3 namespace. * "K:" - for countries of Confederation of Reasonable Legal Freedom * "L:" - for closed loop custom operator-defined namespaces
The namespace can be sub-namespaces with ":" separator.
There are two approaches for restrictions: * "only_in" - functionality accessible only in specific regions * "except_for" - functionality not accessible in specific regions
Unless otherwise noted, each transaction call must be repeated until it succeeds or expected errors occurs.
Common types to use in PSP interfaces.
{
"iface" : "futoin.psp.types",
"version" : "{ver}",
"ftn3rev" : "1.8",
"imports" : [
"futoin.currency.types:1.0",
"futoin.xfer.types:1.0"
],
"types" : {
"AVSCode" : {
"type" : "string",
"regex" : "^[A-z0-9]{1}$"
},
"ComisionRate" : {
"type" : "string",
"regex" : "^0(\\.[0-9]{1,12})?$"
},
"CVVCode" : {
"type" : "string",
"regex" : "^[A-z0-9]{1}$"
},
"InvoiceID" : "XferExtID",
"MethodAlias" : {
"type" : "string",
"regex" : "^[a-b][a-b0-9_]{1,30}[a-b0-9]$"
},
"MethodInfo" : {
"type" : "map",
"fields" : {
"alias" : "MethodAlias",
"min" : "Amount",
"max" : "Amount",
"fee" : {
"type" : "Amount",
"optional" : true
},
"commision" : {
"type" : "ComisionRate",
"optional" : true
},
"only_in" : {
"type" : "RegionList",
"optional" : true
},
"except_for" : {
"type" : "RegionList",
"optional" : true
}
}
},
"MethodInfoList" : {
"type" : "array",
"elemtype" : "MethodInfo",
"maxlen" : 100
},
"RedirectURL" : {
"type" : "string",
"regex" : "^(https://[a-z0-9-]+(\\.[a-z0-9-]+)+/[A-Za-z0-9\\-._~%:/?#[\\]@!$&'()*+,;=])?$"
},
"Region" : {
"type" : "string",
"regex" : "^[IKL]:[A-Z]{1,16}(:[A-Z0-9]{1,16})?$",
"desc" : "T:Code, see the spec"
},
"RegionList" : {
"type" : "array",
"elemtype" : "Region",
"minlen" : 1,
"maxlen" : 1000
},
"SaleResult" : {
"type" : "map",
"fields" : {
"reason" : {
"type" : "string",
"optional" : true
},
"auth_code" : {
"type" : "string",
"optional" : true
},
"avs_code" : {
"type" : "AVSCode",
"optional" : true
},
"cvv_code" : {
"type" : "CVVCode",
"optional" : true
},
"passed_3ds" : {
"type" : "boolean",
"optional" : true
},
"other" : {
"type" : "any",
"optional" : true
}
}
},
"PaymentToken" : "UUIDB64"
}
}
This interface is focused on goods and services sale with optional partial or full refund of transactions.
Merchant's system does "status" call to find out if payment's status.
{ "iface" : "futoin.psp.sale", "version" : "{ver}", "ftn3rev" : "1.8", "imports" : [ "futoin.psp.types:{ver}" ], "funcs" : { "methods" : { "params" : { "currency" : "CurrencyCode" }, "result" : "MethodInfoList", "throws" : [ "UnknownCurrency" ] }, "sale" : { "params" : { "method" : "MethodAlias", "ext_id" : "XferExtID", "currency" : "CurrencyCode", "amount" : "Amount", "invoice" : { "type" : "InvoiceID", "default" : null } }, "result" : { "id" : "XferID", "url" : "RedirectURL" }, "throws" : [ "UnknownCurrency", "UnknownMethod", "UnknownInvoice", "LimitRejected" ] }, "status" : { "params" : { "id" : "XferID" }, "result" : { "method" : "MethodAlias", "ext_id" : "XferExtID", "currency" : "CurrencyCode", "amount" : "Amount", "info" : "SaleResult" }, "throws" : [ "UnknownXferID", "OriginalTooOld", "OriginalMismatch" ] } } }
This interface is not related to sales. Funds are transfered from merchant to client as salary, compenstation, win or any other sort of income.
{
"iface" : "futoin.psp.payout",
"version" : "{ver}",
"ftn3rev" : "1.8",
"imports" : [
"futoin.psp.types:{ver}"
],
"funcs" : {
}
}
The interface is optional and used only for error checking purposes.
{
"iface" : "futoin.psp.reconciliation",
"version" : "{ver}",
"ftn3rev" : "1.8",
"imports" : [
"futoin.psp.types:{ver}"
],
"funcs" : {
}
}
Interface to set electronic invoices. It may operate without related sales interface.
{
"iface" : "futoin.psp.invoice",
"version" : "{ver}",
"ftn3rev" : "1.8",
"imports" : [
"futoin.psp.types:{ver}"
],
"funcs" : {
}
}
Setup recurring payment plan in scope of initial sale and re-use token for later sales. Important part are terms & conditions to be provided and saved in PSP for dispute resolution as recurring payments must be processed without client's confirmation.
{
"iface" : "futoin.psp.billing",
"version" : "{ver}",
"ftn3rev" : "1.8",
"imports" : [
"futoin.psp.types:{ver}"
],
"types" : {
"TermsAndConditions" : {
"type" : "array",
"elemtype" : "string"
}
},
"funcs" : {
"methods" : {
"params" : {
"currency" : "CurrencyCode"
},
"result" : "MethodInfoList",
"throws" : [
"UnknownCurrency"
]
},
"sale" : {
"params" : {
"method" : "MethodAlias",
"ext_id" : "XferExtID",
"currency" : "CurrencyCode",
"amount" : "Amount",
"tc" : "TermsAndConditions",
"invoice" : {
"type" : "InvoiceID",
"default" : null
}
},
"result" : {
"id" : "XferID",
"url" : "RedirectURL"
},
"throws" : [
"UnknownCurrency",
"UnknownMethod",
"UnknownInvoice",
"LimitRejected",
"UnacceptableTC"
]
},
"status" : {
"params" : {
"id" : "XferID"
},
"result" : {
"method" : "MethodAlias",
"ext_id" : "XferExtID",
"currency" : "CurrencyCode",
"amount" : "Amount",
"info" : "SaleResult",
"token" : "PaymentToken"
},
"throws" : [
"UnknownXferID",
"OriginalTooOld",
"OriginalMismatch"
]
},
"tokenSale" : {
"params" : {
"token" : "PaymentToken",
"currency" : "CurrencyCode",
"amount" : "Amount",
"invoice" : {
"type" : "InvoiceID",
"default" : null
}
},
"result" : {
"id" : "XferID",
"info" : "SaleResult"
},
"throws" : [
"LimitRejected",
"UnknownToken"
]
}
}
}
TBD.
=END OF SPEC=