➖
Pay
The Pay product lets you request transfers from banks complying with the revised Payment Service Directive (PSD2) only. It does not rely on bank account aggregation nor the related user-centric services of our API. You may request payments from an emitter bank to a beneficiary without creating a user or connection in our API.
Pay features can be activated by your commercial contact only.
The Pay product has 2 configuration keys that can be modified to adapt its behavior to your needs :
Key | Default value | Description |
---|---|---|
payment.manual_expire_time_days | 7 | The number of days after which the payment will have the status expired if it does not have a definitive status (ie done or rejected). |
payment.max_amount | 0 | The maximum amount allowed in the payment initiation (enabled if amount is strictly greater than 0).
While initiating a payment, an HTTP error 400 will be returned if the requested amount is greater than this maximum amount value. |
Only a limited set of banks currently support the Pay product. You can obtain the compatible connectors by querying the whole list and then filtering the results. Also, payment request execution requires that the values of some connector
fields
be provided. You can also obtain them from the same API call:GET /connectors?expand=fields
{
"connectors": [
{
"id": 40,
"name": "Connecteur de test",
"payment_settings": {
"available_validate_mechanisms": [
"webauth"
],
"beneficiary_types": [
"iban"
],
"execution_date_types": [
"first_open_day",
"instant",
"deferred"
],
"execution_frequencies": [
"two-monthly",
"semiannually",
"weekly",
"yearly",
"four-monthly",
"daily",
"quarterly",
"biannual",
"bimonthly",
"two-weekly",
"monthly"
],
"maximum_number_of_instructions": 10,
"providing_payer_account": "optional"
}
"fields": [
{
"name": "website",
"label": "Région",
"required": true,
"type": "list",
"connector_sources": [ "openapi", … ],
"auth_mechanisms": [ "webauth", … ],
"values": [ { "label": "Région 1", "value": "r1" }, … ]
}
]
…
},
…
]
}
Filter the connectors list to keep only compatible banks:
- The connector must have a source named
openapi
; - The source must have the
transfer
capability, and thetransfer_validate_mechanism
must be set towebauth
.
For a given compatible connector, you can identifiy the required
fields
to display:- The
openapi
value must be present in theconnector_sources
; - The
webauth
value must be present in theauth_mechanisms
; - The field must be marked as
required
; - If the
type
islist
, the value must be selected from thevalues
list.
Connector selection and fields presentation are optional. You can validate a payment request without providing the
id_connector
and required values; in that case we will present the choice to the user before redirecting to the bank.
The
payment_settings
field describes features of the connector relative to payment initiation. See Payment Settings for more information.A connector may require the payer account information in order to initiate a payment. These connectors are identified by the
providing_payer_account
key in the payment_settings
object being set to mandatory
, see PaymentSettings. In this case, the payment account information (identification, scheme, and name) must be passed in the payer
object, see Request. If you are using the payment webview, this step is handled automatically for you.The Pay product requires the use of special access tokens with dedicated scopes:
POST /auth/token
{
"grant_type": "client_credentials",
"client_id": "{clientId}",
"client_secret": "{clientSecret}",
"scope": "payments:admin",
}
{
"token": "{accessToken}",
"scope": "payments:admin"
}
POST /payments
{
"id_connector": 59,
"website": "par",
"client_redirect_uri": "https://mycallback.com",
"client_state": "{optionalClientState}",
"instructions": [
{
"reference_id": "{myReference}",
"label": "Test",
"amount": 50.90,
"currency": "EUR",
"execution_date_type": "first_open_day",
"beneficiary": {
"scheme_name": "iban",
"identification": "FR76XXXXXXXXXXXXXXX",
"label": "ACME Corp.",
"merchant_scheme_name": "siren",
"merchant_identification": "012345678"
}
}
],
"validated": true,
}
{
"id": 110,
"state": "created",
"error_code": null,
"error_description": null,
"register_date": "2020-03-25 11:41:26",
"validate_uri": "http://…",
…
}
When creating a payment request, you must provide the required information about the amount, currency, beneficiary and execution date. You can also provide the
id_connector
of the emitter bank and the values of the required fields (see above).To actually process the payment request, send the
validated
flag and provide the client_redirect_uri
and optionally a client_state
. After the request has been validated, it is locked and the validation_uri
will be returned.You can validate the request immediately on creation if you have the required information. Else, you can delegate the emitter prompt and the validation to our dedicated payment webview.
When the
validate_uri
is provided, you must present it to the end-user to perform the confirmation steps. After the validation is performed, you will be redirected to your callback URL.After the payment is created or validated, you can check the status of the request:
GET /payments/{id}
{
"id": 110,
"state": "created",
"error_code": null,
"error_description": null,
…
}
Make sure you handle the various states and error codes correctly to provide a useful feedback to your users.
You can also have an overview of the payments, for example this will return the 10 last payments:
GET /payments?reverse&limit=10
{
"payments": [
{
"id": 110,
"state": "created",
"error_code": null,
"error_description": null,
…
}
],
"total": 1
}
You can paginate the payments by using the
offset
parameter along your desired limit (page size), this example will return the 21st to 30th last payments (third page):GET /payments?reverse&limit=10&offset=20
{
"payments": [
{
"id": 110,
"state": "created",
"error_code": null,
"error_description": null,
…
}
],
"total": 1
}
You can also filter payments with query parameters. The following example will return payments created after April 1st, 2021:
GET /payments?min_date=2021-04-01
The following example will return payments where the beneficiary identification (e.g. IBAN) is exactly 'FR76XXXXXXXXXX123', independently from the associated scheme name. Also note that no wildcard is supported.
GET /payments?beneficiary_identification=FR76XXXXXXXXXX123
Linking a user to a payment signifies that this user is the payer or beneficiary of the payment. This can be done by providing the
id_user
in the payer_beneficiary
or beneficiary_identity
fields. Note that the given id_user
must exist on your domain.POST /payments
{
"id_connector": 9,
"client_redirect_uri": "https://mycallback.com",
"instructions": [
{
"label": "Example id_user",
"amount": 10.50,
"currency": "EUR",
"execution_date_type": "first_open_day",
"beneficiary": {
"scheme_name": "iban",
"identification": "FR76XXXXXXXXXXXXXXX",
"label": "Corp",
},
"beneficiary_identity": {
"id_user": 2
}
}
],
"payer_identity": {
"id_user": 1
}
}
{
"id": 2058,
"state": "created",
"payer_identity": {
"id": 217,
"id_user": 1,
"kind": "individual",
"external_ref": null,
"first_name": null,
"last_name": null,
"org_name": null,
"org_legal_status": null,
"last_update_date": "2022-10-10 12:53:41",
"disabled_date": null
},
"instructions": [
{
"execution_date_type": "first_open_day",
"label": "Example id_user",
"amount": 10.5000000000,
"beneficiary_identity": {
"id": 216,
"id_user": 2,
"kind": "individual",
"external_ref": null,
"first_name": null,
"last_name": null,
"org_name": null,
"org_legal_status": null,
"last_update_date": "2022-10-10 12:53:41",
"disabled_date": null
},
...
...
}
],
...
}
Since the release of our Pay product (handling PSD2-compliant use-cases), the former Transfer product (based on directaccess) has been deprecated and is no longer offered.
The Transfer product allows you to make transfers on a limited number of bank connectors. It is an extension of the Bank product and transfers are linked and limited to aggregated bank accounts.
Accounts available as a transfer emitter are flagged with the
able_to_transfer
flag:GET /users/me/accounts
{
"accounts": [
{
"id": 12345,
"name": "Compte de dépôt",
"number": "0212366548",
"iban": "FR1221954549412158521",
"type": "checking",
"balance": 1452.56,
"coming": null,
"currency": { "id": "EUR", … },
"able_to_transfer": true,
…
},
…
]
}
Initiate a transfer from an non-flagged account will result in an error.
Transfer-enabled accounts are linked to
recipients
for the purpose of transfer execution. A recipient materializes the couple of an "emitter account" and a pre-registered "transfer destination", and the list of recipients matches the combinations actually available on the bank website. As a consequence, a single "beneficiary" will result in several recipients, from different accounts.
While this API can create new recipients on some connectors, execution of transfers to arbitrary destinations (PSD2 payment) is out of its scope.GET /users/me/recipients
GET /users/me/accounts/{accountId}/recipients
{
"recipients": [
{
"id": 5,
"id_account": 3,
"id_target_account": 2,
"label": "Livret A",
"bank_name": "BNP PARIBAS",
"iban": "FR7630004012550003027641744",
"bic": "BNPAFRPPXXX",
"category": "Internal",
"enabled_at": "2016-10-31 18:52:53",
"state": null,
…
},
{
"id": 6,
"id_account": 3,
"id_target_account": null,
"label": "Test",
"bank_name": "BNP PARIBAS",
"iban": "FR7630004000031234567890143",
"bic": "BNPAFRPPXXX",
"category": "External",
"enabled_at": "2016-10-31 18:52:53",
"deleted": "2016-12-05 12:07:24",
"last_update": "2016-12-05 12:07:24",
"state": "deleted",
…
},
…
]
}
The
id_target_account
property identifies internal recipients, where the destination account is present in the API.Recipients are subject to the same archival mechanism and implicit filtering as bank accounts or transactions. Use the query parameter
all
to display deleted recipients or recipients with an enabled_at
date in the future.Transfers are performed in two steps: initiation and validation.
Tranfer initiation
Create a transfer resource providing the account and recipient IDs and the transfer details:
POST /users/me/transfers
{
"id_account:": 123,
"id_recipient": 456,
"label": "Test",
"amount": 10,
"exec_date": "2019-09-01"
}
{
"id": 110,
"label": "Test",
"amount": 10.0,
"exec_date": "2019-09-01",
"id_recipient": 456,
"account_iban": "FR7630004012550000041157244",
"recipient_iban": "FR7630006000011234567890189",
"state": "created",
"register_date": "2019-02-28 11:41:26",
"currency": { "id": "EUR", … },
…
}
No interaction is made with the bank during the initiation step, and the transfer resource is editable while it has not been validated.
If the execution date is not specified, the default date is the day on which the transfer is created. The date should be checked before validation to avoid requesting the execution of a transfer in the past.
The label is optional but recommended so that the Pay product can find the equivalent transaction in the history to confirm the execution of the transfer. Support of non-ASCII characters in labels vary by banks and should be avoided to prevent validation errors.
Transfer validation
Transfer validation requires an explicit end-user validation.
POST /users/me/transfers/{id}
{ "validated": true }
This request actually submits the transfer order to the bank. It can results in an successful response if the transfer was successfully submitted:
{
"id": 110,
"state": "pending",
…
}
Else, if a user SCA is required to execute the transfer, the required fields are exposed in the reponse:
{
"id": 110,
"state": "pending",
"fields": [
{
"label": "Code secret BNP Paribas",
"type": "password",
"regex": "^[0-9]{6}$",
"name": "password"
}
]
}
The required fields (usually an OTP) must be presented to the user, and the input values must be sent to proceed with validation. We currently manage those sent by SMS or generated by box.
POST /users/me/transfers/{id}
{ "validated": true, "password": "xxxxxxx" }
{
"state": "pending",
"id": 110
}
To enforce security, transfer validation should not be performed using the all-purpose user access token. A special time-limited access token with the dedicated
transfer
scope must be obtained. If transfer execution is performed using a non-transfer
access token, the web banking password of the user will be asked as a validation field.
Last modified 1mo ago