class PrestoAPI::Client
Public Instance Methods
card_status_with_number(card_number)
click to toggle source
# File lib/presto_api.rb, line 83 def card_status_with_number(card_number) card_status_from_page(login_with_card_number(card_number)) end
card_status_with_username_password(username, password)
click to toggle source
# File lib/presto_api.rb, line 79 def card_status_with_username_password(username, password) card_status_from_page(login_with_username_password(username, password)) end
load_registered_card(username, password, email, amount, credit_card)
click to toggle source
# File lib/presto_api.rb, line 87 def load_registered_card(username, password, email, amount, credit_card) login_with_username_password(username, password) load_card(amount, email, credit_card) end
load_unregistered_card(card_number, email, amount, credit_card)
click to toggle source
# File lib/presto_api.rb, line 92 def load_unregistered_card(card_number, email, amount, credit_card) login_with_card_number(card_number) load_card(amount, email, credit_card) end
transaction_history_with_username_password(username, password)
click to toggle source
# File lib/presto_api.rb, line 74 def transaction_history_with_username_password(username, password) login_with_username_password(username, password) transaction_history_from_page(agent.get('https://www.prestocard.ca/en-US/Pages/TransactionalPages/TransactionHistory.aspx')) end
user_with_username_password(username, password)
click to toggle source
# File lib/presto_api.rb, line 67 def user_with_username_password(username, password) card_number = card_number_from_page(login_with_username_password(username, password)) user = user_from_page(agent.get('https://www.prestocard.ca/en-US/Pages/TransactionalPages/ViewUpdateRegistration.aspx')) user.card_number = card_number user end
Private Instance Methods
agent()
click to toggle source
# File lib/presto_api.rb, line 279 def agent @agent ||= Mechanize.new end
card_number_from_page(page)
click to toggle source
# File lib/presto_api.rb, line 179 def card_number_from_page(page) card_number = page.parser.xpath('//span[@id="ctl00_PlaceHolderContent_PlaceHolderSiteNavigation_CardNavigationMenuWebPart_ctl00_labelFareCardNo"]/text()[last()]').last.content card_number[/^\d+/].to_s end
card_status_from_page(page)
click to toggle source
# File lib/presto_api.rb, line 130 def card_status_from_page(page) balance = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_AFMSCardSummaryWebpart_ctl00_wizardCardSummary_labelDisplayBalance"]/text()[last()]').last status = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_AFMSCardSummaryWebpart_ctl00_wizardCardSummary_labelDisplayCardStatus"]/text()[last()]').last if !balance || !status puts 'Try logging in with username/password instead of just the card number' return nil end card = Card.new card.status = status.content card.balance = balance.content card.number = card_number_from_page(page) card end
load_card(amount, email, credit_card)
click to toggle source
# File lib/presto_api.rb, line 204 def load_card(amount, email, credit_card) # Check that we want to load a dollar value onto the card page = agent.get('https://www.prestocard.ca/en-US/Pages/TransactionalPages/ReloadEpurse.aspx') form = page.forms.first radio_button = form.radiobutton_with(:id => 'ctl00_SPWebPartManager1_LoadePurseWebPartWebpartControl_ctl00_wizardLoadEPurse_webpartPeriodPassWebPart_ctl00_wizardPeriodPassSelection_radioButtonListProducts_0') radio_button.check button = form.button_with(:name => "ctl00$SPWebPartManager1$LoadePurseWebPartWebpartControl$ctl00$wizardLoadEPurse$webpartPeriodPassWebPart$ctl00$wizardPeriodPassSelection$buttonNextinProductSelection") page = agent.submit(form, button) # Enter the amount to add to the card and our email address form = page.forms.first amount_field = form.field_with(:id => "ctl00_SPWebPartManager1_LoadePurseWebPartWebpartControl_ctl00_wizardLoadEPurse_textBoxamountToReload") amount_field.value = amount email_field = form.field_with(:id => "ctl00_SPWebPartManager1_LoadePurseWebPartWebpartControl_ctl00_wizardLoadEPurse_textBoxemailAddress") email_field.value = email button = form.button_with(:name => "ctl00$SPWebPartManager1$LoadePurseWebPartWebpartControl$ctl00$wizardLoadEPurse$buttonConfirmReload") page = agent.submit(form, button) # Confirm Amount form = page.forms.first button = form.button_with(:name => "ctl00$SPWebPartManager1$LoadePurseWebPartWebpartControl$ctl00$wizardLoadEPurse$buttonConfirmInVerification") page = agent.submit(form, button) # Intermediate Moneris Submit storeId = page.body[/storeId = '[^\s]*'/,0][/'.*'/,0][1..-2] hppKey = page.body[/hppKey = '[^\s]*'/,0][/'.*'/,0][1..-2] totalCharge = page.body[/totalCharge = '[^\s]*'/,0][/'.*'/,0][1..-2] orderId = page.body[/orderId = '[^\s]*'/,0][/'.*'/,0][1..-2] language = page.body[/language = '[^\s]*'/,0][/'.*'/,0][1..-2] form = page.forms.first form.field_with(:id => "ps_store_id").value = storeId form.field_with(:id => "hpp_key").value = hppKey form.field_with(:id => "charge_total").value = totalCharge form.field_with(:id => "order_id").value = orderId form.field_with(:id => "lang").value = language form.action = "https://www3.moneris.com/HPPDP/index.php" page = form.submit # Enter Payment Details callCCPurchase = page.body[/function callCCPurchase\(\)[^}]*/,0] hpp_id = callCCPurchase[/hpp_id=[^"]+/,0] hpp_id["hpp_id="] = "" hpp_ticket = callCCPurchase[/hpp_ticket=[^"]+/,0] hpp_ticket["hpp_ticket="] = "" pan = credit_card.number pan_mm = credit_card.expiry_month pan_yy = credit_card.expiry_year cardholder = credit_card.name post_data = "hpp_id=" + CGI::escape(hpp_id) + "&hpp_ticket=" + CGI::escape(hpp_ticket) + "&pan=" + CGI::escape(pan) + "&pan_mm=" + CGI::escape(pan_mm) + "&pan_yy=" + CGI::escape(pan_yy) + "&cardholder=" + CGI::escape(cardholder) + "&doTransaction=cc_purchase" # Send Payment headers = { 'Content-Type' => 'application/x-www-form-urlencoded', 'Connection' => 'close', 'Content-length' => post_data.length } page = agent.post( 'https://www3.moneris.com/HPPDP/hprequest.php', post_data, headers) # Confirm with Credit Card Provider parsed = JSON.parse(page.body) form_text_encoded = parsed['response']['data']['form'] form_text_decoded = Base64.decode64(form_text_encoded) form_text_decoded.gsub! '\\n', '' form_text_decoded.gsub! '\\"', '"' # Send the decoded HTML back to the client so the user can # confirm with their credit card provider form_text_decoded end
login_page()
click to toggle source
# File lib/presto_api.rb, line 118 def login_page @login_page ||= agent.get('https://www.prestocard.ca/en-US/Pages/TransactionalPages/AccountLogin.aspx') end
login_with_card_number(card_number)
click to toggle source
# File lib/presto_api.rb, line 109 def login_with_card_number(card_number) # Fill out the anonymous login form field_hash = { 'ctl00$SPWebPartManager1$AccountLoginWebpartControl$ctl00$webpartAnonymousUserLogin$ctl00$textboxAnonymousLogin' => card_number } button_name = 'ctl00$SPWebPartManager1$AccountLoginWebpartControl$ctl00$webpartAnonymousUserLogin$ctl00$buttonSubmit' submit_form(login_page.forms.first, field_hash, button_name) end
login_with_username_password(username, password)
click to toggle source
# File lib/presto_api.rb, line 99 def login_with_username_password(username, password) # Fill out the registered login form field_hash = { 'ctl00$SPWebPartManager1$AccountLoginWebpartControl$ctl00$webpartRegisteredUserLogin$ctl00$textboxRegisteredLogin' => username, 'ctl00$SPWebPartManager1$AccountLoginWebpartControl$ctl00$webpartRegisteredUserLogin$ctl00$textboxPassword' => password } button_name = 'ctl00$SPWebPartManager1$AccountLoginWebpartControl$ctl00$webpartRegisteredUserLogin$ctl00$buttonSubmit' submit_form(login_page.forms.first, field_hash, button_name) end
submit_form(form, field_hash, button_name)
click to toggle source
# File lib/presto_api.rb, line 122 def submit_form(form, field_hash, button_name) field_hash.each do |key, value| form.field_with(:name => key).value = value end button = form.button_with(:name => button_name) agent.submit(form, button) end
transaction_history_from_page(page)
click to toggle source
# File lib/presto_api.rb, line 184 def transaction_history_from_page(page) number_of_items = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']").children.count transaction_history = [] for i in 2..number_of_items transaction = Transaction.new transaction.date = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[1]").last.content transaction.service_provider = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[2]").last.content transaction.location = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[3]").last.content transaction.type = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[4]").last.content transaction.amount = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[5]").last.content transaction.balance = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[6]").last.content transaction.loyalty_month = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[7]").last.content transaction.loyalty_trip = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[8]").last.content transaction.loyalty_step = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[9]").last.content transaction.loyalty_discount = page.parser.xpath("//table[@id='ctl00_SPWebPartManager1_CheckTransactionHistoryWebPartControl_ctl00_ViewTransactionHistory_gridTransactionHistory']/tr[#{i}]/td[10]").last.content transaction_history.push transaction end transaction_history end
user_from_page(page)
click to toggle source
# File lib/presto_api.rb, line 144 def user_from_page(page) first_name = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelFirstNameOutput"]/text()[last()]').last last_name = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelLastNameOutput"]/text()[last()]').last address1 = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelStreetAddress1Output"]/text()[last()]').last address2 = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelStreetAddress2Output"]/text()[last()]').last city = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelCityOutput"]/text()[last()]').last province = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelProvinceOutput"]/text()[last()]').last country = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelCountryOutput"]/text()[last()]').last postal_code = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelPostalCodeOutput"]/text()[last()]').last phone_number = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelPrimaryTelephoneNumberOutput"]/text()[last()]').last email = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_labelEmailAddressOutput"]/text()[last()]').last security_question = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_webPartSecurityDetails_ctl00_labelSecurityQuestionOutput"]/text()[last()]').last security_answer = page.parser.xpath('//span[@id="ctl00_SPWebPartManager1_updateRegistrationWebPart_ctl00_WizardViewUpdateProfile_webPartSecurityDetails_ctl00_labelSecurityResponseOutput"]/text()[last()]').last if !first_name puts 'There is no user information assigned to this account' return nil end user = User.new user.first_name = first_name.content || '' user.last_name = last_name.content || '' user.address1 = address1.content || '' user.address2 = address2.content || '' user.city = city.content || '' user.province = province.content || '' user.country = country.content || '' user.postal_code = postal_code.content || '' user.phone_number = phone_number.content || '' user.email = email.content || '' user.security_question = security_question.content || '' user.security_answer = security_answer.content || '' user end