python-payway 0.0.8__tar.gz → 0.0.9__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.8/python_payway.egg-info → python_payway-0.0.9}/PKG-INFO +22 -1
  2. {python_payway-0.0.8 → python_payway-0.0.9}/README.md +21 -0
  3. {python_payway-0.0.8 → python_payway-0.0.9}/payway/client.py +2 -2
  4. {python_payway-0.0.8 → python_payway-0.0.9}/payway/constants.py +1 -3
  5. {python_payway-0.0.8 → python_payway-0.0.9}/payway/customers.py +3 -3
  6. python_payway-0.0.9/payway/transactions.py +43 -0
  7. {python_payway-0.0.8 → python_payway-0.0.9}/pyproject.toml +1 -1
  8. {python_payway-0.0.8 → python_payway-0.0.9/python_payway.egg-info}/PKG-INFO +22 -1
  9. {python_payway-0.0.8 → python_payway-0.0.9}/tests/test_customers.py +14 -0
  10. python_payway-0.0.9/tests/test_transactions.py +66 -0
  11. python_payway-0.0.8/payway/transactions.py +0 -18
  12. python_payway-0.0.8/tests/test_transactions.py +0 -32
  13. {python_payway-0.0.8 → python_payway-0.0.9}/LICENSE +0 -0
  14. {python_payway-0.0.8 → python_payway-0.0.9}/payway/__init__.py +0 -0
  15. {python_payway-0.0.8 → python_payway-0.0.9}/payway/exceptions.py +0 -0
  16. {python_payway-0.0.8 → python_payway-0.0.9}/payway/model.py +0 -0
  17. {python_payway-0.0.8 → python_payway-0.0.9}/payway/test_utils.py +0 -0
  18. {python_payway-0.0.8 → python_payway-0.0.9}/payway/utils.py +0 -0
  19. {python_payway-0.0.8 → python_payway-0.0.9}/python_payway.egg-info/SOURCES.txt +0 -0
  20. {python_payway-0.0.8 → python_payway-0.0.9}/python_payway.egg-info/dependency_links.txt +0 -0
  21. {python_payway-0.0.8 → python_payway-0.0.9}/python_payway.egg-info/requires.txt +0 -0
  22. {python_payway-0.0.8 → python_payway-0.0.9}/python_payway.egg-info/top_level.txt +0 -0
  23. {python_payway-0.0.8 → python_payway-0.0.9}/setup.cfg +0 -0
  24. {python_payway-0.0.8 → python_payway-0.0.9}/tests/test_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-payway
3
- Version: 0.0.8
3
+ Version: 0.0.9
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
@@ -201,6 +201,27 @@ Poll a transaction using the `get_transaction` method.
201
201
  transaction, errors = client.get_transaction(transaction.transaction_id)
202
202
  ```
203
203
 
204
+ ## Search transactions
205
+
206
+ PayWay has no plain `GET /transactions` resource, only three search paths. Each returns a
207
+ paginated list (20 per page, most recent first) with `next`/`prev` links.
208
+
209
+ ```python
210
+ response = client.search_transactions_by_customer(customer_number)
211
+ response = client.search_transactions_by_receipt(receipt_number)
212
+ response = client.search_transactions_by_order(order_number)
213
+
214
+ transactions = response["data"]
215
+ ```
216
+
217
+ Pass `page` to fetch a later page, using the number from the `next`/`prev` links:
218
+
219
+ ```python
220
+ response = client.search_transactions_by_customer(customer_number, page=2)
221
+ ```
222
+
223
+ `list_customers()` takes the same `page` argument.
224
+
204
225
  ## Process and capture a pre-authorisation
205
226
 
206
227
  To process a credit card pre-authorisation using a credit card stored against a customer use `preAuth` as the `transaction_type` along with the customer's PayWay number, amount and currency.
@@ -178,6 +178,27 @@ Poll a transaction using the `get_transaction` method.
178
178
  transaction, errors = client.get_transaction(transaction.transaction_id)
179
179
  ```
180
180
 
