budgea_client 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +450 -1
- data/lib/budgea_client/models/bank.rb +79 -57
- data/lib/budgea_client/version.rb +1 -1
- data/pkg/budgea_client-1.0.0.gem +0 -0
- data/pkg/budgea_client-1.1.0.gem +0 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b956cc05690bf6faa8f6038b5298c326746b50f43aa8e6b8e365d7c73f72ff69
|
4
|
+
data.tar.gz: 370aead36a87baad2bd4a25d25421ece3c75ec9e285a5af27564bbe6048cd93a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c8654c815ed56039eb1cf4f417cfaf8d8e54cade1a6dfc4168ff9e0b7efadbb04e662434ee5de107baa7767c7571190d4f247e29fe3bf26e786275ecb203d23
|
7
|
+
data.tar.gz: 5142608834a18b3db3dec3675e97a19c4edfc2b3142ad99b4547c937d4418d7fb833e3d67d81d3564f16c80e00b2ad8b1e15b5df626eb63b15547788713508aa
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,456 @@
|
|
2
2
|
|
3
3
|
BudgeaClient - the Ruby gem for the Budgea API Documentation
|
4
4
|
|
5
|
-
# Budgea Development Guides Welcome to **Budgea**'s documentation. This documentation is intended to get you up-and-running with our APIs and advise on the implementation of some regulatory aspects of your application, following the DSP2's guidelines. ## Getting Started **IMPORTANT** Depending on your status with regard of the DSP2 regulation, **agent** or **partner**, you may call our APIs or simply use our Webview and callbacks to get the financial data of your users. As an **agent**, you are allowed to call directly our APIs and implement your own form to get the user's credentials. As a **partner**, you cannot manipulate the credentials, and have to delegate this step to us through our webview. The sections below will document how to use our APIs, make sure you have the **agent** status to do so. For the **partner**, please refer to the section *Webview* and *Callbacks* of this documentation. ### Overview Your API is a REST API which requires a communication through https to send and receive JSON documents. During your tests, we recommend to make calls to the API with curl or any other HTTP client of your choice. You can watch a video demonstration on this [URL](https://asciinema.org/a/FsaFyt3WAPyDm7sfaZPkwal3V). For the examples we'll use the demo API with adress `https://demo.biapi.pro`, you should change that name to your API's name. ### Hello World Let's start by calling the service `/banks` which lists all available banks. ``` curl -X GET \\ https://demo.biapi.pro/2.0/banks/ ``` To log in to a bank webpage, you'll need to know for a given bank, the fields your user should fill in the form. Let's call a specific bank and ask for an additional resource *fields*. ``` curl -X GET \\ https://demo.biapi.pro/2.0/banks/59?expand=fields ``` The response here concerns only 1 bank (since we specified an id) and the resource _Fields_ is added to the response thanks to the query parameter `expand`. To get more interesting things done, you'll need to send authenticated requests. ### Authentication The way to authenticate is by passing the `Authorization: Bearer <token>` header in your request. At the setup a _manage token_ have been generated, you can use this token for now, when creating your user we'll see how to generate a user's token. ``` curl -X GET \\ https://demo.biapi.pro/2.0/config \\ -H 'Authorization: Bearer <token>' ``` This endpoint will list all the parameters you can change to adapt Budgea to your needs. We've covered the very first calls. Before diving deeper, let's see some general information about the APIs. ## Abstract ### API URL `https://demo.biapi.pro/2.0` ### Requests format Data format: **application/x-www-form-urlencoded** or **application/json** (suggested) Additional headers: Authorization: User's token (private) ### Responses format Data format: **application/json** ([http://www.json.org](http://www.json.org/)) Charset: **UTF-8** ### Resources Each call on an endpoint will return resources. The main resources are: | Resource | Description | | ---------------------|:------------------------------------------------------------------------------------------------------------------ | |Users |Represent a user | |Connection |A set of data used to authenticate on a website (usually a login and password). There is 1 connection for each website| |Account |A bank account contained in a connection | |Transaction |An entry in a bank account | |Investment |An asset in a bank account | The chain of resources is as follow: **Users ∈ Connections ∈ Accounts ∈ Transactions or Investments** ### RESTful API This API is RESTful, which means it is stateless and each resource is accessed with an uniq URI. Several HTTP methods are available: | Method | Description | | ------------------------|:-------------------------------| | GET /resources | List resources | | GET /resources/{ID} | Get a resource from its ID | | POST /resources | Create a new resource | | POST /resources/{ID} | Update a resource | | PUT /resources /{ID} | Update a resource | | DELETE /resources | Remove every resources | | DELETE /resources/{ID} | Delete a resource | Each resource can contain sub-resources, for example: `/users/me/connections/2/accounts/23/transactions/48` ### HTTP response codes | Code | Message | Description | | ----------- |:---------------------:|-----------------------------------------------------------------------------------------------| | 200 | OK |Default response when a GET or POST request has succeed | | 202 | Accepted |For a new connection this code means it is necessary to provide complementary information (2FA)| | 204 | No content |Default response when a POST request succeed without content | | 400 | Bad request |Supplied parameters are incorrect | | 403 | Forbidden |Invalid token | | 500 | Internal Servor Error |Server error | | 503 | Service Unavailable |Service is temporarily unavailable | ### Errors management In case an error occurs (code 4xx or 5xx), the response can contain a JSON object describing this error: ```json { \"code\": \"authFailure\", \"message\": \"Wrong password\" // Optional } ``` If an error is displayed on the website, Its content is returned in error_message field. The list of all possible errors is listed further down this page. ### Authentication A user is authenticated by an access_token which is sent by the API during a call on one of the authentication services, and can be supplied with this header: `Authorization: Bearer YYYYYYYYYYYYYYYYYYYYYYYYYYY` There are two user levels: - Normal user, which can only access to his own accounts - Administrator, with extended rights ### Default filters During a call to an URI which lists resources, some filters can be passed as query parameters: | Parameter | Type | Description | | ----------- |:---------:|-----------------------------------------------------------| | offset | Integer |Offset of the first returned resource | | limit | Integer |Limit number of results | | min_date | Date |Minimal date (if supported by service), format: YYYY-MM-DD | | max_date | Date |Maximal date (if supported by service), format: YYYY-MM-DD | ### Extend requests During a GET on a set of resources or on a unique resource, it is possible to add a parameter expand to the request to extend relations with other resources: `GET /2.0/users/me/accounts/123?expand=transactions[category],connection` ```json { \"id\" : 123 \"name\" : \"Compte chèque\" \"balance\" : 1561.15 \"transactions\" : [ { \"id\" : 9849, \"simplified_wording\" : \"HALL'S BEER\", \"value\" : -513.20, ... \"category\" : { \"id\" : 561, \"name\" : \"Sorties / Bar\", ... } }, ... ], \"id_user\" : 1, \"connection\" : { \"id\" : 1518, \"id_bank\" : 41, \"id_user\" : 1, \"error\" : null, ... } } ``` ### Request example ```http GET /2.0/banks?offset=0&limit=10&expand=fields Host: demo.biapi.pro Accept: application/json Authorization: Bearer <token> ``` ```http HTTP/1.1 200 OK Content-Type: application/json Content-Length: 3026 Server: Apache Date: Fri, 14 Mar 2014 08:24:02 GMT { \"banks\" : [ { \"id_weboob\" : \"bnporc\", \"name\" : \"BNP Paribas\", \"id\" : 3, \"hidden\" : false, \"fields\" : [ { \"id\" : 1, \"id_bank\" : 3, \"regex\" : \"^[0-9]{5,10}$\", \"name\" : \"login\", \"type\" : \"text\", \"label\" : \"Numéro client\" }, { \"id\" : 2, \"id_bank\" : 3, \"regex\" : \"^[0-9]{6}$\", \"name\" : \"password\", \"type\" : \"password\", \"label\" : \"Code secret\" } ] }, ... ] \"total\" : 41 } ``` ### Constants #### List of bank account types | Type |Description | | ----------- |-----------------------------------| | checking |Checking account | | savings |Savings account | | deposit |Deposit accounts | | loan |Loan | | market | Market accounts | | joint |Joint account | | card |Card | | lifeinsurance |Life insurance accounts | | pee |Plan Épargne Entreprise | | perco |Plan Épargne Retraite | | article83 |Article 83 | | rsp |Réserve spéciale de participation | | pea |Plan d'épargne en actions | | capitalisation|Contrat de capitalisation | | perp |Plan d'épargne retraite populaire | | madelin |Contrat retraite Madelin | | unknown |Inconnu | #### List of transaction types | Type |Description | | ----------- |-----------------------------------| |transfer |Transfers | |order |Orders | |check |Checks | |deposit |Cash deposit | |payback |Payback | |withdrawal |Withdrawal | |loan_payment |Loan payment | |bank |Bank fees | |card |Card operation | |deferred_card |Deferred card operation | |card_summary |Mensual debit of a deferred card | #### List of synchronization errors | Error |Description | | ----------------------- |------------------------------------------------------------------------------------- | |wrongpass |The authentication on website has failed | |additionalInformationNeeded |Additional information are needed | |websiteUnavailable |The website is unavailable | |actionNeeded |An action is needed on the website | |bug |A bug has occurred during the synchronization. An alert has been sent to Budget Insight| Now you know the basics of Budgea API - Basic call to retrieve resources - Add query parameters to aplly filters - Expand resources - Authenticated calls We're good for the basics! Now let's see how to integrate Budgea in your app and create your first user. ## Integrate Budgea ### The workflow Users of your application exist in the Budgea API. Every User is identified by an access_token which is the shared secret between your application and our API. The workflow is as below: 1. The user is on your application and wants to share his bank accounts or invoices. 2. A call is made **client side** (browser's javascript or desktop application) to create a temporarily token which will be used to make API calls. 3. A form is built, allowing the user to select the connector to use (bank or provider, depending on context). Every connector requires different kind of credentials. 4. A call on the API is made with the temporarily token to add a **Connection** with the credentials supplied by user. 5. In case of success, the user chooses what bank accounts (**Account**) or subscriptions (**Subscription**) he wants to share with your application. 6. When he validates the share, the temporarily token is transmitted to your server. This one will call the Budgea API with this token to get a permanent token. **Note** In case your application works without a server (for example a desktop application), the permanent token can be obtained on the 1st step, by supplying a client_secret to /autinit and the step 6 is omitted. To get more information, read the protocol. There are 3 steps to integrate Budgea in your application: 1. Provide a way for your users to share their credentials with you 2. Get the data scraped from Budgea 3. Be sure to follow the good practices before going into production ### Get credentials from users You have 2 options here: - Integrate the Budget Insight's Webview, a turnkey solution to get user's credentials - Create your own form following the protocol (must have the *agent* status) #### Webview The webview allows your users to give their bank or provider credentials to the safety third-party Budgea API. It is responsive, which means it displays correctly on a desktop or a mobile device. The API meets the standard [OAuth 2](http://tools.ietf.org/html/rfc6749) and any client library that implements it will be able to facilitate the integration to the Budgea API. We provide PHP, Python and Ruby modules to facilitate the integration. |Language | Library | |-----------------|---------------------------------------------------------------------------------------- | |PHP |[BudgeaAPI.php](https://github.com/budgetinsight/budgea-clients/blob/master/BudgeaAPI.php)| |PYTHON |[budgea_api.py](https://github.com/budgetinsight/budgea-clients/blob/master/budgea_api.py)| |RUBY |[budgea.rb](https://github.com/budgetinsight/budgea-clients/blob/master/budgea.rb) | To delegate to the Budgea API the management of the bank and provider credentials of your users, you have to provide a button which redirects on the following page: `https://demo.biapi.pro/2.0/auth/share/` You must first configure your client application. A client, in the OAuth 2 of the term, represents an application accessing to the Budgea API. The parameters to supply to the URL are the following: |Parameter |Description | |---------------------|------------------------------------------------------------ | |client_id |The client id of your application | |redirect_uri |(optional) The adress where the user shoud be redirected after sharing his credentials. The adress must match the redirection URI set for the client | |state |(optional) An arbitrary string sent back to you for control | |types |The type of connectors (**banks** or **providers**) | |connectors |(optional) Given a connector id, it will prefill the form | You can use our libraries to generate this URL. It is also possible to get the HTML code of the button with the libraries, the render is as below: ![Share your accounts button](https://demo.biapi.pro/2.0/auth/share/button_icon.png) When the user confirms the share of his accounts with you, he is redirected to the callback URL you have defined. This one receives the following parameters: |Parameter |Description | |---------------------|-------------------------------------------------------------------------------------------------| |code |A temporary token allowing you to get the **access_token** | |state |The same string passed when redirecting to the webview | |error |In case of error, the value will be **access_denied**, meaning the user has canceled the process | Eventually, to get the **access_token** from the temporarily code which has been transmitted to you, you must call the API: ```python try: if client.handleCallback(received_params): # Keep the token associated with the user # you can't get it twice user.session['access_token'] = client.access_token except client.StateInvalid: # error if 'state' param provided to handleCallback doesn't match except client.AuthFailed: # There may be an error in the query (look for the message), # Or return code is 'access_denied', the user has stopped the process ``` You can now associate this **access_token** to your user, and use it in your next calls to the API with the **Authorization** header. **IMPORTANT** It is important that your users are able to go back on the web, authenticated on their Budgea API account, to add or remove accounts shared with you, and mostly to update their credentials if needed. To do this, when your user is given an access_token, you have to provide him a link to access the webview, similar to the first one, with an additional parameter: a temporarily token (30 minutes life-time). It can be made with the library, by generating the URL with the following manner: ` print '<a href=\"%s\">Edit your accounts</a>' % client.get_settings_url()` After the modification, the user will go back on the callback URL. It will not be necessary to do anything (the access_token won't be changed). #### Protocol This section describes the protocol used to set bank and provider accounts of a user, in case you don't want to use the webview. The idea is to call the following services client-side (with AJAX in case of a web application), to ensure the bank and providers credentials will not be sent to your servers. 1. /auth/init ```http POST /auth/init ``` ```json { \"auth_token\" : \"fBqjMZbYddebUGlkR445JKPA6pCoRaGb\", \"type\" : \"temporary\", \"expires_in\" : 1800 } ``` This service creates a temporarily token, to use in the \"Authorization\" header in next calls to the API The returned token has a life-time of 30 minutes, and should be transfered to the API then (cf Permanent Token), so that your server can get a permanent access_token. It is possible to generate a permanent token immediately, by calling the service with the manage_token, or by supply parameters client_id and client_secret. 2. /banks or /providers ```http GET /banks?expand=fields Authorization: Bearer <token> ``` ```json { \"banks\" : [ { \"hidden\" : false, \"charged\" : true, \"name\" : \"American Express\", \"id\" : 30, \"fields\" : [ { \"values\" : [ { \"label\" : \"Particuliers/Professionnels\", \"value\" : \"pp\" }, { \"value\" : \"ent\", \"label\" : \"Entreprises\" } ], \"label\" : \"Type de compte\", \"regex\" : null, \"name\" : \"website\", \"type\" : \"list\" }, { \"type\" : \"password\", \"label\" : \"Code secret\", \"name\" : \"password\", \"regex\" : \"^[0-9]{6}$\" } ], }, ... ], \"total\" : 44, } ``` You get list of connectors, and all associated fields needed to build the form You can use that list to show your user all available banks. 3. /users/me/connections You have to supply the id_bank (ID of the chosen bank) or id_provider (ID of provider), and all requested fields as key/value parameters. You can get the following return codes: |Code |Description | |---------------|------------------------------------------------------------ | |200 |The connection has succeed and has been created | |202 |It is necessary to provide complementary information. This occurs on the first connection on some kind of Boursorama accounts for example, where a SMS is sent to the customer. It is necessary to ask the user to fill fields requested in the fields, and do a POST again on /users/me/connections/ID, with the connection ID in id_connection. | |400 |Unable to connect to the website, the field error in the JSON can be **websiteUnavailable** or **wrongpass** | |403 |Invalid token | 4. Permanent token If the user validates the share of accounts with you, it is necessary to transform the temporarily code to a permanent access_token. To do that, you have to supply it to your server, which should do a POST request on /auth/token/access with the following parameters: |Parameter |Description | |---------------------|----------------------------------------------------------------| |code |The temporarily token which will let you get the access_token | |client_id |The ID of your client application | |client_secret |The secret of your client application | ```json POST /auth/token/access { \"client_id\" : 17473055, \"client_secret\" : \"54tHJHjvodbANVzaRtcLzlHGXQiOgw80\", \"code\" : \"fBqjMZbYddebUGlkR445JKPA6pCoRaGb\" } ``` ```http HTTP/1.1 200 OK { \"access_token\" : \"7wBPuFfb1Hod82f1+KNa0AmrkIuQ3h1G\", \"token_type\":\"Bearer\" } ``` ### Update accounts Another important call is when a user wants to add/remove connections to banks or providers, or to change the password on one of them, it is advised to give him a temporarily code from the permanent access_token, with the following call (using the access_token as bearer): ```http POST /auth/token/code Authorization: Bearer <token> ``` ```json { \"code\" : \"/JiDppWgbmc+5ztHIUJtHl0ynYfw682Z\", \"type\" : \"temporary\", \"expires_in\" : 1800, } ``` Its life-time is 30 minutes, and let the browser to list connections and accounts, via `GET /users/me/connections?expand=accounts` for example. To update the password of a connection, you can do a POST on the *connection* resource, with the field *password* in the data. The new credentials are checked to make sure they are valid, and the return codes are the same as when adding a connection. ## Getting the data You have created your users and their connections, now it's time to get the data. There are 2 ways to retrieve it, the 2 can be complementary: - make regular calls to the API - use the webhooks (recommended) ### Manual Synchronization It is possible to do a manual synchronization of a user. We recommend to use this method in case the user wants fresh data after logging in. To trigger the synchronization, call the API as below: `PUT /users/ID/connections` The following call is blocking until the synchronization is terminated. Even if it is not recommended, it's possible to fetch synchronously new data. To do that, you can use the *expand* parameter: ` /users/ID/connections?expand=accounts[transactions,investments[type]],subscriptions` ```json { \"connections\" : [ { \"accounts\" : [ { \"balance\" : 7481.01, \"currency\" : { \"symbol\" : \"€\", \"id\" : \"EUR\", \"prefix\" : false }, \"deleted\" : null, \"display\" : true, \"formatted_balance\" : \"7 481,01 €\", \"iban\" : \"FR76131048379405300290000016\", \"id\" : 17, \"id_connection\" : 7, \"investments\" : [ { \"code\" : \"FR0010330902\", \"description\" : \"\", \"diff\" : -67.86, \"id\" : 55, \"id_account\" : 19, \"id_type\" : 1, \"label\" : \"Agressor PEA\", \"portfolio_share\" : 0.48, \"prev_diff\" : 2019.57, \"quantity\" : 7.338, \"type\" : { \"color\" : \"AABBCC\", \"id\" : 1, \"name\" : \"Fonds action\" }, \"unitprice\" : 488.98, \"unitvalue\" : 479.73, \"valuation\" : 3520.28 } ], \"last_update\" : \"2015-07-04 15:17:30\", \"name\" : \"Compte chèque\", \"number\" : \"3002900000\", \"transactions\" : [ { \"active\" : true, \"application_date\" : \"2015-06-17\", \"coming\" : false, \"comment\" : null, \"commission\" : null, \"country\" : null, \"date\" : \"2015-06-18\", \"date_scraped\" : \"2015-07-04 15:17:30\", \"deleted\" : null, \"documents_count\" : 0, \"formatted_value\" : \"-16,22 €\", \"id\" : 309, \"id_account\" : 17, \"id_category\" : 9998, \"id_cluster\" : null, \"last_update\" : \"2015-07-04 15:17:30\", \"new\" : true, \"original_currency\" : null, \"original_value\" : null, \"original_wording\" : \"FACTURE CB HALL'S BEER\", \"rdate\" : \"2015-06-17\", \"simplified_wording\" : \"HALL'S BEER\", \"state\" : \"parsed\", \"stemmed_wording\" : \"HALL'S BEER\", \"type\" : \"card\", \"value\" : -16.22, \"wording\" : \"HALL'S BEER\" } ], \"type\" : \"checking\" } ], \"error\" : null, \"expire\" : null, \"id\" : 7, \"id_user\" : 7, \"id_bank\" : 41, \"last_update\" : \"2015-07-04 15:17:31\" } ], \"total\" : 1, } ``` ### Background synchronizations & Webhooks Webhooks are callbacks sent to your server, when an event is triggered during a synchronization. Synchronizations are automatic, the frequency can be set using the configuration key `autosync.frequency`. Using webhooks allows you to get the most up-to-date data of your users, after each synchronization. The automatic synchronization makes it possible to recover new bank entries, or new invoices, at a given frequency. You have the possibility to add webhooks on several events, and choose to receive each one on a distinct URL. To see the list of available webhooks you can call the endpoint hereunder: ``` curl -X GET \\ https://demo.biapi.pro/2.0/webhooks_events \\ -H 'Authorization: Bearer <token>' ``` The background synchronizations for each user are independent, and their plannings are spread over the day so that they do not overload any website. Once the synchronization of a user is over, a POST request is sent on the callback URL you have defined, including all webhook data. A typical json sent to your server is as below: ```http POST /callback HTTP/1.1 Host: example.org Content-Length: 959 Accept-Encoding: gzip, deflate, compress Accept: */* User-Agent: Budgea API/2.0 Content-Type: application/json; charset=utf-8 Authorization: Bearer sl/wuqgD2eOo+4Zf9FjvAz3YJgU+JKsJ { \"connections\" : [ { \"accounts\" : [ { \"balance\" : 7481.01, \"currency\" : { \"symbol\" : \"€\", \"id\" : \"EUR\", \"prefix\" : false }, \"deleted\" : null, \"display\" : true, \"formatted_balance\" : \"7 481,01 €\", \"iban\" : \"FR76131048379405300290000016\", \"id\" : 17, \"id_connection\" : 7, \"investments\" : [ { \"code\" : \"FR0010330902\", \"description\" : \"\", \"diff\" : -67.86, \"id\" : 55, \"id_account\" : 19, \"id_type\" : 1, \"label\" : \"Agressor PEA\", \"portfolio_share\" : 0.48, \"prev_diff\" : 2019.57, \"quantity\" : 7.338, \"type\" : { \"color\" : \"AABBCC\", \"id\" : 1, \"name\" : \"Fonds action\" }, \"unitprice\" : 488.98, \"unitvalue\" : 479.73, \"valuation\" : 3520.28 } ], \"last_update\" : \"2015-07-04 15:17:30\", \"name\" : \"Compte chèque\", \"number\" : \"3002900000\", \"transactions\" : [ { \"active\" : true, \"application_date\" : \"2015-06-17\", \"coming\" : false, \"comment\" : null, \"commission\" : null, \"country\" : null, \"date\" : \"2015-06-18\", \"date_scraped\" : \"2015-07-04 15:17:30\", \"deleted\" : null, \"documents_count\" : 0, \"formatted_value\" : \"-16,22 €\", \"id\" : 309, \"id_account\" : 17, \"id_category\" : 9998, \"id_cluster\" : null, \"last_update\" : \"2015-07-04 15:17:30\", \"new\" : true, \"original_currency\" : null, \"original_value\" : null, \"original_wording\" : \"FACTURE CB HALL'S BEER\", \"rdate\" : \"2015-06-17\", \"simplified_wording\" : \"HALL'S BEER\", \"state\" : \"parsed\", \"stemmed_wording\" : \"HALL'S BEER\", \"type\" : \"card\", \"value\" : -16.22, \"wording\" : \"HALL'S BEER\" } ], \"type\" : \"checking\" } ], \"bank\" : { \"id_weboob\" : \"ing\", \"charged\" : true, \"name\" : \"ING Direct\", \"id\" : 7, \"hidden\" : false }, \"error\" : null, \"expire\" : null, \"id\" : 7, \"id_user\" : 7, \"id_bank\" : 41, \"last_update\" : \"2015-07-04 15:17:31\" } ], \"total\" : 1, \"user\" : { \"signin\" : \"2015-07-04 15:17:29\", \"id\" : 7, \"platform\" : \"sharedAccess\" } } ``` The authentication on the callback is made with the access_token of the user (which is a shared secret between your server and the Budgea API). When you are in production, it is needed to define a HTTPS URL using a valid certificate, delivered by a recognized authority. If this is not the case, you can contact us to add your CA (Certificate Authority) to our PKI (Public Key Infrastructure). Important: it is necessary to send back a HTTP 200 code, without what we consider that data is not correctly taken into account on your system, and it will be sent again at the next user synchronization. ## Guidelines for production Now you should have integrated the API inside your application. Make sure your Webhooks URLs are in HTTPS, if so you can enable the production state of the API. To make things great, here are some good practices, please check you have respected them: - You have provided to your users a way to configure their accounts - You have provided to your users a way to change their account passwords - You consider the **error** field of Connections, to alert the user in case the state is **wrongpass** - You map IDs of Accounts, Subscriptions, Transactions and Documents in your application, to be sure to correctly match them - When the deleted field is set on a bank transaction, you delete it in your database - You don't loop on all users to launch synchronizations, this might saturate the service If you have questions about above points, please contact us. Otherwise, you can put into production!
|
5
|
+
# Budgea Development Guides
|
6
|
+
|
7
|
+
Welcome to **Budgea**'s documentation.
|
8
|
+
This documentation is intended to get you up-and-running with our APIs and advise on the implementation of some
|
9
|
+
regulatory aspects of your application, following the DSP2's guidelines.
|
10
|
+
## Getting Started **IMPORTANT** Depending on your status with regard of the DSP2 regulation, **agent** or **partner**,
|
11
|
+
you may call our APIs or simply use our Webview and callbacks to get the financial data of your users. As an **agent**,
|
12
|
+
you are allowed to call directly our APIs and implement your own form to get the user's credentials. As a **partner**,
|
13
|
+
you cannot manipulate the credentials, and have to delegate this step to us through our webview.
|
14
|
+
|
15
|
+
The sections below will document how to use our APIs, make sure you have the **agent** status to do so. For the
|
16
|
+
**partner**, please refer to the section *Webview* and *Callbacks* of this documentation.
|
17
|
+
|
18
|
+
### Overview
|
19
|
+
Your API is a REST API which requires a communication through https to send and receive JSON documents. During your
|
20
|
+
tests, we recommend to make calls to the API with curl or any other HTTP client of your choice.
|
21
|
+
You can watch a video demonstration on this [URL](https://asciinema.org/a/FsaFyt3WAPyDm7sfaZPkwal3V). For the examples
|
22
|
+
we'll use the demo API with adress `https://demo.biapi.pro`, you should change that name to your API's name.
|
23
|
+
|
24
|
+
### Hello World
|
25
|
+
Let's start by calling the service `/banks` which lists all available banks.
|
26
|
+
``` curl -X GET \\
|
27
|
+
https://demo.biapi.pro/2.0/banks/
|
28
|
+
```
|
29
|
+
|
30
|
+
To log in to a bank webpage, you'll need to know for a given bank, the fields your user should fill in the form.
|
31
|
+
Let's call a specific bank and ask for an additional resource *fields*.
|
32
|
+
``` curl -X GET \\
|
33
|
+
https://demo.biapi.pro/2.0/banks/59?expand=fields
|
34
|
+
```
|
35
|
+
The response here concerns only 1 bank (since we specified an id) and the resource _Fields_ is added to the response
|
36
|
+
thanks to the query parameter `expand`.
|
37
|
+
|
38
|
+
To get more interesting things done, you'll need to send authenticated requests.
|
39
|
+
|
40
|
+
### Authentication
|
41
|
+
The way to authenticate is by passing the `Authorization: Bearer <token>` header in your request. At the setup
|
42
|
+
a _manage token_ have been generated, you can use this token for now, when creating your user we'll see how to
|
43
|
+
generate a user's token.
|
44
|
+
``` curl -X GET \\
|
45
|
+
https://demo.biapi.pro/2.0/config \\
|
46
|
+
-H 'Authorization: Bearer <token>'
|
47
|
+
```
|
48
|
+
|
49
|
+
This endpoint will list all the parameters you can change to adapt Budgea to your needs.
|
50
|
+
We've covered the very first calls. Before diving deeper, let's see some general information about the APIs.
|
51
|
+
|
52
|
+
## Abstract
|
53
|
+
|
54
|
+
### API URL
|
55
|
+
|
56
|
+
`https://demo.biapi.pro/2.0`
|
57
|
+
|
58
|
+
### Requests format
|
59
|
+
Data format: **application/x-www-form-urlencoded** or **application/json** (suggested)
|
60
|
+
Additional headers: Authorization: User's token (private)
|
61
|
+
|
62
|
+
### Responses format
|
63
|
+
Data format: **application/json** ([http://www.json.org](http://www.json.org/)) Charset: **UTF-8**
|
64
|
+
### Resources
|
65
|
+
Each call on an endpoint will return resources. The main resources are:
|
66
|
+
|
67
|
+
| Resource | Description |
|
68
|
+
|---------------------|:------------------------------------------------------------------------------------------------------------------ |
|
69
|
+
|Users | Represent a user |
|
70
|
+
|Connection | A set of data used to authenticate on a website (usually a login and password). There is 1 connection for each website|
|
71
|
+
|Account | A bank account contained in a connection |
|
72
|
+
|Transaction | An entry in a bank account |
|
73
|
+
|Investment | An asset in a bank account |
|
74
|
+
|
75
|
+
The chain of resources is as follow: **Users ∈ Connections ∈ Accounts ∈ Transactions or Investments**
|
76
|
+
|
77
|
+
### RESTful API
|
78
|
+
This API is RESTful, which means it is stateless and each resource is accessed with an uniq URI.
|
79
|
+
|
80
|
+
Several HTTP methods are available:
|
81
|
+
|
82
|
+
| Method | Description |
|
83
|
+
| ------------------------|:-------------------------------|
|
84
|
+
| GET /resources | List resources |
|
85
|
+
| GET /resources/{ID} | Get a resource from its ID |
|
86
|
+
| POST /resources | Create a new resource |
|
87
|
+
| POST /resources/{ID} | Update a resource |
|
88
|
+
| PUT /resources /{ID} | Update a resource |
|
89
|
+
| DELETE /resources | Remove every resources |
|
90
|
+
| DELETE /resources/{ID} | Delete a resource |
|
91
|
+
|
92
|
+
Each resource can contain sub-resources, for example: `/users/me/connections/2/accounts/23/transactions/48`
|
93
|
+
|
94
|
+
### HTTP response codes
|
95
|
+
|
96
|
+
| Code | Message | Description |
|
97
|
+
| ----------- |:---------------------:|-----------------------------------------------------------------------------------------------|
|
98
|
+
| 200 | OK |Default response when a GET or POST request has succeed |
|
99
|
+
| 202 | Accepted |For a new connection this code means it is necessary to provide complementary information (2FA)|
|
100
|
+
| 204 | No content |Default response when a POST request succeed without content |
|
101
|
+
| 400 | Bad request |Supplied parameters are incorrect |
|
102
|
+
| 403 | Forbidden |Invalid token |
|
103
|
+
| 500 | Internal Servor Error |Server error |
|
104
|
+
| 503 | Service Unavailable |Service is temporarily unavailable |
|
105
|
+
|
106
|
+
### Errors management
|
107
|
+
|
108
|
+
In case an error occurs (code 4xx or 5xx), the response can contain a JSON object describing this error:
|
109
|
+
|
110
|
+
```json
|
111
|
+
{
|
112
|
+
"code": "authFailure",
|
113
|
+
"message": "Wrong password" // Optional
|
114
|
+
}
|
115
|
+
```
|
116
|
+
|
117
|
+
If an error is displayed on the website, Its content is returned in error_message field. The list of all possible
|
118
|
+
errors is listed further down this page.
|
119
|
+
|
120
|
+
### Authentication
|
121
|
+
A user is authenticated by an access_token which is sent by the API during a call on one of the
|
122
|
+
authentication services, and can be supplied with this header: `Authorization: Bearer YYYYYYYYYYYYYYYYYYYYYYYYYYY`
|
123
|
+
There are two user levels:
|
124
|
+
* Normal user, which can only access to his own accounts
|
125
|
+
* Administrator, with extended rights
|
126
|
+
|
127
|
+
### Default filters
|
128
|
+
|
129
|
+
During a call to an URI which lists resources, some filters can be passed as query parameters:
|
130
|
+
|
131
|
+
| Parameter | Type | Description |
|
132
|
+
| ----------- |:---------:|-----------------------------------------------------------|
|
133
|
+
| offset | Integer |Offset of the first returned resource |
|
134
|
+
| limit | Integer |Limit number of results |
|
135
|
+
| min_date | Date |Minimal date (if supported by service), format: YYYY-MM-DD |
|
136
|
+
| max_date | Date |Maximal date (if supported by service), format: YYYY-MM-DD |
|
137
|
+
|
138
|
+
### Extend requests
|
139
|
+
|
140
|
+
During a GET on a set of resources or on a unique resource, it is possible to add a parameter expand to the request
|
141
|
+
to extend relations with other resources:
|
142
|
+
|
143
|
+
`GET /2.0/users/me/accounts/123?expand=transactions[category],connection`
|
144
|
+
|
145
|
+
```json
|
146
|
+
{
|
147
|
+
"id": 123,
|
148
|
+
"name": "Compte chèque",
|
149
|
+
"balance": 1561.15,
|
150
|
+
"transactions": [
|
151
|
+
{
|
152
|
+
"id": 9849,
|
153
|
+
"simplified_wording": "HALL'S BEER",
|
154
|
+
"value": -513.20,
|
155
|
+
...,
|
156
|
+
"category": {
|
157
|
+
"id": 561,
|
158
|
+
"name": "Sorties / Bar",
|
159
|
+
...
|
160
|
+
}
|
161
|
+
},
|
162
|
+
...
|
163
|
+
],
|
164
|
+
"id_user": 1,
|
165
|
+
"connection": {
|
166
|
+
"id": 1518,
|
167
|
+
"id_bank": 41,
|
168
|
+
"id_user": 1,
|
169
|
+
"error": null,
|
170
|
+
...
|
171
|
+
}
|
172
|
+
}
|
173
|
+
```
|
174
|
+
|
175
|
+
### Request example
|
176
|
+
|
177
|
+
```http
|
178
|
+
GET /2.0/banks?offset=0&limit=10&expand=fields
|
179
|
+
Host: demo.biapi.pro
|
180
|
+
Accept: application/json
|
181
|
+
Authorization: Bearer <token>
|
182
|
+
```
|
183
|
+
|
184
|
+
```http
|
185
|
+
HTTP/1.1 200 OK
|
186
|
+
Content-Type: application/json
|
187
|
+
Content-Length: 3026
|
188
|
+
Server: Apache
|
189
|
+
Date: Fri, 14 Mar 2014 08:24:02 GMT
|
190
|
+
{ \"banks\" : [ { \"id_weboob\" : \"bnporc\", \"name\" : \"BNP Paribas\", \"id\" : 3, \"hidden\" : false, \"fields\" : [ { \"id\" : 1, \"id_bank\" : 3, \"regex\" : \"^[0-9]{5,10}$\", \"name\" : \"login\", \"type\" : \"text\", \"label\" : \"Numéro client\" }, { \"id\" : 2, \"id_bank\" : 3, \"regex\" : \"^[0-9]{6}$\", \"name\" : \"password\", \"type\" : \"password\", \"label\" : \"Code secret\" } ] }, ... ] \"total\" : 41 }
|
191
|
+
```
|
192
|
+
|
193
|
+
### Constants
|
194
|
+
|
195
|
+
#### List of bank account types
|
196
|
+
|
197
|
+
| Type |Description |
|
198
|
+
| ----------- |-----------------------------------|
|
199
|
+
| checking |Checking account |
|
200
|
+
| savings |Savings account |
|
201
|
+
| deposit |Deposit accounts |
|
202
|
+
| loan |Loan |
|
203
|
+
| market | Market accounts |
|
204
|
+
| joint |Joint account |
|
205
|
+
| card |Card |
|
206
|
+
| lifeinsurance |Life insurance accounts |
|
207
|
+
| pee |Plan Épargne Entreprise |
|
208
|
+
| perco |Plan Épargne Retraite |
|
209
|
+
| article83 |Article 83 |
|
210
|
+
| rsp |Réserve spéciale de participation |
|
211
|
+
| pea |Plan d'épargne en actions |
|
212
|
+
| capitalisation|Contrat de capitalisation |
|
213
|
+
| perp |Plan d'épargne retraite populaire |
|
214
|
+
| madelin |Contrat retraite Madelin |
|
215
|
+
| unknown |Inconnu |
|
216
|
+
|
217
|
+
#### List of transaction types
|
218
|
+
|
219
|
+
| Type |Description |
|
220
|
+
| ----------- |-----------------------------------|
|
221
|
+
|transfer |Transfers |
|
222
|
+
|order |Orders |
|
223
|
+
|check |Checks |
|
224
|
+
|deposit |Cash deposit |
|
225
|
+
|payback |Payback |
|
226
|
+
|withdrawal |Withdrawal |
|
227
|
+
|loan_payment |Loan payment |
|
228
|
+
|bank |Bank fees |
|
229
|
+
|card |Card operation |
|
230
|
+
|deferred_card |Deferred card operation |
|
231
|
+
|card_summary |Mensual debit of a deferred card |
|
232
|
+
|
233
|
+
#### List of synchronization errors
|
234
|
+
|
235
|
+
| Error |Description |
|
236
|
+
| ----------------------- |------------------------------------------------------------------------------------- |
|
237
|
+
|wrongpass |The authentication on website has failed |
|
238
|
+
|additionalInformationNeeded |Additional information are needed |
|
239
|
+
|websiteUnavailable |The website is unavailable |
|
240
|
+
|actionNeeded |An action is needed on the website |
|
241
|
+
|bug |A bug has occurred during the synchronization. An alert has been sent to Budget Insight|
|
242
|
+
|
243
|
+
Now you know the basics of Budgea API
|
244
|
+
- Basic call to retrieve resources
|
245
|
+
- Add query parameters to aplly filters
|
246
|
+
- Expand resources
|
247
|
+
- Authenticated calls
|
248
|
+
|
249
|
+
We're good for the basics! Now let's see how to integrate Budgea in your app and create your first user.
|
250
|
+
|
251
|
+
## Integrate Budgea
|
252
|
+
|
253
|
+
### The workflow Users of your application exist in the Budgea API.
|
254
|
+
Every User is identified by an access_token which is the shared secret between your application and our API.
|
255
|
+
The workflow is as below:
|
256
|
+
|
257
|
+
1. The user is on your application and wants to share his bank accounts or invoices.
|
258
|
+
2. A call is made **client side** (browser's javascript or desktop application) to create a temporarily token which will be used to make API calls.
|
259
|
+
3. A form is built, allowing the user to select the connector to use (bank or provider, depending on context). Every connector requires different kind of credentials.
|
260
|
+
4. A call on the API is made with the temporarily token to add a **Connection** with the credentials supplied by user.
|
261
|
+
5. In case of success, the user chooses what bank accounts (**Account**) or subscriptions (**Subscription**) he wants to share with your application.
|
262
|
+
6. When he validates the share, the temporarily token is transmitted to your server.
|
263
|
+
|
264
|
+
This one will call the Budgea API with this token to get a permanent token.
|
265
|
+
|
266
|
+
**Note** In case your application works without a server (for example a desktop application), the permanent token can
|
267
|
+
be obtained on the 1st step, by supplying a client_secret to /autinit and the step 6 is omitted. To get more
|
268
|
+
information, read the protocol. There are 3 steps to integrate Budgea in your application:
|
269
|
+
1. Provide a way for your users to share their credentials with you
|
270
|
+
2. Get the data scraped from Budgea
|
271
|
+
3. Be sure to follow the good practices before going into production
|
272
|
+
|
273
|
+
### Get credentials from users
|
274
|
+
You have 2 options here:
|
275
|
+
- Integrate the Budget Insight's Webview, a turnkey solution to get user's credentials
|
276
|
+
- Create your own form following the protocol (must have the *agent* status)
|
277
|
+
|
278
|
+
#### Webview
|
279
|
+
|
280
|
+
The webview allows your users to give their bank or provider credentials to the safety third-party Budgea API.
|
281
|
+
It is responsive, which means it displays correctly on a desktop or a mobile device.
|
282
|
+
The API meets the standard [OAuth 2](http://tools.ietf.org/html/rfc6749) and any client library that implements it will
|
283
|
+
be able to facilitate the integration to the Budgea API. We provide PHP, Python and Ruby modules to facilitate the
|
284
|
+
integration.
|
285
|
+
|
286
|
+
|Language | Library |
|
287
|
+
|-----------------|---------------------------------------------------------------------------------------- |
|
288
|
+
|PHP |[BudgeaAPI.php](https://github.com/budgetinsight/budgea-clients/blob/master/BudgeaAPI.php)|
|
289
|
+
|PYTHON |[budgea_api.py](https://github.com/budgetinsight/budgea-clients/blob/master/budgea_api.py)|
|
290
|
+
|RUBY |[budgea.rb](https://github.com/budgetinsight/budgea-clients/blob/master/budgea.rb) |
|
291
|
+
|
292
|
+
To delegate to the Budgea API the management of the bank and provider credentials of your users, you have to
|
293
|
+
provide a button which redirects on the following page: `https://demo.biapi.pro/2.0/auth/share/`
|
294
|
+
|
295
|
+
You must first configure your client application. A client, in the OAuth 2 of the term, represents an application
|
296
|
+
accessing to the Budgea API. The parameters to supply to the URL are the following:
|
297
|
+
|
298
|
+
|Parameter |Description |
|
299
|
+
|---------------------|------------------------------------------------------------ |
|
300
|
+
|client_id |The client id of your application |
|
301
|
+
|redirect_uri |(optional) The adress where the user shoud be redirected after sharing his credentials. The adress must match the redirection URI set for the client |
|
302
|
+
|state |(optional) An arbitrary string sent back to you for control |
|
303
|
+
|types |The type of connectors (**banks** or **providers**) |
|
304
|
+
|connectors |(optional) Given a connector id, it will prefill the form |
|
305
|
+
|
306
|
+
You can use our libraries to generate this URL. It is also possible to get the HTML code of the button with
|
307
|
+
the libraries, the render is as below: ![Share your accounts button](https://demo.biapi.pro/2.0/auth/share/button_icon.png)
|
308
|
+
|
309
|
+
When the user confirms the share of his accounts with you, he is redirected to the callback URL you have defined. This one receives the following parameters:
|
310
|
+
|
311
|
+
|Parameter |Description |
|
312
|
+
|---------------------|-------------------------------------------------------------------------------------------------|
|
313
|
+
|code |A temporary token allowing you to get the **access_token** |
|
314
|
+
|state |The same string passed when redirecting to the webview |
|
315
|
+
|error |In case of error, the value will be **access_denied**, meaning the user has canceled the process |
|
316
|
+
|
317
|
+
Eventually, to get the **access_token** from the temporarily code which has been transmitted to you, you must call the API:
|
318
|
+
|
319
|
+
```python
|
320
|
+
try:
|
321
|
+
if client.handleCallback(received_params):
|
322
|
+
# Keep the token associated with the user
|
323
|
+
# you can't get it twice
|
324
|
+
user.session['access_token'] = client.access_token
|
325
|
+
except client.StateInvalid:
|
326
|
+
# error if 'state' param provided to handleCallback doesn't match
|
327
|
+
except client.AuthFailed:
|
328
|
+
# There may be an error in the query (look for the message),
|
329
|
+
# Or return code is 'access_denied', the user has stopped the process
|
330
|
+
```
|
331
|
+
|
332
|
+
You can now associate this **access_token** to your user, and use it in your next calls to the API with
|
333
|
+
the **Authorization** header. **IMPORTANT** It is important that your users are able to go back on the web,
|
334
|
+
authenticated on their Budgea API account, to add or remove accounts shared with you, and mostly to update their
|
335
|
+
credentials if needed. To do this, when your user is given an access_token, you have to provide him a link to access
|
336
|
+
the webview, similar to the first one, with an additional parameter: a temporarily token (30 minutes life-time).
|
337
|
+
|
338
|
+
It can be made with the library, by generating the URL with the following manner:
|
339
|
+
` print '<a href=\"%s\">Edit your accounts</a>' % client.get_settings_url()`
|
340
|
+
|
341
|
+
After the modification, the user will go back on the callback URL. It will not be necessary to do anything (the access_token won't be changed).
|
342
|
+
|
343
|
+
#### Protocol
|
344
|
+
|
345
|
+
This section describes the protocol used to set bank and provider accounts of a user, in case you don't want to use
|
346
|
+
the webview. The idea is to call the following services client-side (with AJAX in case of a web application),
|
347
|
+
to ensure the bank and providers credentials will not be sent to your servers. 1. /auth/init
|
348
|
+
|
349
|
+
```http
|
350
|
+
POST /auth/init
|
351
|
+
```
|
352
|
+
|
353
|
+
```json
|
354
|
+
{
|
355
|
+
"auth_token": "fBqjMZbYddebUGlkR445JKPA6pCoRaGb",
|
356
|
+
"type": "temporary",
|
357
|
+
"expires_in": 1800
|
358
|
+
}
|
359
|
+
```
|
360
|
+
This service creates a temporarily token, to use in the \"Authorization\" header in next calls to the API
|
361
|
+
The returned token has a life-time of 30 minutes, and should be transfered to the API then (cf Permanent Token),
|
362
|
+
so that your server can get a permanent access_token. It is possible to generate a permanent token immediately, by
|
363
|
+
calling the service with the manage_token, or by supply parameters client_id and client_secret. 2. /banks or /providers
|
364
|
+
```http
|
365
|
+
GET /banks?expand=fields Authorization: Bearer <token>
|
366
|
+
```
|
367
|
+
```json
|
368
|
+
{
|
369
|
+
"banks" : [ { "hidden" : false, "charged" : true, "name" : "American Express", "id" : 30, "fields" : [ { "values" : [ { "label" : "Particuliers/Professionnels", "value" : "pp" }, { "value" : "ent", "label" : "Entreprises" } ], "label" : "Type de compte", "regex" : null, "name" : "website", "type" : "list" }, { "type" : "password", "label" : "Code secret", "name" : "password", "regex" : "^[0-9]{6}$" } ], }, ... ], "total" : 44,
|
370
|
+
}
|
371
|
+
```
|
372
|
+
|
373
|
+
You get list of connectors, and all associated fields needed to build the form You can use that list to show your user
|
374
|
+
all available banks. 3. /users/me/connections You have to supply the id_bank (ID of the chosen bank) or
|
375
|
+
id_provider (ID of provider), and all requested fields as key/value parameters. You can get the following return codes:
|
376
|
+
|
377
|
+
|Code |Description |
|
378
|
+
|---------------|------------------------------------------------------------ |
|
379
|
+
|200 |The connection has succeed and has been created |
|
380
|
+
|202 |It is necessary to provide complementary information. This occurs on the first connection on some kind of Boursorama accounts for example, where a SMS is sent to the customer. It is necessary to ask the user to fill fields requested in the fields, and do a POST again on /users/me/connections/ID, with the connection ID in id_connection. |
|
381
|
+
|400 |Unable to connect to the website, the field error in the JSON can be **websiteUnavailable** or **wrongpass** |
|
382
|
+
|403 |Invalid token |
|
383
|
+
|
384
|
+
4. Permanent token If the user validates the share of accounts with you, it is necessary to transform the temporarily
|
385
|
+
code to a permanent access_token. To do that, you have to supply it to your server, which should do a POST
|
386
|
+
request on `/auth/token/access` with the following parameters:
|
387
|
+
|
388
|
+
|Parameter |Description |
|
389
|
+
|---------------------|----------------------------------------------------------------|
|
390
|
+
|code |The temporarily token which will let you get the access_token |
|
391
|
+
|client_id |The ID of your client application |
|
392
|
+
|client_secret |The secret of your client application |
|
393
|
+
|
394
|
+
```json POST /auth/token/access { \"client_id\" : 17473055, \"client_secret\" : \"54tHJHjvodbANVzaRtcLzlHGXQiOgw80\", \"code\" : \"fBqjMZbYddebUGlkR445JKPA6pCoRaGb\" } ```
|
395
|
+
```http HTTP/1.1 200 OK { \"access_token\" : \"7wBPuFfb1Hod82f1+KNa0AmrkIuQ3h1G\", \"token_type\":\"Bearer\" } ```
|
396
|
+
|
397
|
+
### Update accounts
|
398
|
+
|
399
|
+
Another important call is when a user wants to add/remove connections to banks or providers, or to change the password
|
400
|
+
on one of them, it is advised to give him a temporarily code from the permanent access_token, with the following call
|
401
|
+
(using the access_token as bearer):
|
402
|
+
|
403
|
+
```http POST /auth/token/code Authorization: Bearer <token> ```
|
404
|
+
|
405
|
+
```json
|
406
|
+
{ \"code\" : \"/JiDppWgbmc+5ztHIUJtHl0ynYfw682Z\", \"type\" : \"temporary\", \"expires_in\" : 1800, }
|
407
|
+
```
|
408
|
+
|
409
|
+
Its life-time is 30 minutes, and let the browser to list connections and accounts,
|
410
|
+
via `GET /users/me/connections?expand=accounts` for example.
|
411
|
+
|
412
|
+
To update the password of a connection, you can do a POST on the *connection* resource, with the field *password*
|
413
|
+
in the data. The new credentials are checked to make sure they are valid, and the return codes are the same as when
|
414
|
+
adding a connection. ## Getting the data You have created your users and their connections, now it's time to get the
|
415
|
+
data. There are 2 ways to retrieve it, the 2 can be complementary: - make regular calls to the API - use the webhooks
|
416
|
+
(recommended)
|
417
|
+
|
418
|
+
### Manual Synchronization
|
419
|
+
It is possible to do a manual synchronization of a user. We recommend to use this method in case the user wants fresh data after logging in.
|
420
|
+
To trigger the synchronization, call the API as below: `PUT /users/ID/connections` The following call is blocking until the synchronization is terminated.
|
421
|
+
Even if it is not recommended, it's possible to fetch synchronously new data. To do that, you can use the *expand* parameter:
|
422
|
+
` /users/ID/connections?expand=accounts[transactions,investments[type]],subscriptions`
|
423
|
+
|
424
|
+
```json
|
425
|
+
{ \"connections\" : [ { \"accounts\" : [ { \"balance\" : 7481.01, \"currency\" : { \"symbol\" : \"€\", \"id\" : \"EUR\", \"prefix\" : false }, \"deleted\" : null, \"display\" : true, \"formatted_balance\" : \"7 481,01 €\", \"iban\" : \"FR76131048379405300290000016\", \"id\" : 17, \"id_connection\" : 7, \"investments\" : [ { \"code\" : \"FR0010330902\", \"description\" : \"\", \"diff\" : -67.86, \"id\" : 55, \"id_account\" : 19, \"id_type\" : 1, \"label\" : \"Agressor PEA\", \"portfolio_share\" : 0.48, \"prev_diff\" : 2019.57, \"quantity\" : 7.338, \"type\" : { \"color\" : \"AABBCC\", \"id\" : 1, \"name\" : \"Fonds action\" }, \"unitprice\" : 488.98, \"unitvalue\" : 479.73, \"valuation\" : 3520.28 } ], \"last_update\" : \"2015-07-04 15:17:30\", \"name\" : \"Compte chèque\", \"number\" : \"3002900000\", \"transactions\" : [ { \"active\" : true, \"application_date\" : \"2015-06-17\", \"coming\" : false, \"comment\" : null, \"commission\" : null, \"country\" : null, \"date\" : \"2015-06-18\", \"date_scraped\" : \"2015-07-04 15:17:30\", \"deleted\" : null, \"documents_count\" : 0, \"formatted_value\" : \"-16,22 €\", \"id\" : 309, \"id_account\" : 17, \"id_category\" : 9998, \"id_cluster\" : null, \"last_update\" : \"2015-07-04 15:17:30\", \"new\" : true, \"original_currency\" : null, \"original_value\" : null, \"original_wording\" : \"FACTURE CB HALL'S BEER\", \"rdate\" : \"2015-06-17\", \"simplified_wording\" : \"HALL'S BEER\", \"state\" : \"parsed\", \"stemmed_wording\" : \"HALL'S BEER\", \"type\" : \"card\", \"value\" : -16.22, \"wording\" : \"HALL'S BEER\" } ], \"type\" : \"checking\" } ], \"error\" : null, \"expire\" : null, \"id\" : 7, \"id_user\" : 7, \"id_bank\" : 41, \"last_update\" : \"2015-07-04 15:17:31\" } ], \"total\" : 1, }
|
426
|
+
```
|
427
|
+
|
428
|
+
### Background synchronizations & Webhooks
|
429
|
+
|
430
|
+
Webhooks are callbacks sent to your server, when an event is triggered during a synchronization.
|
431
|
+
Synchronizations are automatic, the frequency can be set using the configuration key `autosync.frequency`.
|
432
|
+
Using webhooks allows you to get the most up-to-date data of your users, after each synchronization.
|
433
|
+
The automatic synchronization makes it possible to recover new bank entries, or new invoices, at a given frequency.
|
434
|
+
You have the possibility to add webhooks on several events, and choose to receive each one on a distinct URL.
|
435
|
+
To see the list of available webhooks you can call the endpoint hereunder:
|
436
|
+
|
437
|
+
```
|
438
|
+
curl -X GET \
|
439
|
+
https://demo.biapi.pro/2.0/webhooks_events \
|
440
|
+
-H 'Authorization: Bearer <token>'
|
441
|
+
```
|
442
|
+
|
443
|
+
The background synchronizations for each user are independent, and their plannings are spread over the day so that they do not overload any website. Once the synchronization of a user is over, a POST request is sent on the callback URL you have defined, including all webhook data. A typical json sent to your server is as below:
|
444
|
+
|
445
|
+
```http
|
446
|
+
POST /callback HTTP/1.1 Host: example.org
|
447
|
+
Content-Length: 959 Accept-Encoding: gzip, deflate, compress
|
448
|
+
Accept: */* User-Agent: Budgea API/2.0
|
449
|
+
Content-Type: application/json; charset=utf-8
|
450
|
+
Authorization: Bearer sl/wuqgD2eOo+4Zf9FjvAz3YJgU+JKsJ
|
451
|
+
{ \"connections\" : [ { \"accounts\" : [ { \"balance\" : 7481.01, \"currency\" : { \"symbol\" : \"€\", \"id\" : \"EUR\", \"prefix\" : false }, \"deleted\" : null, \"display\" : true, \"formatted_balance\" : \"7 481,01 €\", \"iban\" : \"FR76131048379405300290000016\", \"id\" : 17, \"id_connection\" : 7, \"investments\" : [ { \"code\" : \"FR0010330902\", \"description\" : \"\", \"diff\" : -67.86, \"id\" : 55, \"id_account\" : 19, \"id_type\" : 1, \"label\" : \"Agressor PEA\", \"portfolio_share\" : 0.48, \"prev_diff\" : 2019.57, \"quantity\" : 7.338, \"type\" : { \"color\" : \"AABBCC\", \"id\" : 1, \"name\" : \"Fonds action\" }, \"unitprice\" : 488.98, \"unitvalue\" : 479.73, \"valuation\" : 3520.28 } ], \"last_update\" : \"2015-07-04 15:17:30\", \"name\" : \"Compte chèque\", \"number\" : \"3002900000\", \"transactions\" : [ { \"active\" : true, \"application_date\" : \"2015-06-17\", \"coming\" : false, \"comment\" : null, \"commission\" : null, \"country\" : null, \"date\" : \"2015-06-18\", \"date_scraped\" : \"2015-07-04 15:17:30\", \"deleted\" : null, \"documents_count\" : 0, \"formatted_value\" : \"-16,22 €\", \"id\" : 309, \"id_account\" : 17, \"id_category\" : 9998, \"id_cluster\" : null, \"last_update\" : \"2015-07-04 15:17:30\", \"new\" : true, \"original_currency\" : null, \"original_value\" : null, \"original_wording\" : \"FACTURE CB HALL'S BEER\", \"rdate\" : \"2015-06-17\", \"simplified_wording\" : \"HALL'S BEER\", \"state\" : \"parsed\", \"stemmed_wording\" : \"HALL'S BEER\", \"type\" : \"card\", \"value\" : -16.22, \"wording\" : \"HALL'S BEER\" } ], \"type\" : \"checking\" } ], \"bank\" : { \"id_weboob\" : \"ing\", \"charged\" : true, \"name\" : \"ING Direct\", \"id\" : 7, \"hidden\" : false }, \"error\" : null, \"expire\" : null, \"id\" : 7, \"id_user\" : 7, \"id_bank\" : 41, \"last_update\" : \"2015-07-04 15:17:31\" } ], \"total\" : 1, \"user\" : { \"signin\" : \"2015-07-04 15:17:29\", \"id\" : 7, \"platform\" : \"sharedAccess\" } }
|
452
|
+
```
|
453
|
+
|
454
|
+
The authentication on the callback is made with the access_token of the user (which is a shared secret between your server and the Budgea API). When you are in production, it is needed to define a HTTPS URL using a valid certificate, delivered by a recognized authority. If this is not the case, you can contact us to add your CA (Certificate Authority) to our PKI (Public Key Infrastructure). Important: it is necessary to send back a HTTP 200 code, without what we consider that data is not correctly taken into account on your system, and it will be sent again at the next user synchronization. ## Guidelines for production Now you should have integrated the API inside your application. Make sure your Webhooks URLs are in HTTPS, if so you can enable the production state of the API. To make things great, here are some good practices, please check you have respected them: - You have provided to your users a way to configure their accounts - You have provided to your users a way to change their account passwords - You consider the **error** field of Connections, to alert the user in case the state is **wrongpass** - You map IDs of Accounts, Subscriptions, Transactions and Documents in your application, to be sure to correctly match them - When the deleted field is set on a bank transaction, you delete it in your database - You don't loop on all users to launch synchronizations, this might saturate the service If you have questions about above points, please contact us. Otherwise, you can put into production!
|
6
455
|
|
7
456
|
This SDK is automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) project:
|
8
457
|
|
@@ -36,38 +36,46 @@ module BudgeaClient
|
|
36
36
|
# How many months of history to fetch
|
37
37
|
attr_accessor :months_to_fetch
|
38
38
|
|
39
|
+
attr_accessor :account_types
|
40
|
+
|
41
|
+
attr_accessor :fields
|
42
|
+
|
39
43
|
|
40
44
|
# Attribute mapping from ruby-style variable name to JSON key.
|
41
45
|
def self.attribute_map
|
42
46
|
{
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
47
|
+
:'id' => :'id',
|
48
|
+
:'name' => :'name',
|
49
|
+
:'id_weboob' => :'id_weboob',
|
50
|
+
:'hidden' => :'hidden',
|
51
|
+
:'charged' => :'charged',
|
52
|
+
:'code' => :'code',
|
53
|
+
:'beta' => :'beta',
|
54
|
+
:'color' => :'color',
|
55
|
+
:'slug' => :'slug',
|
56
|
+
:'sync_frequency' => :'sync_frequency',
|
57
|
+
:'months_to_fetch' => :'months_to_fetch',
|
58
|
+
:'account_types' => :'account_types',
|
59
|
+
:'fields' => :'fields'
|
54
60
|
}
|
55
61
|
end
|
56
62
|
|
57
63
|
# Attribute type mapping.
|
58
64
|
def self.swagger_types
|
59
65
|
{
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
66
|
+
:'id' => :'Integer',
|
67
|
+
:'name' => :'String',
|
68
|
+
:'id_weboob' => :'String',
|
69
|
+
:'hidden' => :'BOOLEAN',
|
70
|
+
:'charged' => :'BOOLEAN',
|
71
|
+
:'code' => :'String',
|
72
|
+
:'beta' => :'BOOLEAN',
|
73
|
+
:'color' => :'String',
|
74
|
+
:'slug' => :'String',
|
75
|
+
:'sync_frequency' => :'Float',
|
76
|
+
:'months_to_fetch' => :'Integer',
|
77
|
+
:'account_types' => :'Array<String>',
|
78
|
+
:'fields' => :'Array<Field>'
|
71
79
|
}
|
72
80
|
end
|
73
81
|
|
@@ -129,6 +137,18 @@ module BudgeaClient
|
|
129
137
|
self.months_to_fetch = attributes[:'months_to_fetch']
|
130
138
|
end
|
131
139
|
|
140
|
+
if attributes.has_key?(:'account_types')
|
141
|
+
if (value = attributes[:'account_types']).is_a?(Array)
|
142
|
+
self.account_types = value
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
if attributes.has_key?(:'fields')
|
147
|
+
if (value = attributes[:'fields']).is_a?(Array)
|
148
|
+
self.fields = value
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
132
152
|
end
|
133
153
|
|
134
154
|
# Show invalid properties with the reasons. Usually used together with valid?
|
@@ -184,7 +204,9 @@ module BudgeaClient
|
|
184
204
|
color == o.color &&
|
185
205
|
slug == o.slug &&
|
186
206
|
sync_frequency == o.sync_frequency &&
|
187
|
-
months_to_fetch == o.months_to_fetch
|
207
|
+
months_to_fetch == o.months_to_fetch &&
|
208
|
+
account_types == o.account_types &&
|
209
|
+
fields == o.fields
|
188
210
|
end
|
189
211
|
|
190
212
|
# @see the `==` method
|
@@ -196,7 +218,7 @@ module BudgeaClient
|
|
196
218
|
# Calculates hash code according to all attributes.
|
197
219
|
# @return [Fixnum] Hash code
|
198
220
|
def hash
|
199
|
-
[id, name, id_weboob, hidden, charged, code, beta, color, slug, sync_frequency, months_to_fetch].hash
|
221
|
+
[id, name, id_weboob, hidden, charged, code, beta, color, slug, sync_frequency, months_to_fetch, account_types, fields].hash
|
200
222
|
end
|
201
223
|
|
202
224
|
# Builds the object from hash
|
@@ -225,39 +247,39 @@ module BudgeaClient
|
|
225
247
|
# @return [Object] Deserialized data
|
226
248
|
def _deserialize(type, value)
|
227
249
|
case type.to_sym
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
end
|
244
|
-
when :Object
|
245
|
-
# generic object (usually a Hash), return directly
|
246
|
-
value
|
247
|
-
when /\AArray<(?<inner_type>.+)>\z/
|
248
|
-
inner_type = Regexp.last_match[:inner_type]
|
249
|
-
value.map { |v| _deserialize(inner_type, v) }
|
250
|
-
when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
|
251
|
-
k_type = Regexp.last_match[:k_type]
|
252
|
-
v_type = Regexp.last_match[:v_type]
|
253
|
-
{}.tap do |hash|
|
254
|
-
value.each do |k, v|
|
255
|
-
hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
|
250
|
+
when :DateTime
|
251
|
+
DateTime.parse(value)
|
252
|
+
when :Date
|
253
|
+
Date.parse(value)
|
254
|
+
when :String
|
255
|
+
value.to_s
|
256
|
+
when :Integer
|
257
|
+
value.to_i
|
258
|
+
when :Float
|
259
|
+
value.to_f
|
260
|
+
when :BOOLEAN
|
261
|
+
if value.to_s =~ /\A(true|t|yes|y|1)\z/i
|
262
|
+
true
|
263
|
+
else
|
264
|
+
false
|
256
265
|
end
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
266
|
+
when :Object
|
267
|
+
# generic object (usually a Hash), return directly
|
268
|
+
value
|
269
|
+
when /\AArray<(?<inner_type>.+)>\z/
|
270
|
+
inner_type = Regexp.last_match[:inner_type]
|
271
|
+
value.map { |v| _deserialize(inner_type, v) }
|
272
|
+
when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
|
273
|
+
k_type = Regexp.last_match[:k_type]
|
274
|
+
v_type = Regexp.last_match[:v_type]
|
275
|
+
{}.tap do |hash|
|
276
|
+
value.each do |k, v|
|
277
|
+
hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
else # model
|
281
|
+
temp_model = BudgeaClient.const_get(type).new
|
282
|
+
temp_model.build_from_hash(value)
|
261
283
|
end
|
262
284
|
end
|
263
285
|
|
@@ -305,4 +327,4 @@ module BudgeaClient
|
|
305
327
|
|
306
328
|
end
|
307
329
|
|
308
|
-
end
|
330
|
+
end
|
data/pkg/budgea_client-1.0.0.gem
CHANGED
Binary file
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: budgea_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chaker Nakhli
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -387,6 +387,7 @@ files:
|
|
387
387
|
- lib/budgea_client/models/webhook.rb
|
388
388
|
- lib/budgea_client/version.rb
|
389
389
|
- pkg/budgea_client-1.0.0.gem
|
390
|
+
- pkg/budgea_client-1.1.0.gem
|
390
391
|
- spec/api/administration_api_spec.rb
|
391
392
|
- spec/api/authentication_api_spec.rb
|
392
393
|
- spec/api/banks_api_spec.rb
|