python-payway 0.0.2__py3-none-any.whl → 0.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- payway/client.py +198 -108
- payway/conf.py +7 -10
- payway/constants.py +79 -80
- payway/customers.py +54 -32
- payway/exceptions.py +10 -19
- payway/model.py +161 -126
- payway/test_utils.py +10 -0
- payway/transactions.py +5 -3
- payway/utils.py +9 -3
- {python_payway-0.0.2.dist-info → python_payway-0.0.4.dist-info}/METADATA +64 -58
- python_payway-0.0.4.dist-info/RECORD +15 -0
- {python_payway-0.0.2.dist-info → python_payway-0.0.4.dist-info}/WHEEL +1 -1
- {python_payway-0.0.2.dist-info → python_payway-0.0.4.dist-info}/top_level.txt +0 -1
- python_payway-0.0.2.dist-info/RECORD +0 -18
- tests/__init__.py +0 -0
- tests/test_client.py +0 -393
- tests/test_customers.py +0 -226
- tests/test_transactions.py +0 -88
- {python_payway-0.0.2.dist-info → python_payway-0.0.4.dist-info}/LICENSE +0 -0
payway/client.py
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
1
4
|
from logging import getLogger
|
|
5
|
+
from typing import NoReturn
|
|
6
|
+
|
|
2
7
|
import requests
|
|
3
8
|
|
|
4
|
-
from payway.conf import
|
|
5
|
-
from payway.constants import
|
|
6
|
-
|
|
9
|
+
from payway.conf import CUSTOMER_URL, TOKEN_NO_REDIRECT, TRANSACTION_URL
|
|
10
|
+
from payway.constants import (
|
|
11
|
+
BANK_ACCOUNT_PAYMENT_CHOICE,
|
|
12
|
+
CREDIT_CARD_PAYMENT_CHOICE,
|
|
13
|
+
VALID_PAYMENT_METHOD_CHOICES,
|
|
14
|
+
)
|
|
7
15
|
from payway.customers import CustomerRequest
|
|
8
16
|
from payway.exceptions import PaywayError
|
|
9
|
-
from payway.model import
|
|
17
|
+
from payway.model import (
|
|
18
|
+
BankAccount,
|
|
19
|
+
PaymentError,
|
|
20
|
+
PaymentSetup,
|
|
21
|
+
PayWayCard,
|
|
22
|
+
PayWayCustomer,
|
|
23
|
+
PayWayPayment,
|
|
24
|
+
PayWayTransaction,
|
|
25
|
+
ServerError,
|
|
26
|
+
TokenResponse,
|
|
27
|
+
)
|
|
10
28
|
from payway.transactions import TransactionRequest
|
|
11
29
|
|
|
12
30
|
logger = getLogger(__name__)
|
|
@@ -17,99 +35,151 @@ class Client(CustomerRequest, TransactionRequest):
|
|
|
17
35
|
PayWay Client to connect to PayWay and perform methods given credentials
|
|
18
36
|
"""
|
|
19
37
|
|
|
20
|
-
merchant_id =
|
|
21
|
-
bank_account_id =
|
|
22
|
-
secret_api_key =
|
|
23
|
-
publishable_api_key =
|
|
38
|
+
merchant_id = ""
|
|
39
|
+
bank_account_id = ""
|
|
40
|
+
secret_api_key = ""
|
|
41
|
+
publishable_api_key = ""
|
|
24
42
|
|
|
25
|
-
def __init__(
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
merchant_id: str,
|
|
46
|
+
bank_account_id: str,
|
|
47
|
+
secret_api_key: str,
|
|
48
|
+
publishable_api_key: str,
|
|
49
|
+
) -> NoReturn:
|
|
26
50
|
"""
|
|
27
51
|
:param merchant_id : str = PayWay Merchant ID
|
|
28
52
|
:param bank_account_id : str = PayWay Bank Account ID
|
|
29
53
|
:param secret_api_key : str = PayWay Secret APi Key
|
|
30
54
|
:param publishable_api_key : str = PayWay Publishable API Key
|
|
31
55
|
"""
|
|
32
|
-
self._validate_credentials(
|
|
56
|
+
self._validate_credentials(
|
|
57
|
+
merchant_id,
|
|
58
|
+
bank_account_id,
|
|
59
|
+
secret_api_key,
|
|
60
|
+
publishable_api_key,
|
|
61
|
+
)
|
|
33
62
|
self.merchant_id = merchant_id
|
|
34
63
|
self.bank_account_id = bank_account_id
|
|
35
64
|
self.secret_api_key = secret_api_key
|
|
36
65
|
self.publishable_api_key = publishable_api_key
|
|
37
66
|
|
|
38
67
|
session = requests.Session()
|
|
39
|
-
session.auth = (self.secret_api_key,
|
|
40
|
-
headers = {
|
|
68
|
+
session.auth = (self.secret_api_key, "")
|
|
69
|
+
headers = {"content-type": "application/x-www-form-urlencoded"}
|
|
41
70
|
session.headers = headers
|
|
42
71
|
self.session = session
|
|
43
72
|
session_no_headers = requests.Session()
|
|
44
73
|
session_no_headers.auth = session.auth
|
|
45
74
|
self.session_no_headers = session_no_headers
|
|
46
75
|
|
|
47
|
-
def _validate_credentials(
|
|
76
|
+
def _validate_credentials(
|
|
77
|
+
self,
|
|
78
|
+
merchant_id: str,
|
|
79
|
+
bank_account_id: str,
|
|
80
|
+
secret_api_key: str,
|
|
81
|
+
publishable_api_key: str,
|
|
82
|
+
) -> NoReturn:
|
|
48
83
|
if not merchant_id or not bank_account_id or not secret_api_key or not publishable_api_key:
|
|
49
84
|
if not secret_api_key or not publishable_api_key:
|
|
50
|
-
logger.error(
|
|
51
|
-
raise PaywayError(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
85
|
+
logger.error("PayWay API keys not found")
|
|
86
|
+
raise PaywayError(
|
|
87
|
+
message="PayWay API keys not found",
|
|
88
|
+
code="INVALID_API_KEYS",
|
|
89
|
+
)
|
|
90
|
+
logger.error(
|
|
91
|
+
"Merchant ID, bank account ID, secret API key, publishable API key are " "invalid",
|
|
92
|
+
)
|
|
93
|
+
raise PaywayError(
|
|
94
|
+
message="Invalid credentials",
|
|
95
|
+
code="INVALID_API_CREDENTIALS",
|
|
96
|
+
)
|
|
55
97
|
|
|
56
|
-
def get_request(self, endpoint):
|
|
57
|
-
return requests.get(url=endpoint, auth=(self.secret_api_key,
|
|
98
|
+
def get_request(self, endpoint: str) -> requests.Response:
|
|
99
|
+
return requests.get(url=endpoint, auth=(self.secret_api_key, ""), timeout=30)
|
|
58
100
|
|
|
59
|
-
def post_request(
|
|
101
|
+
def post_request(
|
|
102
|
+
self, endpoint: str, data: dict, auth: tuple | None = None, idempotency_key: str | None = None
|
|
103
|
+
) -> requests.Response:
|
|
104
|
+
"""
|
|
105
|
+
Supply an idempotency_key to avoid duplicate POSTs
|
|
106
|
+
https://www.payway.com.au/docs/rest.html#avoiding-duplicate-posts
|
|
107
|
+
"""
|
|
60
108
|
if not auth:
|
|
61
|
-
auth = (self.secret_api_key,
|
|
62
|
-
headers = {
|
|
63
|
-
|
|
109
|
+
auth = (self.secret_api_key, "")
|
|
110
|
+
headers = {"content-type": "application/x-www-form-urlencoded"}
|
|
111
|
+
if idempotency_key:
|
|
112
|
+
headers["Idempotency-Key"] = idempotency_key
|
|
113
|
+
return requests.post(url=endpoint, auth=auth, data=data, headers=headers, timeout=30)
|
|
64
114
|
|
|
65
|
-
def put_request(self, endpoint, data):
|
|
66
|
-
|
|
67
|
-
|
|
115
|
+
def put_request(self, endpoint: str, data: dict) -> requests.Response:
|
|
116
|
+
return requests.put(
|
|
117
|
+
url=endpoint,
|
|
118
|
+
auth=(self.secret_api_key, ""),
|
|
119
|
+
data=data,
|
|
120
|
+
headers={"content-type": "application/x-www-form-urlencoded"},
|
|
121
|
+
timeout=30,
|
|
122
|
+
)
|
|
68
123
|
|
|
69
|
-
def create_token(
|
|
124
|
+
def create_token(
|
|
125
|
+
self, payway_obj: BankAccount | PayWayCard, payment_method: str, idempotency_key: str | None = None
|
|
126
|
+
) -> tuple[TokenResponse, list]:
|
|
70
127
|
"""
|
|
71
128
|
Creates a single use token for a Customer's payment setup (credit card or bank account)
|
|
72
129
|
:param payway_obj: object: one of model.PayWayCard or model.BankAccount object
|
|
73
130
|
:param payment_method: str: one of `card` or `direct_debit`
|
|
131
|
+
:param idempotency_key: str: unique value to avoid duplicate POSTs
|
|
74
132
|
"""
|
|
75
133
|
data = payway_obj.to_dict()
|
|
76
|
-
if payment_method ==
|
|
134
|
+
if payment_method == "card":
|
|
77
135
|
payway_payment_method = CREDIT_CARD_PAYMENT_CHOICE
|
|
78
|
-
elif payment_method ==
|
|
136
|
+
elif payment_method == "direct_debit":
|
|
79
137
|
payway_payment_method = BANK_ACCOUNT_PAYMENT_CHOICE
|
|
80
|
-
|
|
138
|
+
else:
|
|
139
|
+
valid_payment_method_choices = ", ".join(VALID_PAYMENT_METHOD_CHOICES)
|
|
81
140
|
raise PaywayError(
|
|
82
|
-
message="Invalid payment method. Must be one of
|
|
83
|
-
code=
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
141
|
+
message=f"Invalid payment method. Must be one of {valid_payment_method_choices}",
|
|
142
|
+
code="INVALID_PAYMENT_METHOD",
|
|
143
|
+
)
|
|
144
|
+
data.update(
|
|
145
|
+
{
|
|
146
|
+
"paymentMethod": payway_payment_method,
|
|
147
|
+
},
|
|
148
|
+
)
|
|
87
149
|
endpoint = TOKEN_NO_REDIRECT
|
|
88
|
-
logger.info(
|
|
89
|
-
response = self.post_request(
|
|
90
|
-
|
|
150
|
+
logger.info("Sending Create Token request to PayWay.")
|
|
151
|
+
response = self.post_request(
|
|
152
|
+
endpoint,
|
|
153
|
+
data,
|
|
154
|
+
auth=(self.publishable_api_key, ""),
|
|
155
|
+
idempotency_key=idempotency_key,
|
|
156
|
+
)
|
|
91
157
|
errors = self._validate_response(response)
|
|
92
158
|
if errors:
|
|
93
159
|
return None, errors
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return token_response, errors
|
|
160
|
+
token_response = TokenResponse().from_dict(response.json())
|
|
161
|
+
return token_response, errors
|
|
97
162
|
|
|
98
|
-
def create_card_token(self, card):
|
|
163
|
+
def create_card_token(self, card: PayWayCard, idempotency_key: str | None = None) -> tuple[TokenResponse, list]:
|
|
99
164
|
"""
|
|
100
165
|
:param card: PayWayCard object represents a customer's credit card details
|
|
101
|
-
|
|
166
|
+
:param idempotency_key: str: unique value to avoid duplicate POSTs
|
|
102
167
|
"""
|
|
103
|
-
return self.create_token(card,
|
|
168
|
+
return self.create_token(card, "card", idempotency_key=idempotency_key)
|
|
104
169
|
|
|
105
|
-
def create_bank_account_token(self, bank_account):
|
|
170
|
+
def create_bank_account_token(self, bank_account: BankAccount, idempotency_key: str | None = None) -> str:
|
|
106
171
|
"""
|
|
107
172
|
:param bank_account: BankAccount object represents a customer's bank account
|
|
173
|
+
:param idempotency_key: str: unique value to avoid duplicate POSTs
|
|
108
174
|
See model.BankAccount
|
|
109
175
|
"""
|
|
110
|
-
return self.create_token(
|
|
176
|
+
return self.create_token(
|
|
177
|
+
bank_account,
|
|
178
|
+
"direct_debit",
|
|
179
|
+
idempotency_key=idempotency_key,
|
|
180
|
+
)
|
|
111
181
|
|
|
112
|
-
def create_customer(self, customer):
|
|
182
|
+
def create_customer(self, customer: PayWayCustomer, idempotency_key: str | None = None) -> tuple[PayWayCustomer | None, list]:
|
|
113
183
|
"""
|
|
114
184
|
Create a customer in PayWay system
|
|
115
185
|
|
|
@@ -117,161 +187,181 @@ class Client(CustomerRequest, TransactionRequest):
|
|
|
117
187
|
PUT /customers/{customerNumber} to use your own customer number
|
|
118
188
|
|
|
119
189
|
:param customer: PayWayCustomer object represents a customer in PayWay
|
|
190
|
+
:param idempotency_key: str: unique value to avoid duplicate POSTs
|
|
120
191
|
See model.PayWayCustomer
|
|
121
192
|
:return:
|
|
122
193
|
"""
|
|
123
194
|
|
|
124
195
|
data = customer.to_dict()
|
|
125
|
-
data.update(
|
|
126
|
-
"merchantId": self.merchant_id,
|
|
127
|
-
|
|
128
|
-
})
|
|
196
|
+
data.update(
|
|
197
|
+
{"merchantId": self.merchant_id, "bankAccountId": self.bank_account_id},
|
|
198
|
+
)
|
|
129
199
|
|
|
130
|
-
logger.info(
|
|
200
|
+
logger.info("Sending Create Customer request to PayWay.")
|
|
131
201
|
|
|
132
202
|
if customer.custom_id:
|
|
133
|
-
endpoint =
|
|
203
|
+
endpoint = f"{CUSTOMER_URL}/{customer.custom_id}"
|
|
134
204
|
response = self.put_request(endpoint, data)
|
|
135
205
|
else:
|
|
136
|
-
endpoint =
|
|
137
|
-
response = self.post_request(
|
|
206
|
+
endpoint = f"{CUSTOMER_URL}"
|
|
207
|
+
response = self.post_request(
|
|
208
|
+
endpoint,
|
|
209
|
+
data,
|
|
210
|
+
idempotency_key=idempotency_key,
|
|
211
|
+
)
|
|
138
212
|
|
|
139
|
-
logger.info('Response from server: %s' % response)
|
|
140
213
|
errors = self._validate_response(response)
|
|
141
214
|
if errors:
|
|
142
215
|
return None, errors
|
|
143
|
-
else:
|
|
144
|
-
customer = PayWayCustomer().from_dict(response.json())
|
|
145
|
-
return customer, errors
|
|
146
216
|
|
|
147
|
-
|
|
217
|
+
customer = PayWayCustomer().from_dict(response.json())
|
|
218
|
+
return customer, errors
|
|
219
|
+
|
|
220
|
+
def process_payment(self, payment: PayWayPayment, idempotency_key: str | None = None) -> tuple[PayWayTransaction, list]:
|
|
148
221
|
"""
|
|
149
222
|
Process an individual payment against a Customer with active Recurring Billing setup.
|
|
150
223
|
:param payment: PayWayPayment object (see model.PayWayPayment)
|
|
224
|
+
:param idempotency_key: str: unique value to avoid duplicate POSTs
|
|
151
225
|
"""
|
|
152
226
|
data = payment.to_dict()
|
|
153
227
|
endpoint = TRANSACTION_URL
|
|
154
|
-
logger.info(
|
|
155
|
-
response = self.post_request(endpoint, data)
|
|
156
|
-
logger.info('Response from server: %s' % response)
|
|
228
|
+
logger.info("Sending Process Payment request to PayWay.")
|
|
229
|
+
response = self.post_request(endpoint, data, idempotency_key=idempotency_key)
|
|
157
230
|
errors = self._validate_response(response)
|
|
158
231
|
if errors:
|
|
159
232
|
return None, errors
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
transaction = PayWayTransaction.from_dict(response.json())
|
|
233
|
+
# convert response to PayWayTransaction object
|
|
234
|
+
transaction = PayWayTransaction.from_dict(response.json())
|
|
163
235
|
return transaction, errors
|
|
164
236
|
|
|
165
|
-
def _validate_response(self, response):
|
|
237
|
+
def _validate_response(self, response: requests.Response) -> list | None:
|
|
166
238
|
"""
|
|
167
239
|
Validates all responses from PayWay to catch documented PayWay errors.
|
|
168
240
|
:param response: requests response object
|
|
169
241
|
"""
|
|
170
|
-
if response.status_code in [
|
|
171
|
-
|
|
242
|
+
if response.status_code in [
|
|
243
|
+
400,
|
|
244
|
+
401,
|
|
245
|
+
403,
|
|
246
|
+
405,
|
|
247
|
+
406,
|
|
248
|
+
407,
|
|
249
|
+
409,
|
|
250
|
+
410,
|
|
251
|
+
415,
|
|
252
|
+
429,
|
|
253
|
+
501,
|
|
254
|
+
503,
|
|
255
|
+
]:
|
|
256
|
+
http_error_msg = f"{response.status_code} Client Error: {response.reason} for url: {response.url}"
|
|
172
257
|
raise PaywayError(code=response.status_code, message=http_error_msg)
|
|
173
258
|
|
|
174
|
-
|
|
259
|
+
if response.status_code in [404, 422]: # Documented PayWay errors in JSON
|
|
175
260
|
# parse error message
|
|
176
|
-
|
|
177
|
-
payway_errors = PaymentError().from_dict(errors)
|
|
178
|
-
# instead of raising an exception, return the specific PayWay errors as a list
|
|
179
|
-
return payway_errors
|
|
261
|
+
return PaymentError().from_dict(response.json())
|
|
180
262
|
|
|
181
|
-
|
|
182
|
-
|
|
263
|
+
if response.status_code == 500:
|
|
264
|
+
try:
|
|
265
|
+
errors = response.json()
|
|
266
|
+
except json.JSONDecodeError:
|
|
267
|
+
raise PaywayError(
|
|
268
|
+
code=response.status_code,
|
|
269
|
+
message="Internal server error",
|
|
270
|
+
)
|
|
271
|
+
# Documented PayWay server errors in JSON
|
|
183
272
|
payway_error = ServerError().from_dict(errors)
|
|
184
273
|
message = payway_error.to_message()
|
|
185
274
|
raise PaywayError(code=response.status_code, message=message)
|
|
186
275
|
|
|
187
|
-
|
|
188
|
-
return None
|
|
276
|
+
return None
|
|
189
277
|
|
|
190
|
-
def get_transaction(self, transaction_id):
|
|
278
|
+
def get_transaction(self, transaction_id: int) -> tuple[PayWayTransaction, list]:
|
|
191
279
|
"""
|
|
192
280
|
Lookup and return a transaction if found in PayWay
|
|
193
281
|
:param transaction_id: str A PayWay transaction ID
|
|
194
282
|
"""
|
|
195
|
-
endpoint =
|
|
283
|
+
endpoint = f"{TRANSACTION_URL}/{transaction_id}"
|
|
196
284
|
response = self.get_request(endpoint)
|
|
197
|
-
logger.info('Response from server: %s' % response)
|
|
198
285
|
errors = self._validate_response(response)
|
|
199
286
|
if errors:
|
|
200
287
|
return None, errors
|
|
201
|
-
|
|
202
|
-
transaction = PayWayTransaction.from_dict(response.json())
|
|
288
|
+
transaction = PayWayTransaction.from_dict(response.json())
|
|
203
289
|
return transaction, errors
|
|
204
290
|
|
|
205
|
-
def void_transaction(self, transaction_id):
|
|
291
|
+
def void_transaction(self, transaction_id: int, idempotency_key: str | None = None) -> tuple[PayWayTransaction, list]:
|
|
206
292
|
"""
|
|
207
293
|
Void a transaction in PayWay
|
|
208
294
|
:param transaction_id: str A PayWay transaction ID
|
|
295
|
+
:param idempotency_key: str: unique value to avoid duplicate POSTs
|
|
209
296
|
"""
|
|
210
|
-
endpoint =
|
|
211
|
-
response = self.post_request(endpoint, data={})
|
|
297
|
+
endpoint = f"{TRANSACTION_URL}/{transaction_id}/void"
|
|
298
|
+
response = self.post_request(endpoint, data={}, idempotency_key=idempotency_key)
|
|
212
299
|
errors = self._validate_response(response)
|
|
213
300
|
if errors:
|
|
214
301
|
return None, errors
|
|
215
|
-
|
|
216
|
-
transaction = PayWayTransaction.from_dict(response.json())
|
|
302
|
+
transaction = PayWayTransaction.from_dict(response.json())
|
|
217
303
|
return transaction, errors
|
|
218
304
|
|
|
219
|
-
def refund_transaction(
|
|
305
|
+
def refund_transaction(
|
|
306
|
+
self,
|
|
307
|
+
transaction_id: int,
|
|
308
|
+
amount: float,
|
|
309
|
+
order_id: str | None = None,
|
|
310
|
+
ip_address: str | None = None,
|
|
311
|
+
idempotency_key: str | None = None,
|
|
312
|
+
) -> tuple[PayWayTransaction, list]:
|
|
220
313
|
"""
|
|
221
314
|
Refund a transaction in PayWay
|
|
222
315
|
:param transaction_id: str A PayWay transaction ID
|
|
223
316
|
:param amount: str amount to refund
|
|
224
317
|
:param order_id: str optional reference number
|
|
225
318
|
:param ip_address: str optional IP address
|
|
319
|
+
:param idempotency_key: str: unique value to avoid duplicate POSTs
|
|
226
320
|
"""
|
|
227
|
-
endpoint = TRANSACTION_URL
|
|
228
321
|
data = {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
322
|
+
"transactionType": "refund",
|
|
323
|
+
"parentTransactionId": transaction_id,
|
|
324
|
+
"principalAmount": amount,
|
|
232
325
|
}
|
|
233
326
|
if order_id:
|
|
234
|
-
data[
|
|
327
|
+
data["orderNumber"] = order_id
|
|
235
328
|
if ip_address:
|
|
236
|
-
data[
|
|
237
|
-
response = self.post_request(
|
|
329
|
+
data["customerIpAddress"] = ip_address
|
|
330
|
+
response = self.post_request(TRANSACTION_URL, data, idempotency_key=idempotency_key)
|
|
238
331
|
errors = self._validate_response(response)
|
|
239
332
|
if errors:
|
|
240
333
|
return None, errors
|
|
241
|
-
|
|
242
|
-
transaction = PayWayTransaction.from_dict(response)
|
|
334
|
+
transaction = PayWayTransaction.from_dict(response.json())
|
|
243
335
|
return transaction, errors
|
|
244
336
|
|
|
245
|
-
def get_customer(self, customer_id):
|
|
337
|
+
def get_customer(self, customer_id: str) -> tuple[PayWayCustomer, list]:
|
|
246
338
|
"""
|
|
247
339
|
Returns a PayWay Customer's Payment Setup, [Payment] Schedule, Contact Details, Custom Fields and Notes
|
|
248
340
|
:param customer_id str PayWay customer ID in PayWay system
|
|
249
341
|
"""
|
|
250
|
-
endpoint =
|
|
342
|
+
endpoint = f"{CUSTOMER_URL}/{customer_id}"
|
|
251
343
|
response = self.get_request(endpoint)
|
|
252
344
|
errors = self._validate_response(response)
|
|
253
345
|
if errors:
|
|
254
346
|
return None, errors
|
|
255
|
-
|
|
256
|
-
customer = PayWayCustomer.from_dict(response.json())
|
|
347
|
+
customer = PayWayCustomer.from_dict(response.json())
|
|
257
348
|
return customer, errors
|
|
258
349
|
|
|
259
|
-
def update_payment_setup(self, token, customer_id):
|
|
350
|
+
def update_payment_setup(self, token: str, customer_id: str) -> tuple[PaymentSetup, str]:
|
|
260
351
|
"""
|
|
261
352
|
Updates the Customer's Payment Setup with a new Credit Card or Bank Account.
|
|
262
353
|
:param token: PayWay credit card or bank account token
|
|
263
354
|
:param customer_id: PayWay customer ID
|
|
264
355
|
"""
|
|
265
|
-
endpoint =
|
|
356
|
+
endpoint = f"{CUSTOMER_URL}/{customer_id}/payment-setup"
|
|
266
357
|
data = {
|
|
267
358
|
"singleUseTokenId": token,
|
|
268
359
|
"merchantId": self.merchant_id,
|
|
269
|
-
"bankAccountId": self.bank_account_id
|
|
360
|
+
"bankAccountId": self.bank_account_id,
|
|
270
361
|
}
|
|
271
362
|
response = self.put_request(endpoint, data)
|
|
272
363
|
errors = self._validate_response(response)
|
|
273
364
|
if errors:
|
|
274
365
|
return None, errors
|
|
275
|
-
|
|
276
|
-
ps = PaymentSetup.from_dict(response.json())
|
|
366
|
+
ps = PaymentSetup.from_dict(response.json())
|
|
277
367
|
return ps, errors
|
payway/conf.py
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
PAYWAY_API_URL =
|
|
4
|
-
TOKEN_URL = PAYWAY_API_URL +
|
|
5
|
-
TRANSACTION_URL = PAYWAY_API_URL +
|
|
6
|
-
CUSTOMER_URL = PAYWAY_API_URL +
|
|
7
|
-
OWN_BANK_ACCOUNTS_URL = PAYWAY_API_URL +
|
|
8
|
-
TOKEN_NO_REDIRECT = PAYWAY_API_URL +
|
|
9
|
-
|
|
10
|
-
PUBLISHABLE_API_KEY = os.getenv('PAYWAY_PUBLISHABLE_API_KEY')
|
|
11
|
-
SECRET_API_KEY = os.getenv('PAYWAY_SECRET_API_KEY')
|
|
3
|
+
PAYWAY_API_URL = "https://api.payway.com.au/rest/v1"
|
|
4
|
+
TOKEN_URL = PAYWAY_API_URL + "/single-use-tokens-redirect"
|
|
5
|
+
TRANSACTION_URL = PAYWAY_API_URL + "/transactions"
|
|
6
|
+
CUSTOMER_URL = PAYWAY_API_URL + "/customers"
|
|
7
|
+
OWN_BANK_ACCOUNTS_URL = PAYWAY_API_URL + "/your-bank-accounts"
|
|
8
|
+
TOKEN_NO_REDIRECT = PAYWAY_API_URL + "/single-use-tokens"
|