Configuration de l'API Tinkoff Bank. Comment est votre intuition ....? Ou une chanson sur Oauth 2.0

Il y a quelques semaines, dans l'un des projets, la question s'est posée d'intégrer le CRM à l'API Tinkoff Bank. Il s'agissait en particulier d'obtenir un relevé de compte bancaire.

L'actif avait:

  1. openapi.tinkoff.ru
  2. Service d'assistance téléphonique (compte tenu de l'activité du service d'assistance technique - la tâche de sauver l'homme qui se noie, le travail manuel de l'homme qui se noie)
  3. Document googlé : 24386_policy.pdf (avec des lettres russes à l'intérieur, avec des expressions amusantes, des tours de sorcellerie, inadaptés mais, néanmoins, une chose ...)

Au cours de la boîte de google, des critiques ont également révélé que la mise en place de l'API Tinkoff Bank est très divertissante et non triviale (voir l'article sur banki.ru "API Tinkoff - nous sommes trop stupides pour cela" ).

Oui, j'ai dû bricoler un peu, donc, afin de gagner du temps pour les autres camarades de l'atelier, cet article a été écrit.

Je note que l'API Tinkoff Bank utilise Oauth 2.0 pour l'autorisation.

Pourquoi avons-nous besoin de openapi.tinkoff.ru?

  1. pour le test (voir ci-dessous);
  2. afin de deviner ce qui est quoi et comment; il n'y a pas d'attelle directe; Nous travaillons au niveau de l'intuition! ...

Commençons. Dans la section «SSO Authorization», cliquez sur «how / Hide» puis sur / secure / token # refresh-token («émission d'un token par refresh token»), sélectionnez grant_type comme paramètre, puis dans le champ refresh_token (vous pouvez l'obtenir dans Compte utilisateur). Cliquez sur le bouton "Essayez-le!" Le résultat de ces actions est d'obtenir une chose aussi importante que access_token (c'est-à-dire que openapi.tinkoff.ru démontre la possibilité de la recevoir).

Ensuite, regardez la section "Comptes et paiements", cliquez sur / partenaire / entreprise / {INN} / extrait ("Réception du relevé"). Nous étudions les paramètres nécessaires pour l'obtenir: Authorization, INN, accountNumber, from, till.

Autorisation - nous supposons que l'autorisation n'est rien de plus que access_token, qui a été reçue par nous dans la section "Autorisation SSO";
INN - INN de l'organisation pour laquelle nous configurons l'API;
à partir de - à partir de quel jour (période de sortie);
jusqu'à - quel jour (période de décharge).

