Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf-8 -*-
- from .base import BankModule
- from .exceptions import *
- import requests
- import datetime
- import urllib
- import time
- import json
- import re
- class TMB(BankModule):
- name = 'TMB'
- default_version = 3.0
- default_days = 2
- build = 1004
- TMB_APP_VER = '1.0.12.30'
- auto_add_account = 'autoAddAccount'
- sub_add_account = 'subAddAccount'
- WEBSITE = 'https://www.tmbdirect.com' # For test
- def __init__(self, logger=None):
- super(self.__class__, self).__init__(logger=logger)
- self.session = requests.Session()
- self.session.verify = False # TODO: Dev only
- self.TIMEOUT = None # TODO: Dev only
- self._domain = 'https://www.tmbdirect.com'
- self._landing_path = '/tmb/kdw1.7.5'
- self._home_url = 'https://www.tmbdirect.com/tmb/kdw1.7.5'
- self._url = 'https://www.tmbdirect.com/tmb/MWServlet'
- self._campaign_url = 'https://www.tmbdirect.com/services/TMBMIBService0/GetCampaign'
- self._login_url = 'https://www.tmbdirect.com/services/TMBMIBService9/IBVerifyLoginEligibility'
- self._customer_account_inquiry_url = 'https://www.tmbdirect.com/services/TMBMIBService5/customerAccountInquiry'
- self._calendar_inquiry_url = 'https://www.tmbdirect.com/services/TMBMIBService0/CalendarInquiry'
- self._logout_url = 'https://www.tmbdirect.com/services/TMBMIBService0/logOutTMB'
- self._service_form = {
- 'appID': 'TMB',
- 'appver': self.TMB_APP_VER,
- 'locale': 'th_TH',
- 'channel': 'wap',
- 'platform': 'thinclient',
- 'cacheid': '',
- 'rcid': 'spadesktopweb',
- }
- self._useragent = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'
- self.session.headers.update({'User-Agent': self._useragent})
- self.auto_add_account_filter = self.auto_add_account[:13]
- self.tknid = None
- def get_all_transactions(self):
- logger = self.logger.add_tag('get_all_transactions')
- self.accounts = []
- data = dict()
- today = datetime.date.today()
- query_date = []
- if (today - datetime.timedelta(days=1)).month != today.month: # Between month
- date_from = today - datetime.timedelta(days=2)
- date_to = date_from + datetime.timedelta(days=1)
- query_date.append((date_from, date_to))
- date_from = today
- date_to = today
- query_date.append((date_from, date_to))
- else:
- date_from = today - datetime.timedelta(days=1)
- date_to = today
- query_date.append((date_from, date_to))
- for date_from, date_to in query_date:
- today_str = date_to.strftime('%d.%m.%Y')
- yesterday_str = date_from.strftime('%d.%m.%Y')
- data.update(self._service_form)
- data.update({
- 'serviceID': 'CalendarInquiry',
- 'tknid': self.tknid,
- 'reloadFlag': '1',
- 'accountDetailsFromLink': '',
- 'bankCd': '11',
- 'startDate': yesterday_str,
- 'endDate': today_str,
- })
- r = self.web_post(self._calendar_inquiry_url, data=data, soup=False)
- logger.debug(msg='Get CalendarInquiry page.', attachment=r)
- result = json.loads(r)
- # today_date_str = result['todayDate']
- self.tknid = result['tknid']
- for key, val in result.items():
- if key.startswith('0000'):
- account_exists = [x for x in self.accounts if x['account_no'] == key]
- if account_exists:
- account = account_exists[0]
- else:
- account = dict(name='acc_name', statements=[], account_no=key)
- self.accounts.append(account)
- for statement in val:
- ref_id = statement['finTxnRefID']
- txt_date = statement['txnDate']
- txt_time = statement['txnTime']
- amount = self.parse_float_or_none(statement['finTxnAmount'])
- from_id = statement['fromAcctID']
- to_acct = None
- if 'toAcctNickname' in statement and statement['toAcctNickname']:
- to_acct = statement['toAcctNickname']
- description = statement['txnDescription']
- channel = None
- translate_channels = (
- ('via Mobile', 'MOB'),
- ('via Internet', 'IB'),
- ('via TMB ATM', 'ATM'),
- ('via KBANK ATM', 'ATM'),
- ('via SCB ATM', 'ATM'),
- ('via BAAC ATM', 'ATM'),
- ('via BBL ATM', 'ATM'),
- ('via KTB ATM', 'ATM'),
- ('via KBANK', 'IB'),
- ('via SCB', 'IB'),
- ('via KTB', 'IB'),
- ('via BBL', 'IB'),
- ('via BAAC', 'IB'),
- )
- for keyword, value in translate_channels:
- if keyword in description:
- channel = value
- break
- if not amount:
- revert_desc = description[::-1]
- try:
- revert_index = revert_desc.index('t\\')
- except ValueError:
- revert_index = None
- if revert_index:
- revert_desc = revert_desc[:revert_index]
- amount_desc = revert_desc[::-1]
- else:
- amount_desc = description
- # KARAT 2 150.00 ฿ must result 150.00
- re_match = re.search(r'(?P<amount>[0-9.]+) ฿', amount_desc)
- if re_match:
- amount = self.parse_float_or_none(re_match.group('amount'))
- else:
- amount = self.parse_float_or_none(''.join([x for x in amount_desc if x in '0123456789.']))
- if not amount:
- raise PluginError('Cannot parse Amount on TMB! (get "" even finTxnAmount and txnDescription)')
- if not to_acct:
- method = 'DP'
- deposit = amount
- withdraw = None
- ref_id = 'DP {} {} {}'.format(from_id, txt_date, txt_time)
- elif to_acct:
- method = 'WD'
- withdraw = amount
- deposit = None
- date_time_str = '{} {}'.format(txt_date, txt_time)
- date_object = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
- account['statements'].append(dict(date_str=date_time_str, create_on=date_object, desc=description, withdraw=withdraw, deposit=deposit, balance=None, channel=channel, method=method, log=ref_id))
- return self.accounts
- def pre_login(self):
- logger = self.logger.add_tag('pre_login')
- self.accounts = []
- # GET Website and parse kdw version
- r = self.http_get(self.WEBSITE)
- logger.debug(msg='GET Pre home page.', attachment=r.text)
- re_kdw = re.search(r'(?P<kdw>https://www\.tmbdirect\.com/tmb/kdw\d+\.\d+\.\d+)', r.text)
- if not re_kdw:
- raise PluginHandledError('Unhandle Login Page (Might be kdw version changed).')
- kdw_url = re_kdw.group('kdw')
- # GET home page and parse TMB APP VERSION
- r = self.http_get(kdw_url)
- logger.debug(msg='GET home page.', attachment=r.text)
- if '$KG["version"] = "1.0.' in r.text:
- re_result = re.search(r'\$KG\[\"version\"\] = \"(?P<version>[0-9.]+)\"', r.text)
- if self.TMB_APP_VER != re_result.group('version'):
- logger.warning(msg='TMB version has change from %s to %s (Please contact developer team.)' % (self.TMB_APP_VER, re_result.group('version')))
- self.TMB_APP_VER = re_result.group('version')
- logger.debug(msg='TMB version %s' % self.TMB_APP_VER)
- self._service_form['appver'] = self.TMB_APP_VER
- '''
- Kony App Key, Secret
- '''
- kony_app_key = 'ae8cd4fb292a12727a4833c9fdb8ccb0'
- kony_app_secret = '9bca06a1518df6af31382131cd911009'
- config_url = 'https://www.tmbdirect.com/authService/100000004/appconfig'
- login_url = 'https://www.tmbdirect.com/authService/100000004/login'
- headers = {
- 'Content-Type': 'application/json',
- 'X-HTTP-Method-Override': 'GET',
- 'X-Kony-App-Key': kony_app_key,
- 'X-Kony-App-Secret': kony_app_secret,
- }
- r = self.http_post(config_url, data='ltrim=function%20()%7Breturn%20this.replace(%2F%5E%5Cs%2B%2F%2C%22%22)%7D&rtrim=function%20()%7Breturn%20this.replace(%2F%5Cs%2B%24%2F%2C%22%22)%7D', headers=headers)
- logger.debug(msg='GET kony config.', attachment=r.text)
- r_json = r.json()
- self.mfbaseid = r_json['baseId']
- self.appid = r_json['appId']
- headers = {
- 'X-Kony-App-Key': kony_app_key,
- 'X-Kony-App-Secret': kony_app_secret,
- }
- r = self.http_post(login_url, data={}, headers=headers)
- r_json = r.json()
- kony_token = r_json['claims_token']['value']
- self.session.headers.update({
- 'X-Kony-Authorization': kony_token,
- })
- logger.debug(msg='GET kony authorization.', attachment=kony_token)
- data = self._craft_data({
- 'events': '[]',
- 'timestamp': '',
- 'localeId': '',
- 'platform1': 'D',
- 'serviceID': 'getPhrases',
- 'app_name': 'TMBUI',
- 'widgetName': 'segCampaignImage',
- 'formName': 'frmIBPreLogin',
- 'appChannel': 'I',
- 'prelogin': 'Y',
- 'tknid': '',
- 'httpheaders': '{}',
- 'httpconfig': '{"timeout":180000}',
- })
- r = self.http_post(self.get_service_url('getPhrases'), data=data)
- logger.debug(msg='GET pre login prases.', attachment=r.text)
- # GET tknid
- data = self._craft_data({
- 'events': '[]',
- 'serviceID': 'GetCampaign',
- 'app_name': 'TMBUI',
- 'widgetName': 'segCampaignImage',
- 'formName': 'frmIBPreLogin',
- 'appChannel': 'I',
- 'prelogin': 'Y',
- 'tknid': '',
- 'httpheaders': '{}',
- 'httpconfig': '{"timeout":180000}',
- })
- r = self.http_post(self.get_service_url('GetCampaign'), data=data) # , cookies=cookies)
- logger.debug(msg='GET pre login.', attachment=r.text)
- result = r.json()
- self.tknid = result['tknid']
- def login(self, username, password):
- logger = self.logger.add_tag('login')
- self.pre_login()
- logger.info('Loggin with user="%s" appver="%s"' % (username, self.TMB_APP_VER))
- data = dict(loginId=username, userid=username, password=password)
- data.update({
- 'events': '[]',
- 'appID': 'TMB',
- 'appver': self.TMB_APP_VER,
- 'serviceID': 'IBVerifyLoginEligibility',
- 'locale': 'th_TH',
- 'channel': 'wap',
- 'platform': 'thinclient',
- 'cacheid': '',
- 'tknid': self.tknid,
- 'rcid': 'spadesktopweb',
- })
- r = self.http_post(self.get_service_url('IBVerifyLoginEligibility'), data=data)
- raw_result = r.text
- logger.debug(msg='POST Login page.', attachment=raw_result)
- if r.status_code >= 500: # 500 Internal Server Error
- raise PluginHandledError('Unhandle Login result (Might be version changed or captcha).')
- result = r.json()
- if 'httpStatusCode' not in result:
- logger.error(msg='Unhandle Login result (Might be version changed or captcha).', attachment=result)
- errmsg = result['errmsg'] if 'errmsg' in result else ''
- if result.get('captchaCode') == '1':
- raise PluginHandledError('Login Failed, Captcha detected.')
- raise Exception(u'Unhandle Login result (Might be version changed or captcha). (errmsg=%s)' % errmsg)
- if result['httpStatusCode'] == 500:
- if 'loginattemptcountint' in result:
- raise LoginError('Incorrect password')
- else:
- raise LoginInused('Login currenly in used.')
- self.tknid = result['tknid']
- data = self._craft_data({
- 'serviceID': 'customerAccountInquiry',
- 'activationCompleteFlag': 'true',
- 'upgradeSkip': '',
- 'cacheid': '',
- })
- r = self.http_post(self.get_service_url('customerAccountInquiry'), data)
- logger.info(msg='Login activated page', attachment=r.text)
- return True
- def transactions(self, account_no):
- if not self.accounts:
- self.get_all_transactions()
- account_no = account_no.replace('-', '')
- seen_account = [x['account_no'] for x in self.accounts]
- for account in self.accounts:
- acc_no = account['account_no']
- if str('0000' + account_no) == str(acc_no):
- return account['statements']
- return []
- # raise PluginError('Account %s not found, available %s ' % (account_no, seen_account))
- def balances(self):
- logger = self.logger.add_tag('balances')
- '''
- เปิดหน้าโอน
- '''
- data = self._craft_data({
- 'serviceID': 'customerAccountInquiry',
- # 'transferFlag': 'true',
- })
- r = self.http_post(self._customer_account_inquiry_url, data)
- logger.info(msg='Transfer(balance) page', attachment=r.text)
- result = r.json()
- all_acc = result['custAcctRec']
- data = []
- for account_rec in all_acc:
- account_no = account_rec['accId'][4:] # Trim 4 ตัวแรกทิ้ง
- status = account_rec['acctStatus']
- status = status[0:7]
- ledger_balance = self.parse_float_or_none(account_rec['ledgerBal'])
- balance = self.parse_float_or_none(account_rec['availableBal'])
- if status == 'Active ':
- ledger_balance = ledger_balance
- balance = ledger_balance
- elif status == 'Dormant':
- ledger_balance = ledger_balance
- balance = 0 # Dormant only
- else:
- raise Exception('Unhandled status.')
- data_row = {
- 'account_no': account_no,
- 'balance': balance, # 0 ถ่าโดนอายัด
- 'ledger_balance': ledger_balance,
- }
- data.append(data_row)
- return data
- def balance(self, account_no):
- from banktransfer.models import STATE_ADD_ENUM
- balances = self.balances()
- balances = [x for x in balances if x['account_no'] == account_no]
- if not balances:
- raise Exception('Account no %s not found.' % account_no)
- data = {
- '_balance': balances[0]['balance'],
- '_state_add': STATE_ADD_ENUM.WAIT_ADD,
- }
- return data
- def get_service_url(self, service_name):
- service_ids = {
- 'IBVerifyLoginEligibility': 9,
- 'customerAccountInquiry': 5,
- 'depositAccountInquiry': 7,
- 'debitCardInq': 5,
- 'crmProfileInq': 5,
- 'depositAccountInquiryNonSec': 7,
- 'fundTransferInq': 5,
- 'generateOTPWithUser': 14,
- }
- return 'https://www.tmbdirect.com/services/TMBMIBService%s/%s' % (service_ids.get(service_name, 0), service_name)
- def pre_add_account(self, account_no, account_name='', branch_name='', mobile_no='', email='', task=None, amount=None, from_account_no=None):
- from banktransfer.models import STATE_ADD_ENUM
- logger = self.logger.add_tag('pre_add_account')
- '''
- เปิดหน้าโอน
- '''
- data = self._craft_data({
- 'serviceID': 'customerAccountInquiry',
- 'transferFlag': 'true',
- })
- r = self.http_post(self._customer_account_inquiry_url, data)
- logger.info(msg='pre_add_account page1', attachment=r.text)
- result = r.json()
- self._save_session(result)
- found = False
- found_accounts = []
- use_product_id = None
- for account_rec in result['custAcctRec']:
- account_id = account_rec['accId'][4:] # Trim 4 ตัวแรกทิ้ง
- product_id = account_rec['productID']
- if from_account_no == account_id:
- use_product_id = product_id
- found_accounts.append((account_id, product_id))
- if not use_product_id: # Not found, use fake
- from_account_no, use_product_id = found_accounts[0]
- '''
- เปิดผู้รับโอน
- '''
- data = self._craft_data({
- 'serviceID': 'receipentgetBankService',
- })
- url = 'https://www.tmbdirect.com/services/TMBMIBService0/receipentgetBankService'
- r = self.http_post(url, data)
- logger.info(msg='pre_add_account page2', attachment=r.text)
- result = r.json()
- self._save_session(result)
- data = self._craft_data({
- 'serviceID': 'getRecipientsForTransfer',
- 'prodId': use_product_id,
- 'accId': from_account_no,
- })
- url = 'https://www.tmbdirect.com/services/TMBMIBService0/getRecipientsForTransfer'
- r = self.http_post(url, data)
- logger.info(msg='pre_add_account page3(data)', attachment=json.dumps(data))
- logger.info(msg='pre_add_account page3', attachment=r.text)
- result = r.json()
- self._save_session(result)
- found = False
- personalized_id = None
- for recepient in result['RecepientsList']:
- if recepient['personalizedName'] == self.auto_add_account:
- found = True
- personalized_id = recepient['personalizedId']
- if not found: # autoAddAccount Not found, create!
- data = self._craft_data({
- 'crmId': '',
- 'rqUUId': '',
- 'channelName': 'IB-INQ',
- 'serviceID': 'crmProfileInq',
- })
- url = 'https://www.tmbdirect.com/services/TMBMIBService5/crmProfileInq'
- r = self.http_post(url, data)
- logger.info(msg='pre_add_account (create account) page3.5', attachment=r.text)
- result = r.json()
- data = self._craft_data({
- 'crmId': '',
- 'rqUUId': '',
- 'channelName': 'IB-INQ',
- 'serviceID': 'crmProfileInq',
- })
- r = self.http_post(url, data)
- logger.info(msg='pre_add_account (create account) page4.5(2)', attachment=r.text)
- result = r.json()
- data = self._craft_data({
- 'serviceID': 'receipentgetBankService',
- })
- url = 'https://www.tmbdirect.com/services/TMBMIBService0/receipentgetBankService'
- r = self.http_post(url, data)
- logger.info(msg='pre_add_account getBankService', attachment=r.text)
- result = r.json()
- self._save_session(result)
- data = self._craft_data({
- 'serviceID': 'depositAccountInquiryNonSec',
- 'acctId': account_no,
- 'toAcctNo': account_no,
- 'isFromRecipient': 'yes',
- 'bankcode': '11', # TMB Only
- })
- url = 'https://www.tmbdirect.com/services/TMBMIBService7/depositAccountInquiryNonSec'
- r = self.http_post(url, data)
- logger.info(msg='pre_add_account depositAccountInquiryNonSec', attachment=r.text)
- result = r.json()
- self._save_session(result)
- if 'accountTitle' not in result and result['errMsg'] == "Account is already present for customer's recipient": #
- data = {}
- data['_state_add'] = STATE_ADD_ENUM.SUCCESS # Already exists
- return data
- customer_name = result['accountTitle']
- time.sleep(1) # Input
- self._token_switching()
- time.sleep(1)
- ''' Add User '''
- acc_detail_msg = 'TMB(x%s)' % account_no[-4:]
- receipent_list = '%s,png,,,,Added,N' % self.auto_add_account
- personal_acc_list = u'000000000000000000000000000000,,11,%s,%s,Added,%s' % (account_no, self.sub_add_account, customer_name)
- data = self._craft_data({
- 'receipentList': receipent_list,
- 'personalizedAccList': personal_acc_list.encode('utf-8'),
- 'gblTransactionType': '3',
- 'flow': 'recipients',
- 'Channel': 'AddRecipient',
- 'AccDetailMsg': acc_detail_msg,
- 'userAccountName': self.auto_add_account_filter, # no t
- 'serviceID': 'saveAddAccountDetails',
- 'oldRcName': self.auto_add_account,
- 'oldRcEmail': '',
- 'oldRcmobile': '',
- 'oldFbId': '',
- })
- url = 'https://www.tmbdirect.com/services/TMBMIBService0/saveAddAccountDetails'
- r = self.http_post(url, data)
- logger.info(msg='pre_add_account (create account) page5(data)', attachment=json.dumps(data))
- logger.info(msg='pre_add_account (create account) page5', attachment=r.text)
- result = r.json()
- self._save_session(result)
- time.sleep(1)
- self._token_switching({
- 'crmId': '000000000000000000000000000000',
- })
- time.sleep(1)
- ''' Request OTP for Add User '''
- data = self._craft_data({
- 'retryCounterRequestOTP': '0',
- 'Channel': 'AddRecipient',
- 'AccDetailMsg': acc_detail_msg,
- 'userAccountName': self.auto_add_account_filter,
- 'serviceID': 'generateOTPWithUser',
- })
- r = self.http_post(self.get_service_url('generateOTPWithUser'), data)
- logger.info(msg='pre_add_account (create account) page6(data)', attachment=json.dumps(data))
- logger.info(msg='pre_add_account (create account) page6', attachment=r.text)
- result = r.json()
- self._save_session(result)
- if 'errCode' in result:
- raise Exception(result['errCode'])
- otp_ref = result['Collection1'][7]['ValueString']
- data = {}
- data['_customer_name'] = customer_name
- data['_state_add'] = STATE_ADD_ENUM.WAIT_INPUT_OTP
- data['_otp_ref'] = otp_ref
- data['_account_no'] = account_no
- data['_tmbflow'] = 'ADDACCOUNT'
- return data
- ''' Else, autoAddAccount already! '''
- ''' Add AccountNo '''
- data = self._craft_data({
- 'serviceID': 'depositAccountInquiryNonSec',
- 'acctId': account_no,
- 'toAcctNo': account_no,
- 'isFromRecipient': 'yes',
- 'bankcode': '11', # TMB Only
- })
- r = self.http_post(self.get_service_url('depositAccountInquiryNonSec'), data)
- logger.info(msg='pre_add_account (create account no) page8', attachment=r.text)
- result = r.json()
- self._save_session(result)
- if result['opstatus'] == 1:
- if "Account is already present for customer's recipient" in result['errMsg']:
- data = {}
- data['_state_add'] = STATE_ADD_ENUM.SUCCESS
- return data
- raise Exception('errMsg: %s' % result['errMsg'])
- customer_name = result['accountTitle']
- self._token_switching()
- acc_detail_msg = 'TMB(x%s)' % account_no[-4:]
- personal_acc_list = u'000000000000000000000000000000,%s,11,%s,%s,Added,%s' % (personalized_id, account_no, self.sub_add_account, customer_name)
- data = self._craft_data({
- 'serviceID': 'saveAddAccountDetails',
- 'personalizedAccList': personal_acc_list.encode('utf-8'),
- 'gblTransactionType': '4',
- 'oldRcName': self.auto_add_account,
- 'oldRcmobile': '',
- 'oldFbld': '',
- 'flow': 'recipients',
- 'Channel': 'EditRecipient',
- 'AccDetailMsg': acc_detail_msg,
- 'userAccountName': self.auto_add_account_filter,
- })
- r = self.http_post(self.get_service_url('saveAddAccountDetails'), data)
- logger.info(msg='pre_add_account (create account no) page9', attachment=r.text)
- result = r.json()
- self._save_session(result)
- self._token_switching({'crmId': '000000000000000000000000000000'})
- data = self._craft_data({
- 'serviceID': 'generateOTPWithUser',
- 'retryCounterRequestOTP': 0,
- 'Channel': 'EditRecipient',
- 'AccDetailMsg': acc_detail_msg,
- 'userAccountName': self.auto_add_account_filter,
- 'cacheid': '',
- 'httpconfig': '[object Object]',
- 'konyreportingparams': '{"plat":"windows","aid":"TMB","aver":"1.0.12.26","aname":"dev1_1.0.12.26_build191","did":"1450192634398-54ad-9631-2f27","os":"48","stype":"b2c","dm":"","ua":"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.41 Safari/537.36","chnl":"desktop","atype":"spa","fid":"frmIBMyReceipentsAddBankAccnt","kuid":"","rsid":"1450192669428-e517-7e10-a9e6","metrics":[]}',
- '': '',
- })
- r = self.http_post(self.get_service_url('generateOTPWithUser'), data)
- logger.info(msg='pre_add_account (create account no) page8', attachment=r.text)
- result = r.json()
- self._save_session(result)
- otp_ref = result['Collection1'][7]['ValueString']
- data = {}
- data['_customer_name'] = customer_name
- data['_state_add'] = STATE_ADD_ENUM.WAIT_INPUT_OTP
- data['_otp_ref'] = otp_ref
- data['_personalized_id'] = personalized_id
- data['_account_no'] = account_no
- data['_tmbflow'] = 'EDITACCOUNT'
- return data
- def post_add_account(self, params):
- from banktransfer.models import STATE_ADD_ENUM
- logger = self.logger.add_tag('post_add_account')
- if params['_tmbflow'] == 'ADDACCOUNT':
- personal_acc_list = u'000000000000000000000000000000,,11,%s,%s,Added,%s' % (params['_account_no'], self.sub_add_account, params['_customer_name'])
- data = self._craft_data({
- 'serviceID': 'ExecuteMyRecipientAddService',
- 'gblTokenSwitchFlag': 'false',
- 'password': params['otp'],
- 'retryCounterVerifyAccessPin': '0',
- 'retryCounterVerifyTransPwd': '0',
- 'retryCounterVerifyOTP': '0',
- 'receipentList': '%s,png,,,,Added,N' % self.auto_add_account,
- 'personalizedAccList': personal_acc_list.encode('utf-8'),
- 'gblTransactionType': '3',
- 'serviceFlow': 'recipientsComp',
- 'oldRcName': self.auto_add_account,
- 'oldRcEmail': '',
- 'oldRcmobile': '',
- 'oldFbId': '',
- 'productCode': '200',
- 'cacheid': '',
- })
- r = self.http_post(self.get_service_url('ExecuteMyRecipientAddService'), data)
- # logger.info(msg='post_add_account page1(data)', attachment=json.dumps(data))
- logger.info(msg='post_add_account page1', attachment=r.text)
- result = r.json()
- self._save_session(result)
- personalized_id = result['personalizedIdList'][0]['personalizedId']
- data = self._craft_data({
- 'serviceID': 'confirmPicUpload',
- 'tknid': self.tknid,
- 'crmId': '000000000000000000000000000000',
- 'personalizedId': personalized_id,
- })
- r = self.http_post(self.get_service_url('confirmPicUpload'), data)
- logger.info(msg='post_add_account page2(data)', attachment=json.dumps(data))
- logger.info(msg='post_add_account page2', attachment=r.text)
- result = r.json()
- self._save_session(result)
- if result['opstatus'] == 8005: # "User ID or Password is incorrect. Please try again.
- if result['errCode'] == 'VrfyOTPErr00001':
- logger.debug('Invalid OTP, try again.')
- data = {
- '_state_add': STATE_ADD_ENUM.WAIT_INPUT_OTP,
- '_customer_name': params['_customer_name'],
- '_otp_ref': params['_otp_ref'],
- '_personalized_id': params['_personalized_id'],
- '_account_no': params['_account_no'],
- }
- if '_tmbflow' in params:
- data['_tmbflow'] = params['_tmbflow']
- return data
- elif result['errCode'] == 'VrfyOTPErr00002':
- logger.error('UserID is temporary locked please call 1558')
- raise PluginError('UserID is temporary locked please call 1558')
- else:
- raise Exception('Unhandled Error')
- ''' go Add Account again '''
- data = {}
- data['_state_add'] = STATE_ADD_ENUM.SUCCESS # WAITING
- data['_otp_ref'] = ''
- return data
- elif params['_tmbflow'] == 'EDITACCOUNT':
- personal_acc_list = '000000000000000000000000000000,%s,11,%s,%s,Added,%s' % (params['_personalized_id'], params['_account_no'], self.sub_add_account, params['_customer_name'])
- data = self._craft_data({
- 'serviceID': 'ExecuteMyRecipientAddService',
- 'gblTokenSwitchFlag': 'false',
- 'password': params['otp'],
- 'retryCounterVerifyAccessPin': '0',
- 'retryCounterVerifyTransPwd': '0',
- 'retryCounterVerifyOTP': '0',
- 'personalizedAccList': personal_acc_list.encode('utf-8'),
- 'gblTransactionType': '4',
- 'oldRcName': self.auto_add_account,
- 'oldRcmobile': '',
- 'oldRcEmail': '',
- 'oldFbld': '',
- 'serviceFlow': 'recipientsComp',
- 'productCode': '200',
- })
- r = self.http_post(self.get_service_url('ExecuteMyRecipientAddService'), data)
- logger.info(msg='post_add_account page1(data)', attachment=json.dumps(data))
- logger.info(msg='post_add_account page1', attachment=r.text)
- result = r.json()
- self._save_session(result)
- if result['opstatus'] == 8005: # "User ID or Password is incorrect. Please try again.
- if result['errCode'] == 'VrfyOTPErr00001':
- logger.debug('Invalid OTP, try again.')
- data = {
- '_state_add': STATE_ADD_ENUM.WAIT_INPUT_OTP,
- '_tmbflow': params['_tmbflow'],
- '_customer_name': params['_customer_name'],
- '_otp_ref': params['_otp_ref'],
- '_personalized_id': params['_personalized_id'],
- '_account_no': params['_account_no'],
- }
- return data
- elif result['errCode'] == 'VrfyOTPErr00002':
- logger.error('UserID is temporary locked please call 1558')
- raise PluginError('UserID is temporary locked please call 1558')
- else:
- raise Exception('Unhandled Error')
- data = {}
- data['_state_add'] = STATE_ADD_ENUM.SUCCESS # WAITING
- data['_otp_ref'] = ''
- return data
- else:
- raise Exception('Unexpect _tmbflow')
- pass
- def del_account(self, account_no):
- from banktransfer.models import STATE_DEL_ENUM
- data = {
- '_state_del': STATE_DEL_ENUM.SUCCESS,
- }
- return data
- def del_all_accounts(self, task=None):
- from banktransfer.models import STATE_DEL_ENUM
- from bankcore.bankcore import account_no_format_full
- logger = self.logger.add_tag('del_all_accounts')
- data = self._craft_data({
- 'serviceID': 'receipentListingService',
- 'crmId': '',
- 'cacheid': '',
- })
- r = self.http_post(self.get_service_url('receipentListingService'), data)
- logger.info(msg='del_all_accounts page1', attachment=r.text)
- result = r.json()
- self._save_session(result)
- found = False
- personalized_id = None
- for recepient in result['Results']:
- if recepient['personalizedName'] == self.auto_add_account:
- found = True
- personalized_id = recepient['personalizedId']
- if found:
- data = self._craft_data({
- 'serviceID': 'receipentAllDetailsService',
- 'crmId': '000000000000000000000000000000',
- 'personalizedId': personalized_id, # TODO: must be 1504464354
- })
- r = self.http_post(self.get_service_url('receipentAllDetailsService'), data)
- logger.info(msg='del_all_accounts page2', attachment=r.text)
- result = r.json()
- self._save_session(result)
- sub_accounts = result['Results'][1:]
- for sub_account in sub_accounts:
- personal_id = sub_account['personalizedId']
- sub_account_id = sub_account['personalizedAcctId']
- name = sub_account['PersonalizedAcctName']
- nickname = sub_account['PersonalizedAcctNickName']
- data = self._craft_data({
- 'serviceID': 'ExecuteMyRecipientAccountEditDeleteService',
- 'personalizedAcctId': sub_account_id,
- 'acctNickName': nickname,
- 'personalizedId': personal_id,
- 'bankCD': '11',
- 'acctStatus': 'Deleted',
- 'nickname': nickname.encode('utf-8'),
- 'bankname': 'ธนาคารทหารไทย จำกัด (มหาชน)',
- 'accnumber': account_no_format_full(sub_account_id),
- 'AccountName': name.encode('utf-8'),
- })
- r = self.http_post(self.get_service_url('ExecuteMyRecipientAccountEditDeleteService'), data)
- logger.info(msg='del_all_accounts page3', attachment=r.text)
- result = r.json()
- self._save_session(result)
- if 'httpStatusCode' in result and result['httpStatusCode'] != 200:
- raise Exception('Unhandled Exception.')
- data = {
- '_state_del': STATE_DEL_ENUM.SUCCESS,
- }
- return data
- def transfer(self, from_account_no, to_account_no, amount):
- from banktransfer.models import STATE_TRANSFER_ENUM
- logger = self.logger.add_tag('transfer')
- '''
- เปิดหน้าโอน
- '''
- transfer_date = datetime.datetime.now().strftime('%Y-%m-%d')
- data = self._craft_data({
- 'serviceID': 'customerAccountInquiry',
- 'transferFlag': 'true',
- })
- r = self.http_post(self.get_service_url('customerAccountInquiry'), data)
- logger.info(msg='transfer page1(data)', attachment=json.dumps(data))
- logger.info(msg='transfer page1', attachment=r.text)
- result = r.json()
- self._save_session(result)
- found = False
- found_accounts = []
- available_balance = None
- from_account_nickname = None
- for account_rec in result['custAcctRec']:
- account_id = account_rec['accId'][4:] # Trim 4 ตัวแรกทิ้ง
- found_accounts.append(account_id)
- if account_id == from_account_no:
- found = True
- available_balance = account_rec['availableBal']
- from_account_nickname = account_rec['acctNickName']
- break
- if not found:
- raise InvalidAccountNoFrom('Account not found. (found only %s)' % found_accounts)
- self._token_switching()
- data = self._craft_data({
- 'serviceID': 'crmProfileInq',
- 'transferFlag': 'true',
- 'transferAmt': amount,
- 'gblisTMB': 11,
- 'gblTMBBankCD': 11,
- 'gblPaynow': 'true',
- 'frmAccnt': from_account_no,
- 'recipientMobile': '',
- 'recipientEmailAddr': '',
- 'toNum': to_account_no,
- 'bankRef': 'TMB',
- 'fee': 0,
- 'FuturetransferDate': transfer_date,
- 'accountName': self.sub_add_account,
- 'accountNum': 'xxx-x-%s-x' % to_account_no[4:9],
- 'bankName': 'TMB',
- 'module': 'execute',
- })
- r = self.http_post(self.get_service_url('crmProfileInq'), data)
- logger.info(msg='transfer page2(data)', attachment=json.dumps(data))
- logger.info(msg='transfer page2', attachment=r.text)
- result = r.json()
- self._save_session(result)
- data = self._craft_data({
- 'serviceID': 'depositAccountInquiryNonSec',
- 'acctId': to_account_no,
- })
- r = self.http_post(self.get_service_url('depositAccountInquiryNonSec'), data)
- logger.info(msg='transfer page3(data)', attachment=json.dumps(data))
- logger.info(msg='transfer page3', attachment=r.text)
- result = r.json()
- self._save_session(result)
- customer_name = result['accountTitle']
- data = self._craft_data({
- 'serviceID': 'fundTransferInq',
- 'transferAmt': amount,
- 'transferDate': transfer_date,
- # 'depositeNo': 'undefined',
- 'fromAcctNo': from_account_no,
- 'toAcctNo': to_account_no,
- })
- r = self.http_post(self.get_service_url('fundTransferInq'), data)
- logger.info(msg='transfer page4(data)', attachment=json.dumps(data))
- logger.info(msg='transfer page4', attachment=r.text)
- result = r.json()
- self._save_session(result)
- fee = result['transferFee']
- self._token_switching()
- ''' Generate OTP '''
- data = self._craft_data({
- 'events': '[]',
- 'retryCounterRequestOTP': 0,
- 'Channel': 'ExecuteTransfer',
- 'serviceID': 'generateOTPWithUser',
- 'nameFromRecipientList': 'false',
- 'httpheaders': '{}',
- 'httpconfig': '{"timeout":180000}',
- })
- r = self.http_post(self.get_service_url('generateOTPWithUser'), data)
- logger.info(msg='transfer page5(data)', attachment=json.dumps(data))
- logger.info(msg='transfer page5', attachment=r.text)
- result = r.json()
- self._save_session(result)
- otp_ref = result['Collection1'][7]['ValueString']
- data = {
- '_state_transfer': STATE_TRANSFER_ENUM.WAIT_INPUT_OTP,
- '_otp_ref': otp_ref,
- 'fromAcctNo': from_account_no,
- 'toAcctNo': to_account_no,
- 'amount': amount,
- 'fee': fee,
- '_customer_name': customer_name,
- 'available_balance': available_balance,
- 'from_account_nickname': from_account_nickname,
- }
- return data
- def otp_transfer(self, params, amount=None):
- from banktransfer.models import STATE_TRANSFER_ENUM
- logger = self.logger.add_tag('otp_transfer')
- transfer_date = datetime.datetime.now().strftime('%Y-%m-%d')
- fee_txt = (u'%s ฿' % (params['fee'])).encode('utf-8')
- expected_balance = (float(params['available_balance']) - amount)
- data = self._craft_data({
- 'serviceID': 'executeTransfer',
- 'retryCounterVerifyAccessPin': 0,
- 'retryCounterVerifyTransPwd': 0,
- 'password': params['otp'],
- 'retryCounterVerifyOTP': 1,
- 'freq': 'once',
- 'fromAcctNo': params['fromAcctNo'],
- 'toAcctNo': params['toAcctNo'],
- 'dueDateForEmail': '',
- 'memo': '',
- 'transferAmt': amount, # params['amount'],
- 'gblBANKREF': 'ธนาคารทหารไทย จำกัด (มหาชน)',
- 'gblTrasSMS': 0,
- 'gblTransEmail': 0,
- 'gblTransSMART': 0,
- 'gblTrasORFT': 0,
- 'gblisTMB': 11, # TMB
- 'toAcctBank': 'ธนาคารทหารไทย จำกัด (มหาชน)',
- 'bankShortName': 'TMB',
- 'gblTokenSwitchFlag': 'false',
- 'gblPaynow': 'true',
- 'recipientEmailAddr': '',
- 'recipientMobileNbr': '',
- 'recipientMobile': '',
- 'receipientNote': '',
- 'RecipentName': self.auto_add_account,
- 'times': '',
- 'frmFiident': '0011000102300200', # TODO: What ??
- 'toFIIdent': '11',
- 'acctTitle': self.sub_add_account,
- 'transferDate': transfer_date,
- 'transferFee': fee_txt, # TODO: What ??
- 'finTxnMemo': '',
- 'fromAcctName': params['from_account_nickname'],
- 'fromAcctNickName': params['from_account_nickname'],
- 'toAcctName': params['_customer_name'],
- 'toAcctNickname': self.sub_add_account,
- 'gblBalAfterXfer': expected_balance, # (params['available_balance'] - amount), # TODO: Balance expected after transfer
- 'endDate': '',
- 'transferOrderDate': '', # '15/12/2015 00:36:42', # TODO:
- 'recurring': '',
- 'Recp_category': '1',
- })
- r = self.http_post(self.get_service_url('executeTransfer'), data)
- logger.info(msg='otp_transfer page1(data)', attachment=json.dumps(data))
- logger.info(msg='otp_transfer page1', attachment=r.text)
- result = r.json()
- self._save_session(result)
- if result['opstatus'] == 8005: # "User ID or Password is incorrect. Please try again.
- if result['errCode'] == 'VrfyOTPErr00001':
- logger.debug('Invalid OTP, try again.')
- data = {
- '_state_add': STATE_TRANSFER_ENUM.WAIT_INPUT_OTP,
- # '_tmbflow': params.get('_tmbflow'),
- '_customer_name': params['_customer_name'],
- '_otp_ref': params['_otp_ref'],
- '_personalized_id': params['_personalized_id'],
- '_account_no': params['_account_no'],
- }
- return data
- elif result['errCode'] == 'VrfyOTPErr00002':
- logger.error('UserID is temporary locked please call 1558')
- raise PluginError('UserID is temporary locked please call 1558')
- else:
- raise Exception('Unhandled Error')
- if result['StatusCode'] == 100: # Sorry for inconvenience. TMB cannot proceed your transaction. For more info, please call 1558.
- raise PluginHandledError('Target Account is locked.')
- if result['StatusCode'] != 0:
- raise Exception('Unhandled Error')
- fee = result['Transfer'][0]['fee']
- data = {
- '_fee': fee,
- '_state_transfer': STATE_TRANSFER_ENUM.SUCCESS,
- }
- return data
- def _token_switching(self, optional_params=None):
- logger = self.logger.add_tag('_token_switching')
- data = {
- 'serviceID': 'tokenSwitching',
- }
- if optional_params:
- data.update(optional_params)
- data = self._craft_data(data)
- r = self.web_post(self.get_service_url('tokenSwitching'), data, soup=False)
- logger.info(msg='_token_switching page(data)', attachment=json.dumps(data))
- logger.info(msg='_token_switching page', attachment=r)
- result = json.loads(r)
- self._save_session(result)
- return result
- def logout(self):
- if hasattr(self, 'tknid'):
- '''
- channelId:01
- timeOut:false
- deviceId:campaignBannerIBCount
- languageCd:TH
- appID:TMB
- appver:1.0.12.17
- serviceID:logOutTMB
- locale:th_TH
- channel:wap
- platform:thinclient
- cacheid:
- tknid:E82192EF544DB62D3368E4C87E4CC32DD631C8F305BE83ACBB7AAB56B53B293D
- rcid:spadesktopweb
- :
- '''
- data = dict()
- data.update(self._service_form)
- data.update({
- 'channelId': '01',
- 'timeOut': 'false',
- 'deviceId': 'campaignBannerIBCount',
- 'languageCd': 'TH',
- 'serviceID': 'logOutTMB',
- 'tknid': self.tknid,
- })
- self.http_post(self._logout_url, data=data)
- # json.loads(r)
- print('Logout success')
- def _save_session(self, result):
- if 'opstatus' in result:
- if result['opstatus'] == 0:
- if 'isValidSession' in result and result['isValidSession'] is False:
- raise InvalidToken()
- if result['opstatus'] == 8004:
- raise Exception('errmsg: %s' % result['errmsg'])
- self.tknid = result['tknid']
- def _craft_data(self, new_data):
- data = dict()
- data.update(self._service_form)
- data.update({
- 'tknid': self.tknid,
- })
- data.update(new_data)
- return data
- def serialize(self):
- import pickle
- return pickle.dumps([self.session, self.tknid])
- @classmethod
- def deserialize(cls, data):
- import pickle
- session, tknid, session_headers = pickle.loads(data)
- entity = cls()
- setattr(entity, 'session', session)
- setattr(entity, 'tknid', tknid)
- entity.session.headers = session_headers
- return entity
- @classmethod
- def deserialize(cls, data):
- return cls.deserialize_key(data, ['session', 'tknid'])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement