获取“我的客户中心”费用统计信息:Tinkoff和Rocketbank


引言


MCC (商家类别代码)-银行卡操作中使用的商家类别代码。 银行根据此代码确定客户购买了哪种产品。 这取决于他是否会向您收取现金返还,佣金或取消宽限期。


在一个世纪中,公司从用户收集的数据中获利的时候,不采取相反的做法是一个罪过:使用公司收集的有关自己的数据,这样一来,即使您没有从中获利,也至少可以省钱。


知道您在每个“我的客户中心”代码上花了多少钱,就可以计算出哪张银行卡会带来很多好处。 因此,如果您有足够的时间使用了Tinkoff或Rocketbank卡,则本文将很方便地获取每个MCC支出的统计信息。


廷科夫


当您单击Tinkoff银行的个人帐户时,它会显示MCC操作。



这样您可以看到很多操作,但是如果我们需要在使用卡的整个过程中收集统计信息,则这种情况应该是自动化的。 让我们尝试以便于软件处理的形式获取数据。


UPD:如Smasher所述,您的个人帐户可以上传CSV或Excel格式的所有操作。 因此,在扰流板下是对我如何做的描述,却一无所知。



努力前进

这将需要浏览器开发工具,尤其是网络活动分析(Google Chrome中的“网络”标签)。 如果您打开分析仪,然后要求您的个人帐户显示“ For All Time”操作,那么我们将快速找到所需的请求。



您会注意到,服务器一直一直在提供数据,并且所需的MCC出现在JSON响应中。



为了方便数据处理,请在Python中模拟一个请求。 我正在使用Jupyter笔记本



我们将向URL https://api.tinkoff.ru/v1/grouped_requests发送POST请求,并使用相同的sessionid_methods参数以及requestsData数据。


import requests session_id = "b785Q2R5US2AZo2p5JoCtNQNkbmYsJbl.ds-api02" methods = "operations" #     , payments   params = {'sessionid': session_id, '_methods': methods} #      requestsData   requests_data = '[{"key":0,"operation":"operations","params":{"wuid":"28a44beaeee7460b94dbdd0aa0dc935a","account":"5059373083","start":1136062800000,"end":1529269199999}}]' data = {'requestsData': requests_data} response = requests.post('https://api.tinkoff.ru/v1/grouped_requests', params=params, data=data) 

如果我们做对了所有事情,那么在控制台中输入response.text将显示响应主体。 仍然需要解析此数据并保存我们需要的片段。


 import csv operations = [] payload = response.json()['payload'] for key in payload: feed = payload[key]['payload'] for operation in feed: mcc = operation['mcc'] # MCC   < 100         if (mcc > 100): #     ,    if 'merchant' in operation: merchant_name = operation['merchant']['name'] else: merchant_name = operation['description'] #  accountAmount     «»  cost = operation['accountAmount']['value'] operations.append((mcc, cost, merchant_name)) print(mcc, cost, merchant_name) #    csv output = open("tinkoff.csv",'w') wr = csv.writer(output) for item in operations: wr.writerow(item) 

在输出中,我们得到一个MCC代码,购买成本和商店名称的表。


火箭银行


Rocketbank会在收据上显示MCC交易。 因此,我们需要收集所有操作收据的链接。



使用Rocketbank会稍微复杂一点,因为只有通过移动应用程序才能访问您的个人帐户。 我只会讲什么对我有用,也只会讲Android。 在计算机上安装Charles分析仪,并通过它传递电话流量。


为此,电话和计算机必须连接到同一网络。 您将需要找出本地网络上计算机的IP。 例如,使用ifconfig


接下来,配置电话以通过Charles代理服务器工作。 在Android 7.0中,长按连接的网络即可在Wi-Fi设置中完成此操作。 指定计算机的IP和端口8888,默认为Charles。



不用说,Rocketbank应用程序在与服务器交互时会使用TLS,我们将无法像这样监听流量。 Charles通过替换TLS证书来支持流量拦截,即,它实现了MITM攻击。 但是,为此,设备必须信任Charles根证书。


当您从启用了代理的移动设备上单击链接https://chls.pro/ssl时,将安装Charles根证书。 另外,您需要在代理-> SSL代理设置中将rocketbank.ru添加到代理主机的列表中。