Ainsi (nous regardons le matériel Oauth 2.0), l' obtention des données d'instruction se déroule en deux étapes - d'abord nous obtenons access_token, puis ayant access_token sous la main, nous obtenons les données pour cette instruction . Super. L'algorithme est clair, nous écrivons le code (les paramètres d'accès dans les valeurs de code pour $ user, $ pass, $ refresh_token, $ inn, $ accountNumber - dans le code ci-dessous sont modifiés, pour des raisons évidentes).

Créez les fichiers suivants:

  1. Le premier fichier de paramètres est StartSettings.php
  2. Le deuxième fichier de démarrage est Start.php
  3. Le troisième fichier de publication / analyse des données vers / depuis l'API est TinkoffInsertData.php ; nous utilisons CURL (php).
  4. Un vidage de base de données vide où vous pouvez télécharger les données de vos relevés: bank.sql ; Base de données MySQL (nous envoyons des données à la base de données via PDO).

Alors, regardez le code et ses commentaires!

Fichier de paramètres - StartSettings.php:

$host = '127.0.0.1'; $db = 'bank'; $user = 'root'; $pass = ''; $charset = 'utf8'; $dsn = "mysql:host=$host;dbname=$db;charset=$charset"; $opt = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; $pdo = new PDO($dsn, $user, $pass, $opt); $user="IKu0jn98kllkI90kklii"; //20  $pass="ds4234SDFsdfsdijoijslkkdjfoIOi"; //30  $refresh_token='dsfh345kljlkjsdf098sdfkljklj098sdfkklKKLjhjihiKL90909llkrre5345dfFDDFretertERTERETfdgd==';// 88  $inn = '750151513135'; $accountNumber = '40802810300000121212';//20  $from_year = '1980'; $from_month = '01'; $from_day = '01'; $till_year = date('Y'); $till_month = date('m'); $till_day = date('d'); 

Fichier de démarrage - Start.php:

 session_start(); error_reporting(E_ALL); include 'StartSettings.php'; include 'TinkoffInsertData.php'; TinkoffInsertData($user,$pass,$refresh_token, $inn, $accountNumber, $from_year, $from_month, $from_day, $till_year, $till_month, $till_day, $pdo); $stmt = $pdo->prepare("INSERT INTO `bank`.`dateofwork` (dateofwork) VALUES (NOW())"); $stmt->execute(); 

Fichier pour publier / analyser des données vers / depuis l'API - TinkoffInsertData.php:

 function TinkoffInsertData($user,$pass,$refresh_token, $inn, $accountNumber, $from_year, $from_month, $from_day, $till_year, $till_month, $till_day, $pdo){ //  -    access_token $from_date = $from_year."-".$from_month."-".$from_day.'%2B03%3A00%3A00'; $till_date = $till_year."-".$till_month."-".$till_day.'%2B03%3A00%3A00'; $params=['grant_type'=>'refresh_token', 'refresh_token'=>$refresh_token ]; $headers = [ 'POST /secure/token HTTP/1.1', 'Content-Type: application/x-www-form-urlencoded' ]; $curlURL='https://sso.tinkoff.ru/secure/token'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$curlURL); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $pass); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($params)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); $curl_res = curl_exec($ch); if($curl_res) { $server_output = json_decode($curl_res); } // access_token -     2  $access_token_pos_start = strpos ($curl_res, 'access_token', 0); $access_token_pos_start = $access_token_pos_start + 15; $token_type_pos_start = strpos ($curl_res, "token_type", 0); $access_token = mb_substr($curl_res, $access_token_pos_start, ($token_type_pos_start-$access_token_pos_start-3)); //!....   ..... // ,    sleep,        //sleep(1); //  -     $params=[ 'Authorization'=>$access_token, 'INN'=>$inn, 'accountNumber'=>$accountNumber ]; $headers = [ 'Authorization: Bearer '.$access_token ]; $curlURL='https://sme-partner.tinkoff.ru/api/v1/partner/company/'.$inn.'/excerpt?accountNumber='.$accountNumber.'&from='.$from_date.'&till='.$till_date; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$curlURL); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $pass); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_POST, false); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($params)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); $curl_res = curl_exec($ch); if($curl_res) { $server_output = json_decode($curl_res); } $IE_Edge_pos_start = strpos ($curl_res, 'IE=Edge', 0); $IE_Edge_pos_start = $IE_Edge_pos_start + 7; $tinkoff_json = mb_substr($curl_res, $IE_Edge_pos_start); $tinkoff_json = trim($tinkoff_json); $tinkoff_json = json_decode($tinkoff_json); //     ,  ;) foreach ($tinkoff_json as $k=>$v){ if($k=='accountNumber'){ if(!($v==$accountNumber)) die('not that accountNumber'); } } //$tinkoff_array -    json   foreach ($tinkoff_json as $k=>$v){ if($k=='operation'){ $i=0; foreach ($v as $t=>$s){ foreach ($s as $e=>$f){ $tinkoff_array[$i][$e]=$f; } $i++; } } } //   $tinkoff_array    for ($i=0;$i<count($tinkoff_array);$i++){ $temp_id = $pdo->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]['paymentPurpose'])!=""){ $stmt = $pdo->prepare("INSERT INTO `justtin`.`tinkoff` (id, date, amount, drawDate, payerName, payerInn, payerAccount, payerCorrAccount, payerBic, payerBank, chargeDate, recipient, recipientInn, recipientAccount, recipientCorrAccount, recipientBic, recipientBank, operationType, uin, paymentPurpose, creatorStatus, payerKpp, executionOrder, date_of_save) VALUES (:id, :date, :amount, :drawDate, :payerName, :payerInn, :payerAccount, :payerCorrAccount, :payerBic, :payerBank, :chargeDate, :recipient, :recipientInn, :recipientAccount, :recipientCorrAccount, :recipientBic, :recipientBank, :operationType, :uin, :paymentPurpose, :creatorStatus, :payerKpp, :executionOrder, NOW())"); $stmt->bindParam(':id', $tinkoff_array[$i]['id']); $stmt->bindParam(':date', $tinkoff_array[$i]['date']); $stmt->bindParam(':amount', $tinkoff_array[$i]['amount']); $stmt->bindParam(':drawDate', $tinkoff_array[$i]['drawDate']); $stmt->bindParam(':payerName', $tinkoff_array[$i]['payerName']); $stmt->bindParam(':payerInn', $tinkoff_array[$i]['payerInn']); $stmt->bindParam(':payerAccount', $tinkoff_array[$i]['payerAccount']); $stmt->bindParam(':payerCorrAccount', $tinkoff_array[$i]['payerCorrAccount']); $stmt->bindParam(':payerBic', $tinkoff_array[$i]['payerBic']); $stmt->bindParam(':payerBank', $tinkoff_array[$i]['payerBank']); $stmt->bindParam(':chargeDate', $tinkoff_array[$i]['chargeDate']); $stmt->bindParam(':recipient', $tinkoff_array[$i]['recipient']); $stmt->bindParam(':recipientInn', $tinkoff_array[$i]['recipientInn']); $stmt->bindParam(':recipientAccount', $tinkoff_array[$i]['recipientAccount']); $stmt->bindParam(':recipientCorrAccount', $tinkoff_array[$i]['recipientCorrAccount']); $stmt->bindParam(':recipientBic', $tinkoff_array[$i]['recipientBic']); $stmt->bindParam(':recipientBank', $tinkoff_array[$i]['recipientBank']); $stmt->bindParam(':operationType', $tinkoff_array[$i]['operationType']); $stmt->bindParam(':uin', $tinkoff_array[$i]['uin']); $stmt->bindParam(':paymentPurpose', $tinkoff_array[$i]['paymentPurpose']); $stmt->bindParam(':creatorStatus', $tinkoff_array[$i]['creatorStatus']); $stmt->bindParam(':payerKpp', $tinkoff_array[$i]['payerKpp']); $stmt->bindParam(':executionOrder', $tinkoff_array[$i]['executionOrder']); $stmt->execute(); } } } } 

Lecteurs: J'espère que ce matériel vous aidera à monétiser vos services Web et les services de vos clients. Que la force vienne avec vous!

Les gars du support technique de Tinkoff Bank: j'espère que cet article vous réduira la charge! Bonne chance

Source: https://habr.com/ru/post/fr431908/


All Articles