python-payway 0.0.4__tar.gz → 0.0.5__tar.gz

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.
Files changed (24) hide show
  1. {python_payway-0.0.4 → python_payway-0.0.5}/PKG-INFO +1 -1
  2. {python_payway-0.0.4 → python_payway-0.0.5}/payway/client.py +30 -21
  3. {python_payway-0.0.4 → python_payway-0.0.5}/payway/customers.py +3 -1
  4. {python_payway-0.0.4 → python_payway-0.0.5}/payway/exceptions.py +6 -6
  5. {python_payway-0.0.4 → python_payway-0.0.5}/payway/model.py +78 -78
  6. {python_payway-0.0.4 → python_payway-0.0.5}/payway/test_utils.py +2 -1
  7. {python_payway-0.0.4 → python_payway-0.0.5}/pyproject.toml +2 -2
  8. {python_payway-0.0.4 → python_payway-0.0.5}/python_payway.egg-info/PKG-INFO +1 -1
  9. {python_payway-0.0.4 → python_payway-0.0.5}/tests/test_client.py +15 -16
  10. {python_payway-0.0.4 → python_payway-0.0.5}/tests/test_customers.py +8 -9
  11. {python_payway-0.0.4 → python_payway-0.0.5}/tests/test_transactions.py +2 -3
  12. {python_payway-0.0.4 → python_payway-0.0.5}/LICENSE +0 -0
  13. {python_payway-0.0.4 → python_payway-0.0.5}/README.md +0 -0
  14. {python_payway-0.0.4 → python_payway-0.0.5}/payway/__init__.py +0 -0
  15. {python_payway-0.0.4 → python_payway-0.0.5}/payway/conf.py +0 -0
  16. {python_payway-0.0.4 → python_payway-0.0.5}/payway/constants.py +0 -0
  17. {python_payway-0.0.4 → python_payway-0.0.5}/payway/transactions.py +0 -0
  18. {python_payway-0.0.4 → python_payway-0.0.5}/payway/utils.py +0 -0
  19. {python_payway-0.0.4 → python_payway-0.0.5}/python_payway.egg-info/SOURCES.txt +0 -0
  20. {python_payway-0.0.4 → python_payway-0.0.5}/python_payway.egg-info/dependency_links.txt +0 -0
  21. {python_payway-0.0.4 → python_payway-0.0.5}/python_payway.egg-info/requires.txt +0 -0
  22. {python_payway-0.0.4 → python_payway-0.0.5}/python_payway.egg-info/top_level.txt +0 -0
  23. {python_payway-0.0.4 → python_payway-0.0.5}/setup.cfg +0 -0
  24. {python_payway-0.0.4 → python_payway-0.0.5}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-payway
3
- Version: 0.0.4
3
+ Version: 0.0.5
4
4
  Summary: Python client for working with Westpac's PayWay REST API
5
5
  Author-email: Ben Napper <reppan197@gmail.com>
6
6
  License: MIT
@@ -2,7 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  from logging import getLogger
5
- from typing import NoReturn
5
+ from typing import Any
6
6
 
7
7
  import requests
8
8
 
@@ -46,7 +46,7 @@ class Client(CustomerRequest, TransactionRequest):
46
46
  bank_account_id: str,
47
47
  secret_api_key: str,
48
48
  publishable_api_key: str,
49
- ) -> NoReturn:
49
+ ) -> None:
50
50
  """
51
51
  :param merchant_id : str = PayWay Merchant ID
52
52
  :param bank_account_id : str = PayWay Bank Account ID
@@ -66,8 +66,7 @@ class Client(CustomerRequest, TransactionRequest):
66
66
 
67
67
  session = requests.Session()
68
68
  session.auth = (self.secret_api_key, "")
69
- headers = {"content-type": "application/x-www-form-urlencoded"}
70
- session.headers = headers
69
+ session.headers = {"content-type": "application/x-www-form-urlencoded"}
71
70
  self.session = session
72
71
  session_no_headers = requests.Session()
73
72
  session_no_headers.auth = session.auth
@@ -79,7 +78,7 @@ class Client(CustomerRequest, TransactionRequest):
79
78
  bank_account_id: str,
80
79
  secret_api_key: str,
81
80
  publishable_api_key: str,
82
- ) -> NoReturn:
81
+ ) -> None:
83
82
  if not merchant_id or not bank_account_id or not secret_api_key or not publishable_api_key:
84
83
  if not secret_api_key or not publishable_api_key:
85
84
  logger.error("PayWay API keys not found")
@@ -99,7 +98,7 @@ class Client(CustomerRequest, TransactionRequest):
99
98
  return requests.get(url=endpoint, auth=(self.secret_api_key, ""), timeout=30)
100
99
 
101
100
  def post_request(
102
- self, endpoint: str, data: dict, auth: tuple | None = None, idempotency_key: str | None = None
101
+ self, endpoint: str, data: dict[str, Any], auth: tuple[str, str] | None = None, idempotency_key: str | None = None
103
102
  ) -> requests.Response:
104
103
  """
105
104
  Supply an idempotency_key to avoid duplicate POSTs
