Setting up the Tinkoff Bank API. How is your intuition ? Or a song about Oauth 2.0

 3r33338. 3r3-31. A couple of weeks ago in one of the projects there was a question about the integration of CRM with the API of Bank Tinkoff. In particular, it was about getting a bank account statement.
 3r33338.
 3r33338. The asset had:
 3r33338.
 3r33338. 3r3391.  3r33338. 3r3108. openapi.tinkoff.ru 3r3111.  3r33338. 3r3108. The telephone of the support service (taking into account the employment of the technical support department is the business of saving the drowning man, the work of the drowning man himself). 3r3111.  3r33338. 3r3108. Loaded document: 24386_policy.pdf 3r3-3110. (with Russian letters inside, with amusing expressions, magical turns, of little use, but still a thing ) 3r3111.  3r33338. 3r3113.
 3r33338. In the course of googlezh, reviews were also found that setting up the API of Tinkoff Bank is quite entertaining and non-trivial (see the article on banki.ru
“API Tinkoff - we are too stupid for this” 3r33110.).
 3r33338.
 3r33338. Yes, I had to tinker a little, therefore, in order to save time for the other shopmates, this article was written.
 3r33338.
3r31-10.
 3r33338. I note that the Tinkoff Bank API uses Oauth 2.0 for authorization.
 3r33338.
 3r33338. Why do we need openapi.tinkoff.ru?
 3r33338.
 3r33338. 3r3391.  3r33338. 3r3108. for the test (see below); 3r3111.  3r33338. 3r3108. in order to guess what and how; there is no direct splint; working at the level of intuition! 3r3111.  3r33338. 3r3113.
 3r33338. Let's get started In the “SSO Authorization” section, click on “how /Hide” and then /secure /token # refresh-token (“Token issue via refresh token”), select grant_type as a parameter, then in the refresh_token field (you can get it in Personal user account). Click the button “Try it out!” The result of these actions is to get this important things like access_token (i.e. openapi.tinkoff.ru [b] demonstrates 3r3-382. possibility of its receipt).
 3r33338.
 3r33338. Next, we look at the section “Accounts and payments”, click on /partner /company /{INN} /excerpt (“Receive statement”). We study what parameters are necessary in order to get it: Authorization, INN, accountNumber, from, till.
 3r33338.
 3r33338. Authorization - we guess that Authorization is nothing more than an access_token, which we received in the section “SSO Authorization”;
 3r33338. INN - the organization's TIN for which we set up the API;
 3r33338. from - from which day (discharge period);
 3r33338. till - on what day (discharge period).
 3r33338.
 3r33338. Thus (we look at the Oauth 2.0 hardware), [b] The receipt of the statement data takes place in two stages - first we get access_token, then having access_token in hand, we get the data for this statement 3r382. . Fine. The algorithm is clear, we write the code (the access parameters in the code are the values ​​for $ user, $ pass, $ refresh_token, $ inn, $ accountNumber — in the code below, they are changed, for obvious reasons).
 3r33338.
 3r33338. Create the following files:
 3r33338.
 3r33338. 3r3391.  3r33338. 3r3108. The first settings file is 3r3394. StartSettings.php
3r3111.  3r33338. 3r3108. The second file is starting - 3r3999. Start.php 3r3-3110. 3r3111.  3r33338. 3r3108. The third file of posting /parsing data to /from the API is 3r3-3104. TinkoffInsertData.php 3r3-3110. ; use CURL (php). 3r3111.  3r33338. 3r3108. Empty database dump where you can fill in your statement dаta: bank.sql ; MySQL database (data is sent to the database via PDO). 3r3111.  3r33338. 3r3113.
 3r33338. So, look at the code and comments to it!
 3r33338.
 3r33338. Settings file - StartSettings.php:
 3r33338.
 3r33338. 3r33180. 3r3181. $ host = '???.1'; 3r33338. $ db = 'bank'; 3r33338. $ user = 'root'; 3r33338. $ pass = "; 3r33338. $ charset = 'utf8'; 3r33338. 3r33338. 3r33338. $ dsn = "mysql: host = $ host; dbname = $ db; charset = $ charset"; 3r33338. $ opt =[