181
+ ## Search transactions
182
+
183
+ PayWay has no plain `GET /transactions` resource, only three search paths. Each returns a
184
+ paginated list (20 per page, most recent first) with `next`/`prev` links.
185
+
186
+ ```python
187
+ response = client.search_transactions_by_customer(customer_number)
188
+ response = client.search_transactions_by_receipt(receipt_number)
189
+ response = client.search_transactions_by_order(order_number)
190
+
191
+ transactions = response["data"]
192
+ ```
193
+
194
+ Pass `page` to fetch a later page, using the number from the `next`/`prev` links:
195
+
196
+ ```python
197
+ response = client.search_transactions_by_customer(customer_number, page=2)
198
+ ```
199
+
200
+ `list_customers()` takes the same `page` argument.
201
+
181
202
  ## Process and capture a pre-authorisation
182
203
 
183
204
  To process a credit card pre-authorisation using a credit card stored against a customer use `preAuth` as the `transaction_type` along with the customer's PayWay number, amount and currency.
@@ -15,7 +15,7 @@ from payway.constants import (
15
15
  CUSTOMER_URL,
16
16
  PAYWAY_ERROR_RESPONSE_CODES,
17
17
  RETRYABLE_STATUS_CODES,
18
- TOKEN_NO_REDIRECT,
18
+ TOKEN_URL,
19
19
  TRANSACTION_URL,
20
20
  VALID_PAYMENT_METHOD_CHOICES,
21
21
  PaymentMethod,
@@ -190,7 +190,7 @@ class Client(CustomerRequest, TransactionRequest):
190
190
  data["paymentMethod"] = BANK_ACCOUNT_PAYMENT_CHOICE
191
191
  logger.info("Sending Create Token request to PayWay.")
192
192
  response = self.post_request(
193
- TOKEN_NO_REDIRECT,
193
+ TOKEN_URL,
194
194
  data,
195
195
  auth=(self.publishable_api_key, ""),
196
196
  idempotency_key=idempotency_key,
@@ -10,11 +10,9 @@ class PaymentMethod(StrEnum):
10
10
 
11
11
 
12
12
  PAYWAY_API_URL = "https://api.payway.com.au/rest/v1"
13
- TOKEN_URL = PAYWAY_API_URL + "/single-use-tokens-redirect"
13
+ TOKEN_URL = PAYWAY_API_URL + "/single-use-tokens"
14
14
  TRANSACTION_URL = PAYWAY_API_URL + "/transactions"
15
15
  CUSTOMER_URL = PAYWAY_API_URL + "/customers"
16
- OWN_BANK_ACCOUNTS_URL = PAYWAY_API_URL + "/your-bank-accounts"
17
- TOKEN_NO_REDIRECT = PAYWAY_API_URL + "/single-use-tokens"
18
16
  TRANSACTION_APPROVED = "0"
19
17
 
20
18
  SUMMARY_CODES = {
@@ -98,10 +98,10 @@ class CustomerRequest:
98
98
  )
99
99
 
100
100
  @json_list("list_customers")
101
- def list_customers(self) -> requests.Response:
101
+ def list_customers(self, page: int | None = None) -> requests.Response:
102
102
  """
103
103
  List all customers in PayWay
104
104
  Returns paginated list of customerNumber, customerName
105
+ :param page: page number, taken from the `next`/`prev` links of a previous response
105
106
  """
106
- # TODO: add page numbers
107
- return self.session_no_headers.get(CUSTOMER_URL)
107
+ return self.session_no_headers.get(CUSTOMER_URL, params={"page": page})
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import requests
6
+
7
+ from payway.constants import TRANSACTION_URL
8
+ from payway.utils import json_list
9
+
10
+
11
+ class TransactionRequest:
12
+ session = requests.Session()
13
+ session_no_headers = requests.Session()
14
+
15
+ def _search(self, path: str, params: dict[str, Any]) -> requests.Response:
16
+ return self.session_no_headers.get(f"{TRANSACTION_URL}/{path}", params=params)
17
+
18
+ @json_list("search_transactions_by_customer")
19
+ def search_transactions_by_customer(self, customer_number: int | str, page: int | None = None) -> requests.Response:
20
+ """
21
+ Returns a paginated list of transactions for a PayWay customer, most recent first
22
+ :param customer_number: PayWay customer number
23
+ :param page: page number, taken from the `next`/`prev` links of a previous response
24
+ """
25
+ return self._search("search-customer", {"customerNumber": customer_number, "page": page})
26
+
27
+ @json_list("search_transactions_by_receipt")
28
+ def search_transactions_by_receipt(self, receipt_number: int | str, page: int | None = None) -> requests.Response:
29
+ """
30
+ Returns a paginated list of transactions with the given receipt number, most recent first
31
+ :param receipt_number: PayWay receipt number
32
+ :param page: page number, taken from the `next`/`prev` links of a previous response
33
+ """
34
+ return self._search("search-receipt", {"receiptNumber": receipt_number, "page": page})
35
+
36
+ @json_list("search_transactions_by_order")
37
+ def search_transactions_by_order(self, order_number: str, page: int | None = None) -> requests.Response:
38
+ """
39
+ Returns a paginated list of transactions with the given order number, most recent first
40
+ :param order_number: your order number, supplied when the transaction was created
41
+ :param page: page number, taken from the `next`/`prev` links of a previous response
42
+ """
43
+ return self._search("search-order", {"orderNumber": order_number, "page": page})
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "python-payway"
7
- version = "0.0.8"
7
+ version = "0.0.9"
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" }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-payway
3
- Version: 0.0.8
3
+ Version: 0.0.9
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
@@ -201,6 +201,27 @@ Poll a transaction using the `get_transaction` method.
201
201
  transaction, errors = client.get_transaction(transaction.transaction_id)
202
202
  ```
203
203
 
204
+ ## Search transactions
205
+
206
+ PayWay has no plain `GET /transactions` resource, only three search paths. Each returns a
207
+ paginated list (20 per page, most recent first) with `next`/`prev` links.
208
+
209
+ ```python
210
+ response = client.search_transactions_by_customer(customer_number)
211
+ response = client.search_transactions_by_receipt(receipt_number)
212
+ response = client.search_transactions_by_order(order_number)
213
+
214
+ transactions = response["data"]
215
+ ```
216
+
217
+ Pass `page` to fetch a later page, using the number from the `next`/`prev` links:
218
+
219
+ ```python
220
+ response = client.search_transactions_by_customer(customer_number, page=2)
221
+ ```
222
+
223
+ `list_customers()` takes the same `page` argument.
224
+
204
225
  ## Process and capture a pre-authorisation
205
226
 
206
227
  To process a credit card pre-authorisation using a credit card stored against a customer use `preAuth` as the `transaction_type` along with the customer's PayWay number, amount and currency.
@@ -211,6 +211,20 @@ class TestCustomerRequest(unittest.TestCase):
211
211
  mock_get.return_value.status_code = 200
212
212
  mock_get.return_value.json.return_value = load_json_file("tests/data/customers.json")
213
213
  response = self.client.list_customers()
214
+ mock_get.assert_called_once_with(
215
+ "https://api.payway.com.au/rest/v1/customers",
216
+ params={"page": None},
217
+ )
214
218
  self.assertEqual(response.__class__, dict)
215
219
  self.assertIsNotNone(response)
216
220
  self.assertIsNotNone(response.get("data"))
221
+
222
+ @patch("requests.Session.get")
223
+ def test_list_customers_with_page(self, mock_get) -> None:
224
+ mock_get.return_value.status_code = 200
225
+ mock_get.return_value.json.return_value = load_json_file("tests/data/customers.json")
226
+ self.client.list_customers(page=3)
227
+ mock_get.assert_called_once_with(
228
+ "https://api.payway.com.au/rest/v1/customers",
229
+ params={"page": 3},
230
+ )
@@ -0,0 +1,66 @@
1
+ from __future__ import annotations
2
+
3
+ import unittest
4
+ from unittest.mock import patch
5
+
6
+ from payway.client import Client
7
+ from payway.test_utils import load_json_file
8
+
9
+
10
+ class TestTransactionRequest(unittest.TestCase):
11
+ @classmethod
12
+ def setUpClass(cls) -> None:
13
+ merchant_id = "TEST"
14
+ bank_account_id = "0000000A"
15
+ publishable_api_key = "TPUBLISHABLE-API-KEY"
16
+ secret_api_key = "TPUBLISHABLE-SECRET"
17
+
18
+ cls.client = Client(
19
+ merchant_id=merchant_id,
20
+ bank_account_id=bank_account_id,
21
+ publishable_api_key=publishable_api_key,
22
+ secret_api_key=secret_api_key,
23
+ )
24
+
25
+ @patch("requests.Session.get")
26
+ def test_search_transactions_by_customer(self, mock_get) -> None:
27
+ mock_get.return_value.status_code = 200
28
+ mock_get.return_value.json.return_value = load_json_file("tests/data/transactions.json")
29
+ response = self.client.search_transactions_by_customer(1)
30
+ mock_get.assert_called_once_with(
31
+ "https://api.payway.com.au/rest/v1/transactions/search-customer",
32
+ params={"customerNumber": 1, "page": None},
33
+ )
34
+ self.assertIsNotNone(response["data"])
35
+
36
+ @patch("requests.Session.get")
37
+ def test_search_transactions_by_customer_with_page(self, mock_get) -> None:
38
+ mock_get.return_value.status_code = 200
39
+ mock_get.return_value.json.return_value = load_json_file("tests/data/transactions.json")
40
+ self.client.search_transactions_by_customer(1, page=2)
41
+ mock_get.assert_called_once_with(
42
+ "https://api.payway.com.au/rest/v1/transactions/search-customer",
43
+ params={"customerNumber": 1, "page": 2},
44
+ )
45
+
46
+ @patch("requests.Session.get")
47
+ def test_search_transactions_by_receipt(self, mock_get) -> None:
48
+ mock_get.return_value.status_code = 200
49
+ mock_get.return_value.json.return_value = load_json_file("tests/data/transactions.json")
50
+ response = self.client.search_transactions_by_receipt("1234567")
51
+ mock_get.assert_called_once_with(
52
+ "https://api.payway.com.au/rest/v1/transactions/search-receipt",
53
+ params={"receiptNumber": "1234567", "page": None},
54
+ )
55
+ self.assertIsNotNone(response["data"])
56
+
57
+ @patch("requests.Session.get")
58
+ def test_search_transactions_by_order(self, mock_get) -> None:
59
+ mock_get.return_value.status_code = 200
60
+ mock_get.return_value.json.return_value = load_json_file("tests/data/transactions.json")
61
+ response = self.client.search_transactions_by_order("ORDER-1")
62
+ mock_get.assert_called_once_with(
63
+ "https://api.payway.com.au/rest/v1/transactions/search-order",
64
+ params={"orderNumber": "ORDER-1", "page": None},
65
+ )
66
+ self.assertIsNotNone(response["data"])
@@ -1,18 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import requests
4
-
5
- from payway.constants import TRANSACTION_URL
6
- from payway.utils import json_list
7
-
8
-
9
- class TransactionRequest:
10
- session = requests.Session()
11
- session_no_headers = requests.Session()
12
-
13
- @json_list("search_transactions")
14
- def search_transactions(self, query: str) -> requests.Response:
15
- """
16
- Returns a list of transactions
17
- """
18
- return self.session_no_headers.get(TRANSACTION_URL + query)
@@ -1,32 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import unittest
4
- from unittest.mock import patch
5
-
6
- from payway.client import Client
7
- from payway.test_utils import load_json_file
8
-
9
-
10
- class TestTransactionRequest(unittest.TestCase):
11
- @classmethod
12
- def setUpClass(cls) -> None:
13
- merchant_id = "TEST"
14
- bank_account_id = "0000000A"
15
- publishable_api_key = "TPUBLISHABLE-API-KEY"
16
- secret_api_key = "TPUBLISHABLE-SECRET"
17
-
18
- cls.client = Client(
19
- merchant_id=merchant_id,
20
- bank_account_id=bank_account_id,
21
- publishable_api_key=publishable_api_key,
22
- secret_api_key=secret_api_key,
23
- )
24
-
25
- @patch("requests.Session.get")
26
- def test_search_transactions(self, mock_get) -> None:
27
- mock_get.return_value.status_code = 200
28
- mock_get.return_value.json.return_value = load_json_file("tests/data/transactions.json")
29
- query = "/search-customer?customerNumber=1"
30
- response = self.client.search_transactions(query)
31
- transactions = response["data"]
32
- self.assertIsNotNone(transactions)
File without changes
File without changes