@@ -112,7 +111,7 @@ class Client(CustomerRequest, TransactionRequest):
112
111
  headers["Idempotency-Key"] = idempotency_key
113
112
  return requests.post(url=endpoint, auth=auth, data=data, headers=headers, timeout=30)
114
113
 
115
- def put_request(self, endpoint: str, data: dict) -> requests.Response:
114
+ def put_request(self, endpoint: str, data: dict[str, Any]) -> requests.Response:
116
115
  return requests.put(
117
116
  url=endpoint,
118
117
  auth=(self.secret_api_key, ""),
@@ -123,7 +122,7 @@ class Client(CustomerRequest, TransactionRequest):
123
122
 
124
123
  def create_token(
125
124
  self, payway_obj: BankAccount | PayWayCard, payment_method: str, idempotency_key: str | None = None
126
- ) -> tuple[TokenResponse, list]:
125
+ ) -> tuple[TokenResponse | None, list[PaymentError] | None]:
127
126
  """
128
127
  Creates a single use token for a Customer's payment setup (credit card or bank account)
129
128
  :param payway_obj: object: one of model.PayWayCard or model.BankAccount object
@@ -160,14 +159,18 @@ class Client(CustomerRequest, TransactionRequest):
160
159
  token_response = TokenResponse().from_dict(response.json())
161
160
  return token_response, errors
162
161
 
163
- def create_card_token(self, card: PayWayCard, idempotency_key: str | None = None) -> tuple[TokenResponse, list]:
162
+ def create_card_token(
163
+ self, card: PayWayCard, idempotency_key: str | None = None
164
+ ) -> tuple[TokenResponse | None, list[PaymentError] | None]:
164
165
  """
165
166
  :param card: PayWayCard object represents a customer's credit card details
166
167
  :param idempotency_key: str: unique value to avoid duplicate POSTs
167
168
  """
168
169
  return self.create_token(card, "card", idempotency_key=idempotency_key)
169
170
 
170
- def create_bank_account_token(self, bank_account: BankAccount, idempotency_key: str | None = None) -> str:
171
+ def create_bank_account_token(
172
+ self, bank_account: BankAccount, idempotency_key: str | None = None
173
+ ) -> tuple[TokenResponse | None, list[PaymentError] | None]:
171
174
  """
172
175
  :param bank_account: BankAccount object represents a customer's bank account
173
176
  :param idempotency_key: str: unique value to avoid duplicate POSTs
@@ -179,7 +182,9 @@ class Client(CustomerRequest, TransactionRequest):
179
182
  idempotency_key=idempotency_key,
180
183
  )
181
184
 
182
- def create_customer(self, customer: PayWayCustomer, idempotency_key: str | None = None) -> tuple[PayWayCustomer | None, list]:
185
+ def create_customer(
186
+ self, customer: PayWayCustomer, idempotency_key: str | None = None
187
+ ) -> tuple[PayWayCustomer | None, list[PaymentError] | None]:
183
188
  """
184
189
  Create a customer in PayWay system
185
190
 
@@ -217,7 +222,9 @@ class Client(CustomerRequest, TransactionRequest):
217
222
  customer = PayWayCustomer().from_dict(response.json())
218
223
  return customer, errors
219
224
 
220
- def process_payment(self, payment: PayWayPayment, idempotency_key: str | None = None) -> tuple[PayWayTransaction, list]:
225
+ def process_payment(
226
+ self, payment: PayWayPayment, idempotency_key: str | None = None
227
+ ) -> tuple[PayWayTransaction | None, list[PaymentError] | None]:
221
228
  """
222
229
  Process an individual payment against a Customer with active Recurring Billing setup.
223
230
  :param payment: PayWayPayment object (see model.PayWayPayment)
@@ -234,7 +241,7 @@ class Client(CustomerRequest, TransactionRequest):
234
241
  transaction = PayWayTransaction.from_dict(response.json())
235
242
  return transaction, errors
236
243
 
237
- def _validate_response(self, response: requests.Response) -> list | None:
244
+ def _validate_response(self, response: requests.Response) -> list[PaymentError] | None:
238
245
  """
239
246
  Validates all responses from PayWay to catch documented PayWay errors.
240
247
  :param response: requests response object
@@ -254,7 +261,7 @@ class Client(CustomerRequest, TransactionRequest):
254
261
  503,
255
262
  ]:
256
263
  http_error_msg = f"{response.status_code} Client Error: {response.reason} for url: {response.url}"
257
- raise PaywayError(code=response.status_code, message=http_error_msg)
264
+ raise PaywayError(code=str(response.status_code), message=http_error_msg)
258
265
 
259
266
  if response.status_code in [404, 422]: # Documented PayWay errors in JSON
260
267
  # parse error message
@@ -265,17 +272,17 @@ class Client(CustomerRequest, TransactionRequest):
265
272
  errors = response.json()
266
273
  except json.JSONDecodeError:
267
274
  raise PaywayError(
268
- code=response.status_code,
275
+ code=str(response.status_code),
269
276
  message="Internal server error",
270
277
  )
271
278
  # Documented PayWay server errors in JSON
272
279
  payway_error = ServerError().from_dict(errors)
273
280
  message = payway_error.to_message()
274
- raise PaywayError(code=response.status_code, message=message)
281
+ raise PaywayError(code=str(response.status_code), message=message)
275
282
 
276
283
  return None
277
284
 
278
- def get_transaction(self, transaction_id: int) -> tuple[PayWayTransaction, list]:
285
+ def get_transaction(self, transaction_id: int) -> tuple[PayWayTransaction | None, list[PaymentError] | None]:
279
286
  """
