-
Notifications
You must be signed in to change notification settings - Fork 0
/
paypal_requester.py
138 lines (99 loc) · 4.12 KB
/
paypal_requester.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# credentials stored locally and .gitignore-d
import secrets
import time
"""
Function that uses a designated webdriver to log into Paypal.com and request various amounts of money from multiple people simultaneously.
"""
def request_payments(driver, amounts_due, memo):
"""
STEP 1: LOG INTO PAYPAL AND NAVIGATE TO MONEY REQUESTS PAGE
"""
# go to Request Money on paypal, which will redirect to a login page
driver.get("https://www.paypal.com/myaccount/transfer/homepage/request")
# wait for login page to load
WebDriverWait(driver, 60).until(EC.presence_of_element_located((
By.ID, "email")))
print(driver.title, '\n')
# find the form inputs and submit button element
usernameInput = driver.find_element(By.ID, "email")
passwordInput = driver.find_element(By.ID, "password")
nextButton = driver.find_element(By.ID, "btnNext")
submitButton = driver.find_element(By.ID, "btnLogin")
# log in with credentials, with some time in between actions to simulate user limitations
usernameInput.send_keys(secrets.PAYPAL_USERNAME)
time.sleep(2)
if nextButton:
nextButton.click()
# wait just in case we had to click the next button to render the password input and submit button
WebDriverWait(driver, 60).until(EC.element_to_be_clickable((
By.ID, "btnLogin")))
passwordInput.send_keys(secrets.PAYPAL_PASSWORD)
time.sleep(2)
# submit the form
submitButton.click()
print(driver.title, '\n')
# TO DO: sometimes paypal gets hung up on the captcha and redirects to a "try again" page
# this may have been fixed by adding the waits (time.sleep())s between actions
# if it happens again, add code path to automatically retry login in the above scenario
"""
STEP 2: ENTER ALL PAYEES TO INITIATE SIMULTANEOUS REQUEST
"""
# wait for money requests page to load
WebDriverWait(driver, 60).until(EC.presence_of_element_located((
By.ID, "fn-requestRecipient")))
print(driver.title, '\n')
# add all payees to input box - NB: has autocomplete/ typeahead functionality
payeeInput = driver.find_element(By.ID, "fn-requestRecipient")
for person in secrets.PAYEES:
time.sleep(1)
payeeInput.send_keys(person["email"])
time.sleep(1)
payeeInput.send_keys(Keys.RETURN)
time.sleep(2)
# next button only enabled when valid email(s) entered
WebDriverWait(driver, 60).until(EC.element_to_be_clickable((
By.CSS_SELECTOR, "span.recipient-next > button")))
nextButton = driver.find_element(By.CSS_SELECTOR, "span.recipient-next > button")
nextButton.click()
"""
STEP 3: SUBMIT REQUEST TO EACH PAYEE FOR RESPECTIVE AMOUNTS CALCULATED FROM BILL
"""
# wait for request preview page to load
WebDriverWait(driver, 60).until(EC.presence_of_element_located((
By.ID, "fn-amount")))
totalInput = driver.find_element(By.ID, "fn-amount")
splitButton = driver.find_element(By.ID, "split-request")
# sum up total amount to request from everyone, cast to string to be inputted
total = str(sum(amounts_due))
totalInput.send_keys(total)
# paypal automatically assumes that you want each person to pay you this amount
# solution: change mode from Request Money to Split Bill
splitButton.click()
# paypal assumes next that you want this total to be equally split amongst payees
# solution: wait til UI changes and then manually edit each amount due
WebDriverWait(driver, 60).until(EC.presence_of_element_located((
By.ID, "split-request-tab")))
actions = ActionChains(driver)
actions.send_keys(Keys.TAB)
numPayees = len(amounts_due)
for i in range(numPayees):
print(amounts_due[i])
actions.send_keys(Keys.TAB) \
.send_keys(Keys.BACK_SPACE * 6) \
.send_keys(str(amounts_due[i])) \
.pause(1)
# add memo for requests
actions.send_keys(Keys.TAB * 2)
actions.send_keys(memo)
actions.pause(2)
# submit requests
actions.send_keys(Keys.TAB)
actions.send_keys(Keys.RETURN)
actions.pause(10)
actions.perform()
# TO DO: check for success response