但这还不够,因为默认情况下,在Android 7.0中,应用程序不信任用户证书颁发机构。 安全! 该应用程序必须经过适当的许可才能编译。 有障碍吗 没有一次。 我们根据需要反编译。


首先,我们从电话中获取应用程序包。 可以使用Android调试桥Apk提取器应用程序来完成。 Android 7.0上的第一种方法对我不起作用,第二种方法可以完成任务。


我们将软件包带到计算机并使用apktool进行反编译。


 apktool d rocket.apk 

您必须沿路径res / xml / network_security_config.xml添加网络安全配置文件。 您可以在此处阅读有关配置文件格式的更多信息,但是以下设置对我们来说足够了:


 <network-security-config> <base-config> <trust-anchors> <!-- Always trust user added CAs --> <certificates src="user" /> </trust-anchors> </base-config> </network-security-config> 

必须通过在应用程序清单(根中为AndroidManifest.xml)中指定android:networkSecurityConfig参数,以在应用程序清单中指定此配置文件。


 <application android:networkSecurityConfig="@xml/network_security_config" android:allowBackup="false" ...>...</application> 

现在编译。


 apktool b rocket 

由于未安装未签名的应用程序,因此仍然需要对应用程序进行签名。 为此,我们使用带有内置测试证书的签名程序


 java -jar sign.jar rocket.apk 

从手机上删除原始的Rocketbank应用程序,将修改后的程序包复制到手机上并进行安装(例如,通过“文件”应用程序)。


现在,在Charles中进行流量拦截应该可以了。 打开Rocketbank应用程序,登录并查看Charles。 这是收据的链接。



让我们回到Python并模拟此GET请求,只是不要在上面浪费时间,而是要求服务器向我们提供有关所有操作的数据。 好吧,或者至少是关于第一个999999。


 token = 'c8ccb54b-09e3-4608-a5b4-7914a92c21f3206582' params = {'token': token, 'page': 1, 'per_page': 999999} 

通过实验发现,只有将正确的x-device-idx-timex-sig与令牌一起发送时,服务器才会信任会话。 我们不会后悔,因为我们不必发明和计算任何东西,只需复制它即可。


 x_device_id = 'ANDROID_C6FBB57CD433E756_899EE771-4AC5-46ED-44A1-656CE47A417B' x_time = '1529194008' x_sig = 'c486365013ddebe8b7f4599afbf73d26' headers = {'x-device-id': x_device_id, 'x-time': x_time, 'x-sig': x_sig} response = requests.get('https://rocketbank.ru/api/v5/operations/sexy_feed', params=params, headers=headers) 

定期将MCC从收据中取出。 我们仔细检查一下操作,阅读收据,按常规时间表运行,然后将所需的一切都放在口袋里。


 import re regex = re.compile('MCC:</dt><.+?>(\d+)</dd>') operations = [] feed = response.json()['feed'] for item in feed: if item[0] == 'operation': operation = item[1] merchant_name = operation['merchant']['name'] receipt_url = operation['receipt_url'] cost = operation['money']['amount'] #    if cost < 0: receipt = requests.get(receipt_url) match = regex.search(receipt.text) if match is not None: mcc = match[1] operations.append((mcc, -cost, merchant_name)) print(mcc, -cost, merchant_name) else: #  MCC  ,      , #        MCC operations.append((merchant_name, -cost)) print(merchant_name, -cost) output = open("rocket.csv",'w') wr = csv.writer(output) for item in operations: wr.writerow(item) 

也许您可以删除修改后的应用程序,然后再安装原来的应用程序。


合计


通过合并来自两个银行的数据,通过MCC使用数据透视表对操作进行分组,从转账和现金提取中手动清除数据,并将它们分组到类似的类别中,我得到了以下图片:



现在,使用像mcc-codes.ru这样的服务,您可以为最昂贵的类别挑选现金返还增加的卡。 并且,将可能的现金返还金额与年度维护成本相关联,确定是否建议草拟特定的卡。


这有什么好处? 用我的花销和正确的选择卡,我每年可以节省1万卢布。 值得吗? 您决定:)

Source: https://habr.com/ru/post/zh-CN414349/


All Articles