280
287
  Lookup and return a transaction if found in PayWay
281
288
  :param transaction_id: str A PayWay transaction ID
@@ -288,7 +295,9 @@ class Client(CustomerRequest, TransactionRequest):
288
295
  transaction = PayWayTransaction.from_dict(response.json())
289
296
  return transaction, errors
290
297
 
291
- def void_transaction(self, transaction_id: int, idempotency_key: str | None = None) -> tuple[PayWayTransaction, list]:
298
+ def void_transaction(
299
+ self, transaction_id: int, idempotency_key: str | None = None
300
+ ) -> tuple[PayWayTransaction | None, list[PaymentError] | None]:
292
301
  """
293
302
  Void a transaction in PayWay
294
303
  :param transaction_id: str A PayWay transaction ID
@@ -309,7 +318,7 @@ class Client(CustomerRequest, TransactionRequest):
309
318
  order_id: str | None = None,
310
319
  ip_address: str | None = None,
311
320
  idempotency_key: str | None = None,
312
- ) -> tuple[PayWayTransaction, list]:
321
+ ) -> tuple[PayWayTransaction | None, list[PaymentError] | None]:
313
322
  """
314
323
  Refund a transaction in PayWay
315
324
  :param transaction_id: str A PayWay transaction ID
@@ -334,7 +343,7 @@ class Client(CustomerRequest, TransactionRequest):
334
343
  transaction = PayWayTransaction.from_dict(response.json())
335
344
  return transaction, errors
336
345
 
337
- def get_customer(self, customer_id: str) -> tuple[PayWayCustomer, list]:
346
+ def get_customer(self, customer_id: str) -> tuple[PayWayCustomer | None, list[PaymentError] | None]:
338
347
  """
339
348
  Returns a PayWay Customer's Payment Setup, [Payment] Schedule, Contact Details, Custom Fields and Notes
340
349
  :param customer_id str PayWay customer ID in PayWay system
@@ -347,7 +356,7 @@ class Client(CustomerRequest, TransactionRequest):
347
356
  customer = PayWayCustomer.from_dict(response.json())
348
357
  return customer, errors
349
358
 
350
- def update_payment_setup(self, token: str, customer_id: str) -> tuple[PaymentSetup, str]:
359
+ def update_payment_setup(self, token: str, customer_id: str) -> tuple[PaymentSetup | None, list[PaymentError] | None]:
351
360
  """
352
361
  Updates the Customer's Payment Setup with a new Credit Card or Bank Account.
353
362
  :param token: PayWay credit card or bank account token
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from typing import Any
4
+
3
5
  import requests
4
6
 
5
7
  from payway.conf import CUSTOMER_URL
@@ -79,7 +81,7 @@ class CustomerRequest:
79
81
 
80
82
  @json_list("update_contact_details")
81
83
  def update_contact_details(
82
- self, customer_number: int, customer: PayWayCustomer | None = None, **options: dict
84
+ self, customer_number: int, customer: PayWayCustomer | None = None, **options: dict[str, Any]
83
85
  ) -> requests.Response:
84
86
  """
85
87
  param: customer_number: PayWay customer number
@@ -1,13 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import NoReturn
3
+ from typing import Any
4
4
 
5
5
 
6
6
  class PaywayError(Exception):
7
- _code: str = None
8
- _message: str = None
7
+ _code: str = ""
8
+ _message: str = ""
9
9
 
10
- def __init__(self, code: str, message: str, *args: dict, **kwargs: dict) -> NoReturn:
10
+ def __init__(self, code: str, message: str, *args: dict[str, Any], **kwargs: dict[str, Any]) -> None:
11
11
  """
12
12
  code : str = PayWay API response/error code
13
13
  message : str = appropriate message
@@ -16,7 +16,7 @@ class PaywayError(Exception):
16
16
  super().__init__(*args, **kwargs)
17
17
 
18
18
  self._code = code
19
- self._message = f"{code}: {message}".encode()
19
+ self._message = f"{code}: {message}"
20
20
 
21
21
  def __str__(self) -> str:
22
- return self.message
22
+ return self._message
@@ -48,7 +48,7 @@ class PayWayCard:
48
48
  }
49
49
 
50
50
  @staticmethod
51
- def from_dict(payway_card: dict) -> PayWayCard:
51
+ def from_dict(payway_card: dict[str, Any]) -> PayWayCard:
52
52
  card = PayWayCard()
53
53
  if payway_card.get("maskedCardNumber"):
54
54
  card.card_number = payway_card.get("maskedCardNumber")