PDO::ATTR_ERRMODE
=> PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES
=> false,
]; 3r33338. $ pdo = new PDO ($ dsn, $ user, $ pass, $ opt); 3r33338. 3r33338. $ user = "IKu0jn98kllkI90kklii"; //20 characters
$ pass = "ds4234SDFsdfsdijoijslkkdjfoIOi"; //30 characters 3r33338. $ refresh_token = 'dsfh345kljlkjsdf098sdfkljklj098sdfkklKKLjhjihiKL90909llkrre5345dfFDDFretertERTERETfdgd =='; //88 characters 3r3338. $ inn = '750151513135'; 3r33338. $ accountNumber = '40802810300000121212'; //20 characters
3r33338. 3r33338. $ from_year = '1980'; 3r33338. $ from_month = '01'; 3r33338. $ from_day = '01'; 3r33338. 3r33338. 3r33338. $ till_year = date ('Y'); 3r33338. $ till_month = date ('m'); 3r33338. $ till_day = date ('d'); 3r33333.
 3r33338. Starting file - Start.php:
 3r33338.
 3r33338. 3r33180. 3r3181. session_start (); 3r33338. error_reporting (E_ALL); 3r33338. include 'StartSettings.php'; 3r33338. include 'TinkoffInsertData.php'; 3r33338. 3r33338. TinkoffInsertData ($ user, $ pass, $ refresh_token, $ inn, $ accountNumber, $ from_year, $ from_month, $ from_day, $ till_year, $ till_month, $ till_day, $ pdo); 3r33338. $ stmt = $ pdo-> prepare ("INSERT INTO` bank`.`dateofwork` (dateofwork) VALUES (NOW ()) "); 3r33338. $ stmt-> execute (); 3r33333.
 3r33338. File posting /parsing data to /from the API - TinkoffInsertData.php:
 3r33338.
 3r33338. 3r33180. 3r3181. function TinkoffInsertData ($ user, $ pass, $ refresh_token, $ inn, $ accountNumber, $ from_year, $ from_month, $ from_day, $ till_year, $ till_month, $ till_day, $ pdo) {
3r33338. 3r33338. //The first stage - the campaign of the Jedi for access_token
$ from_date = $ from_year. "-". $ from_month. "-". $ from_day. '% 2B03% 3A00% 3A00'; 3r33338. $ till_date = $ till_year. "-". $ till_month. "-". $ till_day. '% 2B03% 3A00% 3A00'; 3r33338. 3r33338. $ params =['grant_type'=>'refresh_token',
'refresh_token'=>$refresh_token
]; 3r33338. $ headers =[
'POST /secure/token HTTP/1.1',
'Content-Type: application/x-www-form-urlencoded'
]; 3r33338. $ curlURL = 'https: //sso.tinkoff.ru/secure/token'; 3r33338. $ ch = curl_init (); 3r33338. curl_setopt ($ ch, CURLOPT_URL, $ curlURL); 3r33338. curl_setopt ($ ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 3r33338. curl_setopt ($ ch, CURLOPT_USERPWD, $ user. ":". $ pass); 3r33338. curl_setopt ($ ch, CURLOPT_HEADER, true); 3r33338. curl_setopt ($ ch, CURLOPT_HTTPHEADER, $ headers); 3r33338. curl_setopt ($ ch, CURLOPT_POST, true); 3r33338. curl_setopt ($ ch, CURLOPT_POSTFIELDS, http_build_query ($ params)); 3r33338. curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, true); 3r33338. curl_setopt ($ ch, CURLOPT_VERBOSE, true); 3r33338. 3r33338. $ curl_res = curl_exec ($ ch); 3r33338. if ($ curl_res) {
$ server_output = json_decode ($ curl_res); 3r33338.}
3r33338. //Read access_token - it is needed to implement stage 2 3r33338. $ access_token_pos_start = strpos ($ curl_res, 'access_token', 0); 3r33338. $ access_token_pos_start = $ access_token_pos_start + 15; 3r33338. $ token_type_pos_start = strpos ($ curl_res, "token_type", 0); 3r33338. $ access_token = mb_substr ($ curl_res, $ access_token_pos_start, ($ token_type_pos_start- $ access_token_pos_start-3)); 3r33338. //Hooray! we did it
3r33338. //If desired, you can uncomment this sleep, but in principle it works without it
//sleep (1); 3r33338. 3r33338. 3r33338. //The second stage - the campaign of the Jedi for the data 3r33338. $ params =[
'Authorization'=>$access_token,
'INN'=>$inn,
'accountNumber'=>$accountNumber
]; 3r33338. 3r33338. $ headers =[
'Authorization: Bearer '.$access_token
]; 3r33338. 3r33338. $ curlURL = 'https: //sme-partner.tinkoff.ru/api/v1/partner/company/'.$inn.'/excerpt? accountNumber ='. $ accountNumber. '& from ='. $ from_date. '& till = '. $ till_date; 3r33338. 3r33338. 3r33338. $ ch = curl_init (); 3r33338. curl_setopt ($ ch, CURLOPT_URL, $ curlURL); 3r33338. curl_setopt ($ ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); 3r33338. curl_setopt ($ ch, CURLOPT_USERPWD, $ user. ":". $ pass); 3r33338. curl_setopt ($ ch, CURLOPT_HEADER, true); 3r33338. curl_setopt ($ ch, CURLOPT_HTTPHEADER, $ headers); 3r33338. curl_setopt ($ ch, CURLOPT_POST, false); 3r33338. curl_setopt ($ ch, CURLOPT_CUSTOMREQUEST, 'GET'); 3r33338. curl_setopt ($ ch, CURLOPT_POSTFIELDS, http_build_query ($ params)); 3r33338. curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, true); 3r33338. curl_setopt ($ ch, CURLOPT_VERBOSE, true); 3r33338. 3r33338. $ curl_res = curl_exec ($ ch); 3r33338. if ($ curl_res) {
$ server_output = json_decode ($ curl_res); 3r33338.}
3r33338. $ IE_Edge_pos_start = strpos ($ curl_res, 'IE = Edge', 0); 3r33338. $ IE_Edge_pos_start = $ IE_Edge_pos_start + 7; 3r33338. $ tinkoff_json = mb_substr ($ curl_res, $ IE_Edge_pos_start); 3r33338. $ tinkoff_json = trim ($ tinkoff_json); 3r33338. $ tinkoff_json = json_decode ($ tinkoff_json); 3r33338. 3r33338. 3r33338. //whether and that account we read, sobsno;)
foreach ($ tinkoff_json as $ k => $ v) {3r3333338. if ($ k == 'accountNumber') {
if (! ($ v == $ accountNumber)) die ('not that accountNumber'); 3r33338.}
}
3r33338. 3r33338. //$ tinkoff_array - write data from json to the
array. foreach ($ tinkoff_json as $ k => $ v) {3r3333338. if ($ k == 'operation') {3r33333. $ i = 0; 3r33338. foreach ($ v as $ t => $ s) {
foreach ($ s as $ e => $ f) {
$ tinkoff_array[$i] [$e]= $ f; 3r33338.}
$ i ++; 3r33338.}
}
}
3r33338. 3r33338. 3r33338. 3r33338. //fill in the data from $ tinkoff_array into the
database. for ($ i = 0; $ i
query ("SELECT count (*) FROM` justtin``tinkoff` WHERE id = ". $ tinkoff_array[$i] ['id']."; ")) -> fetchColumn ();
if ($ temp_id == 0) {
if (Get_highly_likely_is_number_bill ($ tinkoff_array[$i]w2w250.)! = "") {
`justtin`.`tinkoff` (id, date, amount, drawDate, payerName, payerInn, payerAccount, payerCorrAccount, payerBic, payerBank, chargeDate, recipient, recipientInn, recipientAccount, recipientCorrAccount, recipientB.course, etc., recipient Administrator, recipientAccount, recipientCorrAccount, recipientBrough, etc, etc. payerKpp, executionOrder, date_of_save) VALUES (: id,: date,: amount,: drawDate,: payerName,: payerInn,: payerAccount,: payerCorrAccount,: payerBic,: payerBank,: chargeDate,: recipient,: recipientInn,:; : recipientCorrAccount,: recipientBic,: recipientBank,: operationType,: uin,: paymentPurpose,: creatorStatus,: payerKpp,: executionOrder, NOW ()) "; 3rr3838. $ stmt-> bin dParam (': id', $ tinkoff_array[$i] ['id']); 3r33338. $ stmt-> bindParam (': date', $ tinkoff_array[$i] ['date']); 3r33338. $ stmt-> bindParam (': amount', $ tinkoff_array[$i] ['amount']); 3r33338. $ stmt-> bindParam (': drawDate', $ tinkoff_array[$i] ['drawDate']); 3r33338. $ stmt-> bindParam (': payerName', $ tinkoff_array[$i] ['payerName']); 3r33338. $ stmt-> bindParam (': payerInn', $ tinkoff_array[$i] ['payerInn']); 3r33338. $ stmt-> bindParam (': payerAccount', $ tinkoff_array[$i] ['payerAccount']); 3r33338. $ stmt-> bindParam (': payerCorrAccount', $ tinkoff_array[$i] ['payerCorrAccount']); 3r33338. $ stmt-> bindParam (': payerBic', $ tinkoff_array[$i] ['payerBic']); 3r33338. $ stmt-> bindParam (': payerBank', $ tinkoff_array[$i] ['payerBank']); 3r33338. $ stmt-> bindParam (': chargeDate', $ tinkoff_array[$i] ['chargeDate']); 3r33338. $ stmt-> bindParam (': recipient', $ tinkoff_array[$i] ['recipient']); 3r33338. $ stmt-> bindParam (': recipientInn', $ tinkoff_array[$i] ['recipientInn']); 3r33338. $ stmt-> bindParam (': recipientAccount', $ tinkoff_array[$i] ['recipientAccount']); 3r33338. $ stmt-> bindParam (': recipientCorrAccount', $ tinkoff_array[$i] ['recipientCorrAccount']); 3r33338. $ stmt-> bindParam (': recipientBic', $ tinkoff_array[$i] ['recipientBic']); 3r33338. $ stmt-> bindParam (': recipientBank', $ tinkoff_array[$i] ['recipientBank']); 3r33338. $ stmt-> bindParam (': operationType', $ tinkoff_array[$i] ['operationType']); 3r33338. $ stmt-> bindParam (': uin', $ tinkoff_array[$i] ['uin']); 3r33338. $ stmt-> bindParam (': paymentPurpose', $ tinkoff_array[$i] ['paymentPurpose']); 3r33338. $ stmt-> bindParam (': creatorStatus', $ tinkoff_array[$i] ['creatorStatus']); 3r33338. $ stmt-> bindParam (': payerKpp', $ tinkoff_array[$i] ['payerKpp']); 3r33338. $ stmt-> bindParam (': executionOrder', $ tinkoff_array[$i] ['executionOrder']); 3r33338. $ stmt-> execute (); 3r33338.}
}
}
}
 3r33338. Readers: I hope this material will help in the monetization of your web services and services of your customers. May the force be with you!
 3r33338.
 3r33338. To the guys from technical support of Bank Tinkoff: I hope this article will reduce the load on you! Good luck!
3r33338. 3r33338. 3r33338.
3r33338.
3r33338. 3r33338. 3r33338. 3r33338.
API / PHP
+ 0 -

Add comment