@@ -124,14 +124,14 @@ class PayWayCustomer:
124
124
  return customer
125
125
 
126
126
  @staticmethod
127
- def from_dict(response: dict) -> PayWayCustomer:
127
+ def from_dict(response: dict[str, Any]) -> PayWayCustomer:
128
128
  """
129
129
  Parse PayWay Customer response data
130
130
  :param response: dict PayWay response dictionary
131
131
  :return:
132
132
  """
133
133
  customer = PayWayCustomer()
134
- contact = response.get("contact")
134
+ contact = response.get("contact", {})
135
135
  customer.customer_name = contact.get("customerName")
136
136
  customer.email_address = contact.get("emailAddress")
137
137
  customer.send_email_receipts = contact.get("sendEmailReceipts")
@@ -146,11 +146,11 @@ class PayWayCustomer:
146
146
 
147
147
  if response.get("paymentSetup") is not None:
148
148
  customer.payment_setup = PaymentSetup().from_dict(
149
- response.get("paymentSetup"),
149
+ response.get("paymentSetup", {}),
150
150
  )
151
151
 
152
152
  if response.get("customFields") is not None:
153
- custom_fields = response.get("customFields")
153
+ custom_fields = response.get("customFields", {})
154
154
  for k, v in custom_fields.items():
155
155
  setattr(customer, k, v)
156
156
 
@@ -161,17 +161,17 @@ class PayWayCustomer:
161
161
 
162
162
 
163
163
  class PaymentError:
164
- field_name: str = None
165
- message: str = None
166
- field_value: str = None
164
+ field_name: str | None = None
165
+ message: str | None = None
166
+ field_value: str | None = None
167
167
 
168
168
  @staticmethod
169
- def from_dict(payway_response: dict) -> list:
169
+ def from_dict(payway_response: dict[str, Any]) -> list[PaymentError]:
170
170
  """
171
171
  Returns a list of errors from PayWay
172
172
  :param: payway_response: dict PayWay response dictionary
173
173
  """
174
- errors = payway_response.get("data")
174
+ errors = payway_response.get("data", [])
175
175
  payment_errors = []
176
176
  for error in errors:
177
177
  payway_error = PaymentError()
@@ -200,17 +200,17 @@ class PaymentError:
200
200
 
201
201
 
202
202
  class ServerError:
203
- error_number: int = None
204
- trace_code: str = None
203
+ error_number: int | None = None
204
+ trace_code: str | None = None
205
205
 
206
206
  @staticmethod
207
- def from_dict(response: dict) -> ServerError:
207
+ def from_dict(response: dict[str, Any]) -> ServerError:
208
208
  """
209
209
  :param: response: dict PayWay response dictionary
210
210
  """
211
211
  payway_error = ServerError()
212
- payway_error.error_number = response.get("errorNumber")
213
- payway_error.trace_code = response.get("traceCode")
212
+ payway_error.error_number = response.get("errorNumber", {})
213
+ payway_error.trace_code = response.get("traceCode", {})
214
214
  return payway_error
215
215
 
216
216
  def to_message(self) -> str:
@@ -233,8 +233,8 @@ class PayWayPayment:
233
233
  def __init__(
234
234
  self,
235
235
  transaction_type: str,
236
- customer_number: int | None = None,
237
- amount: int | None = None,
236
+ customer_number: str | None = None,
237
+ amount: float | None = None,
238
238
  currency: str | None = None,
239
239
  order_number: str | None = None,
240
240
  ip_address: str | None = None,
@@ -272,42 +272,42 @@ class PayWayPayment:
272
272
 
273
273
 
274
274
  class PayWayTransaction:
275
- transaction_id: int = None
276
- receipt_number: str = None
277
- status: str = None
278
- response_code: str = None
279
- response_text: str = None
280
- transaction_type: str = None
281
- customer_number: str = None
282
- customer_name: str = None
283
- customer_email: str = None
284
- bpay_ref: str = None
285
- order_number: str = None
286
- currency: str = None
287
- principal_amount: float = None
288
- surcharge_amount: float = None
289
- payment_amount: float = None
290
- payment_method: str = None
291
- declined_date: str = None
292
- card: PayWayCard = None
293
- merchant: Merchant = None
294
- virtual_account: dict = None
295
- australia_post: dict = None
296
- bpay: dict = None
297
- your_bank_account: dict = None
298
- customer_paypal_account: dict = None
299
- your_paypal_account: dict = None
300
- transaction_date_time: str = None
301
- user: dict = None
302
- settlement_date: str = None
303
- parent_transaction: dict = None
304
- ip_address: str = None
305
- fraud_result: str = None
306
- ip_country: str = None
307
- card_country: str = None
308
- custom_fields: dict = None
309
- is_voidable: bool = None
310
- is_refundable: bool = None
275
+ transaction_id: int | None = None
276
+ receipt_number: str | None = None
277
+ status: str | None = None
278
+ response_code: str | None = None
279
+ response_text: str | None = None
280
+ transaction_type: str | None = None
281
+ customer_number: str | None = None
282
+ customer_name: str | None = None
283
+ customer_email: str | None = None
284
+ bpay_ref: str | None = None
285
+ order_number: str | None = None
286
+ currency: str | None = None
287
+ principal_amount: float | None = None
288
+ surcharge_amount: float | None = None
289
+ payment_amount: float | None = None
290
+ payment_method: str | None = None
291
+ declined_date: str | None = None
292
+ card: PayWayCard | None = None
293
+ merchant: Merchant | None = None
294
+ virtual_account: dict[str, Any] | None = None
295
+ australia_post: dict[str, Any] | None = None
296
+ bpay: dict[str, Any] | None = None
297
+ your_bank_account: dict[str, Any] | None = None
298
+ customer_paypal_account: dict[str, Any] | None = None
299
+ your_paypal_account: dict[str, Any] | None = None
300
+ transaction_date_time: str | None = None
301
+ user: dict[str, Any] | None = None
302
+ settlement_date: str | None = None
303
+ parent_transaction: dict[str, Any] | None = None
304
+ ip_address: str | None = None
305
+ fraud_result: str | None = None
306
+ ip_country: str | None = None
307
+ card_country: str | None = None
308
+ custom_fields: dict[str, Any] | None = None
309
+ is_voidable: bool | None = None
310
+ is_refundable: bool | None = None
311
311
 
312
312
  def to_dict(self) -> dict[str, Any]:
313
313
  return {
@@ -325,8 +325,8 @@ class PayWayTransaction:
325
325
  "surchargeAmount": self.surcharge_amount,
326
326
  "paymentAmount": self.payment_amount,
327
327
  "paymentMethod": self.payment_method,
328
- "creditCard": self.card.to_dict(),
329
- "merchant": self.merchant.to_dict(),
328
+ "creditCard": self.card.to_dict() if self.card is not None else {},
329
+ "merchant": self.merchant.to_dict() if self.merchant is not None else {},
330
330
  "virtualAccount": self.virtual_account,
331
331
  "bpaustraliaPostay": self.australia_post,
332
332
  "bpay": self.bpay,
@@ -348,7 +348,7 @@ class PayWayTransaction:
348
348
  }
349
349
 
350
350
  @staticmethod
351
- def from_dict(response: dict) -> PayWayTransaction:
351
+ def from_dict(response: dict[str, Any]) -> PayWayTransaction:
352
352
  """
353
353
  :param: response: dict PayWay response dictionary
354
354
  """
@@ -369,10 +369,10 @@ class PayWayTransaction:
369
369
  transaction.payment_method = response.get("paymentMethod")
370
370
 
371
371
  if response.get("creditCard") is not None:
372
- transaction.card = PayWayCard.from_dict(response.get("creditCard"))
372
+ transaction.card = PayWayCard.from_dict(response.get("creditCard", {}))
373
373
 
374
374
  if response.get("merchant") is not None:
375
- transaction.merchant = Merchant.from_dict(response.get("merchant"))
375
+ transaction.merchant = Merchant.from_dict(response.get("merchant", {}))
376
376
 
377
377
  transaction.virtual_account = response.get("virtualAccount")
378
378
  transaction.australia_post = response.get("bpaustraliaPostay")
@@ -406,14 +406,14 @@ class Merchant:
406
406
  account
407
407
  """
408
408
 
409
- merchant_id: str = None
410
- merchant_name: str = None
411
- settlement_bsb: str = None
412
- settlement_account_number: str = None
413
- surcharge_bsb: str = None
414
- surcharge_account_number: str = None
409
+ merchant_id: str | None = None
410
+ merchant_name: str | None = None
411
+ settlement_bsb: str | None = None
412
+ settlement_account_number: str | None = None
413
+ surcharge_bsb: str | None = None
414
+ surcharge_account_number: str | None = None
415
415
 
416
- def to_dict(self) -> dict[str, None]:
416
+ def to_dict(self) -> dict[str, Any]:
417
417
  return {
418
418
  "merchantId": self.merchant_id,
419
419
  "merchantName": self.merchant_name,
@@ -424,7 +424,7 @@ class Merchant:
424
424
  }
425
425
 
426
426
  @staticmethod
427
- def from_dict(payway_obj: dict) -> Merchant:
427
+ def from_dict(payway_obj: dict[str, Any]) -> Merchant:
428
428
  """
429
429
  :param: payway_obj: dict PayWay response dictionary
430
430
  """
@@ -439,13 +439,13 @@ class Merchant:
439
439
 
440
440
 
441
441
  class PaymentSetup:
442
- payment_method: str = None
443
- stopped: bool = None
444
- credit_card: PayWayCard = None
445
- merchant: Merchant = None
442
+ payment_method: str | None = None
443
+ stopped: bool | None = None
444
+ credit_card: PayWayCard | None = None
445
+ merchant: Merchant | None = None
446
446
 
447
447
  @staticmethod
448
- def from_dict(response: dict) -> PaymentSetup:
448
+ def from_dict(response: dict[str, Any]) -> PaymentSetup:
449
449
  """
450
450
  :param: response: dict PayWay response dictionary
451
451
  """
@@ -453,20 +453,20 @@ class PaymentSetup:
453
453
  ps.payment_method = response.get("paymentMethod")
454
454
  ps.stopped = response.get("stopped")
455
455
  if response.get("creditCard") is not None:
456
- ps.credit_card = PayWayCard().from_dict(response.get("creditCard"))
456
+ ps.credit_card = PayWayCard().from_dict(response.get("creditCard", {}))
457
457
  if response.get("merchant") is not None:
458
- ps.merchant = Merchant().from_dict(response.get("merchant"))
458
+ ps.merchant = Merchant().from_dict(response.get("merchant", {}))
459
459
  return ps
460
460
 
461
461
 
462
462
  class TokenResponse:
463
- token: str = None
464
- payment_method: str = None
465
- card: PayWayCard = None
466
- bank_account: dict = None
463
+ token: str | None = None
464
+ payment_method: str | None = None
465
+ card: PayWayCard | None = None
466
+ bank_account: dict[str, Any] | None = None
467
467
 
468
468
  @staticmethod
469
- def from_dict(response: dict) -> TokenResponse:
469
+ def from_dict(response: dict[str, Any]) -> TokenResponse:
470
470
  """
471
471
  :param: response: dict PayWay response dictionary
472
472
  """
@@ -2,9 +2,10 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import pathlib
5
+ from typing import Any
5
6
 
6
7
 
7
- def load_json_file(file_path: str) -> dict:
8
+ def load_json_file(file_path: str) -> dict[str, Any]:
8
9
  file = pathlib.Path(file_path)
9
10
  with open(file) as f:
10
11
  return json.load(f)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-payway"
7
- version = "0.0.4"
7
+ version = "0.0.5"
8
8
  description = "Python client for working with Westpac's PayWay REST API"
9
9
  authors = [
10
10
  { name = "Ben Napper", email = "reppan197@gmail.com" }
@@ -114,7 +114,7 @@ exclude = ["__init__.py"]
114
114
  required-imports = ["from __future__ import annotations"]
115
115
 
116
116
  [tool.pyright]
117
- typeCheckingMode = "off"
117
+ typeCheckingMode = "strict"
118
118
 
119
119
  [tool.pytest.ini_options]
120
120
  log_cli = true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-payway
3
- Version: 0.0.4
3
+ Version: 0.0.5
4
4
  Summary: Python client for working with Westpac's PayWay REST API
5
5
  Author-email: Ben Napper <reppan197@gmail.com>
6
6
  License: MIT
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import copy
4
4
  import unittest
5
- from typing import NoReturn
6
5
  from unittest.mock import patch
7
6
 
8
7
  from payway.client import Client
@@ -18,7 +17,7 @@ from payway.test_utils import load_json_file
18
17
 
19
18
  class TestClient(unittest.TestCase):
20
19
  @classmethod
21
- def setUpClass(cls) -> NoReturn:
20
+ def setUpClass(cls) -> None:
22
21
  merchant_id = "TEST"
23
22
  bank_account_id = "0000000A"
24
23
  publishable_api_key = "TPUBLISHABLE-API-KEY"
@@ -72,7 +71,7 @@ class TestClient(unittest.TestCase):
72
71
  cls.payment = PayWayPayment(
73
72
  customer_number="",
74
73
  transaction_type="payment",
75
- amount="10",
74
+ amount=10,
76
75
  currency="aud",
77
76
  order_number="5100",
78
77
  ip_address="127.0.0.1",
@@ -80,7 +79,7 @@ class TestClient(unittest.TestCase):
80
79
  cls.pre_auth_payment = PayWayPayment(
81
80
  customer_number="",
82
81
  transaction_type="preAuth",
83
- amount="2.15",
82
+ amount=2.15,
84
83
  currency="aud",
85
84
  order_number="5110",
86
85
  ip_address="127.0.0.1",
@@ -88,7 +87,7 @@ class TestClient(unittest.TestCase):
88
87
  cls.pre_auth_capture_payment = PayWayPayment(
89
88
  transaction_type="capture",
90
89
  parent_transaction_id="",
91
- amount="2.15",
90
+ amount=2.15,
92
91
  order_number="5111",
93
92
  ip_address="127.0.0.1",
94
93
  )
@@ -104,7 +103,7 @@ class TestClient(unittest.TestCase):
104
103
  )
105
104
 
106
105
  @patch("requests.post")
107
- def test_create_token(self, mock_post) -> NoReturn:
106
+ def test_create_token(self, mock_post) -> None:
108
107
  mock_post.return_value.status_code = 200
109
108
  mock_post.return_value.json.return_value = {
110
109
  "singleUseTokenId": "2bcec36f-7b02-43db-b3ec-bfb65acfe272",
@@ -118,7 +117,7 @@ class TestClient(unittest.TestCase):
118
117
  self.assertEqual(token_response.token, "2bcec36f-7b02-43db-b3ec-bfb65acfe272")
119
118
 
120
119
  @patch("requests.post")
121
- def test_create_bank_account_token(self, mock_post) -> NoReturn:
120
+ def test_create_bank_account_token(self, mock_post) -> None:
122
121
  mock_post.return_value.status_code = 200
123
122
  mock_post.return_value.json.return_value = {
124
123
  "singleUseTokenId": "3bcec36f-7b02-43db-b3ec-bfb65acfe272",
@@ -131,7 +130,7 @@ class TestClient(unittest.TestCase):
131
130
  self.assertEqual(token, "3bcec36f-7b02-43db-b3ec-bfb65acfe272")
132
131
 
133
132
  @patch("requests.post")
134
- def test_create_customer(self, mock_post) -> NoReturn:
133
+ def test_create_customer(self, mock_post) -> None:
135
134
  mock_post.return_value.status_code = 200
136
135
  mock_post.return_value.json.return_value = load_json_file("tests/data/customer.json")
137
136
  card = self.card
@@ -146,7 +145,7 @@ class TestClient(unittest.TestCase):
146
145
  self.assertEqual(payway_customer.email_address, "bect@example.net")
147
146
 
148
147
  @patch("requests.put")
149
- def test_create_customer_with_custom_id(self, mock_post) -> NoReturn:
148
+ def test_create_customer_with_custom_id(self, mock_post) -> None:
150
149
  mock_post.return_value.status_code = 200
151
150
  mock_post.return_value.json.return_value = load_json_file("tests/data/customer.json")
152
151
  customer = copy.deepcopy(self.customer)
@@ -158,7 +157,7 @@ class TestClient(unittest.TestCase):
158
157
  self.assertEqual(payway_customer_number, "98")
159
158
 
160
159
  @patch("requests.post")
161
- def test_process_payment(self, mock_post) -> NoReturn:
160
+ def test_process_payment(self, mock_post) -> None:
162
161
  # Take payment (using a credit card token)
163
162
  mock_post.return_value.status_code = 200
164
163
  mock_post.return_value.json.return_value = load_json_file("tests/data/transaction.json")
@@ -177,7 +176,7 @@ class TestClient(unittest.TestCase):
177
176
  self.assertEqual(transaction.response_code, "11")
178
177
 
179
178
  @patch("requests.post")
180
- def test_process_payment_with_idempotency_key(self, mock_post) -> NoReturn:
179
+ def test_process_payment_with_idempotency_key(self, mock_post) -> None:
181
180
  """
182
181
  Send a payment using a unique idempotency key to try and avoid duplicate POSTs
183
182
  https://www.payway.com.au/docs/rest.html#avoiding-duplicate-posts
@@ -204,7 +203,7 @@ class TestClient(unittest.TestCase):
204
203
  self.assertEqual(transaction.response_code, "11")
205
204
 
206
205
  @patch("requests.get")
207
- def test_get_transaction_card(self, mock_get) -> NoReturn:
206
+ def test_get_transaction_card(self, mock_get) -> None:
208
207
  mock_get.return_value.status_code = 200
209
208
  mock_get.return_value.json.return_value = load_json_file("tests/data/card_transaction.json")
210
209
  transaction, errors = self.client.get_transaction(
@@ -215,7 +214,7 @@ class TestClient(unittest.TestCase):
215
214
  self.assertEqual(transaction.transaction_id, 1179985404)
216
215
 
217
216
  @patch("requests.post")
218
- def test_void(self, mock_post) -> NoReturn:
217
+ def test_void(self, mock_post) -> None:
219
218
  mock_post.return_value.status_code = 200
220
219
  mock_post.return_value.json.return_value = load_json_file("tests/data/void_transaction.json")
221
220
  void_transaction, void_errors = self.client.void_transaction(1179985404)
@@ -224,7 +223,7 @@ class TestClient(unittest.TestCase):
224
223
  self.assertEqual(void_transaction.status, "voided")
225
224
 
226
225
  @patch("requests.post")
227
- def test_refund(self, mock_post) -> NoReturn:
226
+ def test_refund(self, mock_post) -> None:
228
227
  mock_post.return_value.status_code = 200
229
228
  mock_post.return_value.json.return_value = load_json_file("tests/data/refund_transaction.json")
230
229
  transaction, errors = self.client.refund_transaction(
@@ -235,7 +234,7 @@ class TestClient(unittest.TestCase):
235
234
  self.assertEqual(transaction.status, "refunded")
236
235
 
237
236
  @patch("requests.get")
238
- def test_get_customer(self, mock_get) -> NoReturn:
237
+ def test_get_customer(self, mock_get) -> None:
239
238
  mock_get.return_value.status_code = 200
240
239
  mock_get.return_value.json.return_value = load_json_file("tests/data/customer.json")
241
240
  customer, customer_errors = self.client.get_customer("98")
@@ -245,7 +244,7 @@ class TestClient(unittest.TestCase):
245
244
  self.assertEqual(customer.customer_name, "Rebecca Turing")
246
245
 
247
246
  @patch("requests.put")
248
- def test_update_payment_setup_card(self, mock_post) -> NoReturn:
247
+ def test_update_payment_setup_card(self, mock_post) -> None:
249
248
  # update card or bank account in PayWay from token
250
249
  mock_post.return_value.status_code = 200
251
250
  mock_post.return_value.json.return_value = {
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import datetime
4
4
  import unittest
5
- from typing import NoReturn
6
5
  from unittest.mock import patch
7
6
 
8
7
  from payway.client import Client
@@ -12,7 +11,7 @@ from payway.test_utils import load_json_file
12
11
 
13
12
  class TestCustomerRequest(unittest.TestCase):
14
13
  @classmethod
15
- def setUpClass(cls) -> NoReturn:
14
+ def setUpClass(cls) -> None:
16
15
  """
17
16
  You will need to create a sandbox PayWay account and add your sandbox API keys into your environment
18
17
  """
@@ -102,7 +101,7 @@ class TestCustomerRequest(unittest.TestCase):
102
101
  )
103
102
 
104
103
  @patch("requests.Session.patch")
105
- def test_stop_all_payments(self, mock_post) -> NoReturn:
104
+ def test_stop_all_payments(self, mock_post) -> None:
106
105
  # stop payments for customer
107
106
  mock_post.return_value.status_code = 200
108
107
  mock_post.return_value.json.return_value = {
@@ -113,7 +112,7 @@ class TestCustomerRequest(unittest.TestCase):
113
112
  self.assertEqual(stopped, True)
114
113
 
115
114
  @patch("requests.Session.patch")
116
- def test_start_all_payments(self, mock_post) -> NoReturn:
115
+ def test_start_all_payments(self, mock_post) -> None:
117
116
  # start payments for customer
118
117
  mock_post.return_value.status_code = 200
119
118
  mock_post.return_value.json.return_value = {
@@ -124,14 +123,14 @@ class TestCustomerRequest(unittest.TestCase):
124
123
  self.assertEqual(stopped, False)
125
124
 
126
125
  @patch("requests.Session.delete")
127
- def test_delete_customer(self, mock_post) -> NoReturn:
126
+ def test_delete_customer(self, mock_post) -> None:
128
127
  mock_post.return_value.status_code = 204
129
128
  # delete customer record in PayWay
130
129
  response = self.client.delete_customer("1")
131
130
  self.assertEqual(response.status_code, 204)
132
131
 
133
132
  @patch("requests.Session.put")
134
- def test_schedule_payments(self, mock_post) -> NoReturn:
133
+ def test_schedule_payments(self, mock_post) -> None:
135
134
  next_week = datetime.datetime.now() + datetime.timedelta(weeks=1)
136
135
  next_payment_date = next_week.strftime("%d %b %Y")
137
136
  mock_post.return_value.status_code = 200
@@ -156,14 +155,14 @@ class TestCustomerRequest(unittest.TestCase):
156
155
  self.assertEqual(response["regularPaymentAmount"], 10.50)
157
156
 
158
157
  @patch("requests.Session.delete")
159
- def test_stop_schedule(self, mock_post) -> NoReturn:
158
+ def test_stop_schedule(self, mock_post) -> None:
160
159
  # stop schedule
161
160
  mock_post.return_value.status_code = 204
162
161
  response = self.client.stop_schedule("1")
163
162
  self.assertEqual(response.status_code, 204)
164
163
 
165
164
  @patch("requests.Session.put")
166
- def test_update_contact_details(self, mock_post) -> NoReturn:
165
+ def test_update_contact_details(self, mock_post) -> None:
167
166
  # update contact details
168
167
  mock_post.return_value.status_code = 200
169
168
  mock_post.return_value.json.return_value = {
@@ -208,7 +207,7 @@ class TestCustomerRequest(unittest.TestCase):
208
207
  self.assertEqual(address["postalCode"], new_postcode)
209
208
 
210
209
  @patch("requests.Session.get")
211
- def test_list_customers(self, mock_get) -> NoReturn:
210
+ def test_list_customers(self, mock_get) -> None:
212
211
  mock_get.return_value.status_code = 200
213
212
  mock_get.return_value.json.return_value = load_json_file("tests/data/customers.json")
214
213
  response = self.client.list_customers()
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import unittest
4
- from typing import NoReturn
5
4
  from unittest.mock import patch
6
5
 
7
6
  from payway.client import Client
@@ -10,7 +9,7 @@ from payway.test_utils import load_json_file
10
9
 
11
10
  class TestTransactionRequest(unittest.TestCase):
12
11
  @classmethod
13
- def setUpClass(cls) -> NoReturn:
12
+ def setUpClass(cls) -> None:
14
13
  merchant_id = "TEST"
15
14
  bank_account_id = "0000000A"
16
15
  publishable_api_key = "TPUBLISHABLE-API-KEY"
@@ -24,7 +23,7 @@ class TestTransactionRequest(unittest.TestCase):
24
23
  )
25
24
 
26
25
  @patch("requests.Session.get")
27
- def test_search_transactions(self, mock_get) -> NoReturn:
26
+ def test_search_transactions(self, mock_get) -> None:
28
27
  mock_get.return_value.status_code = 200
29
28
  mock_get.return_value.json.return_value = load_json_file("tests/data/transactions.json")
30
29
  query = "/search-customer?customerNumber=1"
File without changes
File without changes
File without changes