pypaystack2 3.0.2__tar.gz → 3.2.0__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 (177) hide show
  1. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/PKG-INFO +43 -59
  2. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/README.md +34 -54
  3. pypaystack2-3.2.0/pyproject.toml +60 -0
  4. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/_metadata.py +1 -1
  5. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/base_clients.py +64 -21
  6. pypaystack2-3.2.0/src/pypaystack2/cli.py +21 -0
  7. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/enums.py +3 -0
  8. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/main_clients.py +38 -19
  9. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/models/__init__.py +1 -0
  10. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/models/payload_models.py +16 -0
  11. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/models/response_models.py +13 -5
  12. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/charge.py +35 -19
  13. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/customers.py +193 -1
  14. pypaystack2-3.2.0/src/pypaystack2/sub_clients/async_clients/direct_debits.py +91 -0
  15. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/miscellaneous.py +4 -0
  16. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/payment_pages.py +28 -4
  17. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/refunds.py +50 -2
  18. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/transactions.py +5 -2
  19. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/transfers.py +14 -1
  20. pypaystack2-3.2.0/src/pypaystack2/sub_clients/async_clients/virtual_terminals.py +293 -0
  21. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/charge.py +36 -20
  22. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/customers.py +193 -1
  23. pypaystack2-3.2.0/src/pypaystack2/sub_clients/sync_clients/direct_debits.py +91 -0
  24. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/miscellaneous.py +4 -0
  25. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/payment_pages.py +28 -4
  26. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/refunds.py +50 -2
  27. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/transactions.py +3 -0
  28. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/transfers.py +14 -1
  29. pypaystack2-3.2.0/src/pypaystack2/sub_clients/sync_clients/virtual_terminals.py +287 -0
  30. pypaystack2-3.2.0/src/pypaystack2/utils.py +32 -0
  31. {pypaystack2-3.0.2/tests → pypaystack2-3.2.0/src/pypaystack2/webhook}/__init__.py +0 -0
  32. pypaystack2-3.2.0/src/pypaystack2/webhook/cli.py +267 -0
  33. pypaystack2-3.2.0/src/pypaystack2/webhook/enums.py +28 -0
  34. pypaystack2-3.2.0/src/pypaystack2/webhook/logging_config.py +51 -0
  35. pypaystack2-3.2.0/src/pypaystack2/webhook/models.py +45 -0
  36. pypaystack2-3.2.0/src/pypaystack2/webhook/webhook_proxy_server.py +129 -0
  37. pypaystack2-3.0.2/.gitattributes +0 -6
  38. pypaystack2-3.0.2/.github/FUNDING.yml +0 -1
  39. pypaystack2-3.0.2/.github/workflows/documentation-release.yml +0 -32
  40. pypaystack2-3.0.2/.github/workflows/publish.yml +0 -25
  41. pypaystack2-3.0.2/.github/workflows/python-package.yml +0 -40
  42. pypaystack2-3.0.2/.gitignore +0 -9
  43. pypaystack2-3.0.2/.nojekyll +0 -0
  44. pypaystack2-3.0.2/.pre-commit-config.yaml +0 -19
  45. pypaystack2-3.0.2/.python-version +0 -1
  46. pypaystack2-3.0.2/CHANGELOG.md +0 -199
  47. pypaystack2-3.0.2/LICENSE +0 -21
  48. pypaystack2-3.0.2/Makefile +0 -4
  49. pypaystack2-3.0.2/docs/assets/illustration-0.png +0 -0
  50. pypaystack2-3.0.2/docs/assets/illustration-1.png +0 -0
  51. pypaystack2-3.0.2/docs/assets/pypaystack2.svg +0 -44
  52. pypaystack2-3.0.2/docs/explanation.md +0 -1
  53. pypaystack2-3.0.2/docs/how-to-guides.md +0 -3
  54. pypaystack2-3.0.2/docs/index.md +0 -405
  55. pypaystack2-3.0.2/docs/reference/apple_pay.md +0 -2
  56. pypaystack2-3.0.2/docs/reference/bulk_charges.md +0 -2
  57. pypaystack2-3.0.2/docs/reference/charge.md +0 -2
  58. pypaystack2-3.0.2/docs/reference/customer.md +0 -2
  59. pypaystack2-3.0.2/docs/reference/dedicated_accounts.md +0 -2
  60. pypaystack2-3.0.2/docs/reference/disputes.md +0 -2
  61. pypaystack2-3.0.2/docs/reference/index.md +0 -41
  62. pypaystack2-3.0.2/docs/reference/integration.md +0 -2
  63. pypaystack2-3.0.2/docs/reference/miscellaneous.md +0 -2
  64. pypaystack2-3.0.2/docs/reference/payment_pages.md +0 -2
  65. pypaystack2-3.0.2/docs/reference/payment_requests.md +0 -2
  66. pypaystack2-3.0.2/docs/reference/plans.md +0 -2
  67. pypaystack2-3.0.2/docs/reference/products.md +0 -2
  68. pypaystack2-3.0.2/docs/reference/refunds.md +0 -2
  69. pypaystack2-3.0.2/docs/reference/settlements.md +0 -2
  70. pypaystack2-3.0.2/docs/reference/splits.md +0 -2
  71. pypaystack2-3.0.2/docs/reference/subaccounts.md +0 -2
  72. pypaystack2-3.0.2/docs/reference/subscriptions.md +0 -2
  73. pypaystack2-3.0.2/docs/reference/terminals.md +0 -2
  74. pypaystack2-3.0.2/docs/reference/transactions.md +0 -2
  75. pypaystack2-3.0.2/docs/reference/transfer_recipients.md +0 -2
  76. pypaystack2-3.0.2/docs/reference/transfers.md +0 -2
  77. pypaystack2-3.0.2/docs/reference/transfers_control.md +0 -2
  78. pypaystack2-3.0.2/docs/reference/verification.md +0 -2
  79. pypaystack2-3.0.2/docs/stylesheets/extra.css +0 -5
  80. pypaystack2-3.0.2/docs/tutorials/tutorial-00.md +0 -474
  81. pypaystack2-3.0.2/mkdocs.yml +0 -111
  82. pypaystack2-3.0.2/pyproject.toml +0 -52
  83. pypaystack2-3.0.2/tests/test__metadata.py +0 -44
  84. pypaystack2-3.0.2/tests/test_baseapi.py +0 -168
  85. pypaystack2-3.0.2/tests/test_paystack.py +0 -191
  86. pypaystack2-3.0.2/tests/test_paystack_fees_calculation.py +0 -116
  87. pypaystack2-3.0.2/tests/test_sub_clients/__init__.py +0 -0
  88. pypaystack2-3.0.2/tests/test_sub_clients/mocked_api_testcase.py +0 -105
  89. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/__init__.py +0 -0
  90. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_apple_pay.py +0 -77
  91. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_bulk_charges.py +0 -79
  92. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_charge.py +0 -76
  93. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_customers.py +0 -93
  94. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_dedicated_accounts.py +0 -47
  95. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_disputes.py +0 -50
  96. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_integration.py +0 -37
  97. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_miscellaneous.py +0 -46
  98. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_payment_pages.py +0 -74
  99. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_payment_requests.py +0 -105
  100. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_plans.py +0 -53
  101. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_products.py +0 -58
  102. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_refunds.py +0 -40
  103. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_settlements.py +0 -30
  104. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_splits.py +0 -81
  105. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_subaccounts.py +0 -55
  106. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_subscriptions.py +0 -88
  107. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_terminals.py +0 -39
  108. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_transactions.py +0 -103
  109. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_transfer_recipients.py +0 -98
  110. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_transfers.py +0 -59
  111. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_transfers_control.py +0 -69
  112. pypaystack2-3.0.2/tests/test_sub_clients/test_async_clients/test_verification.py +0 -55
  113. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/__init__.py +0 -0
  114. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_apple_pay.py +0 -73
  115. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_bulk_charges.py +0 -66
  116. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_charge.py +0 -70
  117. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_customers.py +0 -87
  118. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_dedicated_accounts.py +0 -44
  119. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_disputes.py +0 -48
  120. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_integration.py +0 -33
  121. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_miscellaneous.py +0 -42
  122. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_payment_pages.py +0 -67
  123. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_payment_requests.py +0 -89
  124. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_plans.py +0 -53
  125. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_products.py +0 -58
  126. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_refunds.py +0 -38
  127. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_settlements.py +0 -27
  128. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_splits.py +0 -77
  129. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_subaccounts.py +0 -51
  130. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_subscriptions.py +0 -80
  131. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_terminals.py +0 -38
  132. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_transactions.py +0 -95
  133. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_transfer_recipients.py +0 -84
  134. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_transfers.py +0 -51
  135. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_transfers_control.py +0 -66
  136. pypaystack2-3.0.2/tests/test_sub_clients/test_sync_clients/test_verification.py +0 -48
  137. pypaystack2-3.0.2/uv.lock +0 -1057
  138. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/__init__.py +0 -0
  139. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/exceptions.py +0 -0
  140. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/fees_calculation_mixin.py +0 -0
  141. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/py.typed +0 -0
  142. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/__init__.py +0 -0
  143. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/__init__.py +0 -0
  144. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/apple_pay.py +0 -0
  145. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/bulk_charges.py +0 -0
  146. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/dedicated_accounts.py +0 -0
  147. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/disputes.py +0 -0
  148. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/integration.py +0 -0
  149. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/payment_requests.py +0 -0
  150. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/plans.py +0 -0
  151. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/products.py +0 -0
  152. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/settlements.py +0 -0
  153. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/splits.py +0 -0
  154. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/subaccounts.py +0 -0
  155. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/subscriptions.py +0 -0
  156. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/terminals.py +0 -0
  157. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/transfer_recipients.py +0 -0
  158. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/transfers_control.py +0 -0
  159. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/async_clients/verification.py +0 -0
  160. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/__init__.py +0 -0
  161. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/apple_pay.py +0 -0
  162. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/bulk_charges.py +0 -0
  163. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/dedicated_accounts.py +0 -0
  164. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/disputes.py +0 -0
  165. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/integration.py +0 -0
  166. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/payment_requests.py +0 -0
  167. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/plans.py +0 -0
  168. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/products.py +0 -0
  169. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/settlements.py +0 -0
  170. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/splits.py +0 -0
  171. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/subaccounts.py +0 -0
  172. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/subscriptions.py +0 -0
  173. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/terminals.py +0 -0
  174. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/transfer_recipients.py +0 -0
  175. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/transfers_control.py +0 -0
  176. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/sub_clients/sync_clients/verification.py +0 -0
  177. {pypaystack2-3.0.2 → pypaystack2-3.2.0}/src/pypaystack2/types.py +0 -0
@@ -1,17 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pypaystack2
3
- Version: 3.0.2
3
+ Version: 3.2.0
4
4
  Summary: A developer-friendly client library for Paystack
5
+ Keywords: paystack-python,pypaystack,paystack,paystackapi
6
+ Author: Gbenga Adeyi
5
7
  Author-email: Gbenga Adeyi <adeyigbenga005@gmail.com>
6
8
  License-Expression: MIT
7
- License-File: LICENSE
8
- Keywords: paystack,paystack-python,paystackapi,pypaystack
9
9
  Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Programming Language :: Python
11
11
  Classifier: Programming Language :: Python :: 3
12
- Requires-Python: >=3.11
13
12
  Requires-Dist: httpx>=0.28.1
14
- Requires-Dist: pydantic>=2.10.6
13
+ Requires-Dist: pydantic>=2.12.5
14
+ Requires-Dist: fastapi[standard]>=0.123.10 ; extra == 'webhook'
15
+ Requires-Dist: ngrok>=1.4.0 ; extra == 'webhook'
16
+ Requires-Dist: python-dotenv>=1.2.1 ; extra == 'webhook'
17
+ Requires-Python: >=3.11
18
+ Provides-Extra: webhook
15
19
  Description-Content-Type: text/markdown
16
20
 
17
21
  # PyPaystack2
@@ -31,6 +35,7 @@ projects. It aims at being developer friendly and easy to use.
31
35
  - Synchronous and Asynchronous clients.
32
36
  - Pydantic for data modelling.
33
37
  - Fees Calculation utilities.
38
+ - Webhook support & utilities (>= v3.1.0).
34
39
 
35
40
  ## Installation
36
41
 
@@ -38,6 +43,10 @@ projects. It aims at being developer friendly and easy to use.
38
43
  $ pip install -U pypaystack2
39
44
  # or install with uv
40
45
  $ uv add pypaystack2
46
+ # For webhook cli
47
+ $ pip install -U "pypaystack2[webhook]"
48
+ or install with uv
49
+ $ uv add "pypaystack2[webhook]"
41
50
  ```
42
51
 
43
52
  ## Usage Preview
@@ -55,7 +64,7 @@ you to provide a secret key. It also does not handle likely exceptions that call
55
64
  for network related issues and `ValueError` for validation related issues.
56
65
 
57
66
  ```bash
58
- Python 3.11.11 (main, Feb 12 2025, 14:51:05) [Clang 19.1.6 ] on linux
67
+ Python 3.11.13 (main, Sep 2 2025, 14:20:25) [Clang 20.1.4 ] on linux
59
68
  Type "help", "copyright", "credits" or "license" for more information.
60
69
  >>> from pypaystack2 import __version__
61
70
  >>> print(__version__)
@@ -81,59 +90,34 @@ Response(
81
90
  message='Subscription successfully created',
82
91
  data=Subscription(
83
92
  customer=87934333,
84
- plan=2237384,
85
- integration=630606,
86
- domain=<Domain.TEST: 'test'>,
87
- start=1741208073,
88
- status='active',
89
- quantity=1,
90
- amount=100000,
91
- subscription_code='SUB_4sje2s7kb30m5bt',
92
- email_token='uqzg0vneparuxtm',
93
- authorization=368220905,
94
- easy_cron_id=None,
95
- cron_expression='54 20 5 3 *',
96
- next_payment_date=datetime.datetime(2026, 3, 5, 20, 54, tzinfo=TzInfo(UTC)),
97
- open_invoice=None,
98
- invoice_limit=0,
99
- id=759264,
100
- split_code=None,
101
- cancelled_at=None,
102
- updated_at=datetime.datetime(2025, 3, 5, 20, 54, 33, tzinfo=TzInfo(UTC)),
103
- payments_count=None,
104
- most_recent_invoice=None,
105
- invoices=None,
106
- invoice_history=None),
107
- meta=None,
108
- type=None,
109
- code=None,
110
- raw={
111
- 'status': True,
112
- 'message': 'Subscription successfully created',
113
- 'data': {
114
- 'customer': 87934333,
115
- 'plan': 2237384,
116
- 'integration': 630606,
117
- 'domain': 'test',
118
- 'start': 1741208073,
119
- 'status': 'active',
120
- 'quantity': 1,
121
- 'amount': 100000,
122
- 'authorization': 368220905,
123
- 'invoice_limit': 0,
124
- 'split_code': None,
125
- 'metadata': None,
126
- 'subscription_code': 'SUB_4sje2s7kb30m5bt',
127
- 'email_token': 'uqzg0vneparuxtm',
128
- 'id': 759264,
129
- 'cancelledAt': None,
130
- 'createdAt': '2025-03-05T20:54:33.000Z',
131
- 'updatedAt': '2025-03-05T20:54:33.000Z',
132
- 'cron_expression': '54 20 5 3 *',
133
- 'next_payment_date': '2026-03-05T20:54:00.000Z',
134
- 'easy_cron_id': None,
135
- 'open_invoice': None}
136
- })
93
+ plan=2237384,...
94
+ ```
95
+
96
+ ### Webhook
97
+
98
+ PyPaystack2 now supports verifying the authenticity of a webhook payload and a CLI to make working with webhooks locally
99
+ seamless
100
+
101
+ #### Verifying a webhook payload
102
+
103
+ ```bash
104
+ Python 3.11.13 (main, Sep 2 2025, 14:20:25) [Clang 20.1.4 ] on linux
105
+ Type "help", "copyright", "credits" or "license" for more information.
106
+ >>> from pypaystack2 import PaystackClient
107
+ >>> client = PaystackClient()
108
+ >>> payload = ... # webhook payload e.g., b'{"event": "customeridentification.success", "data": {"customer_id": 324345768, "customer_code": "CUS_e7urjebaoyk1ze2", "email": "jddae8446e-e54c-42ab-bf37-e5abff14527e@example.com", "identification": {"country": "NG", "type": "bank_account", "bvn": "123*****543", "account_number": "342****22", "bank_code": "121"}}}'
109
+ >>> signature = ... # x-paystack-signature e.g., "5d049eb93c7c71fa098f5215d7297bda401710b62df8b392b9052adf8d1a02ff308f6ca57a1db14ffeabd5b66264e9c42de029b7067b9c71eb9c231fb2a8e383"
110
+ >>> is_verified_webhook_payload = client.is_verified_webhook_payload(payload,signature)
111
+ >>> print(is_verified_webhook_payload)
112
+ True
113
+ ```
114
+
115
+ #### Forward webhook events from paystack to your app running locally
116
+
117
+ **Note:** This requires that you install `pypaystack2[webhook]`
118
+
119
+ ```bash
120
+ pypaystack2 webhook start-tunnel-server --addr localhost:8000 --ngrok-auth-token
137
121
  ```
138
122
 
139
123
  ## Documentation
@@ -15,6 +15,7 @@ projects. It aims at being developer friendly and easy to use.
15
15
  - Synchronous and Asynchronous clients.
16
16
  - Pydantic for data modelling.
17
17
  - Fees Calculation utilities.
18
+ - Webhook support & utilities (>= v3.1.0).
18
19
 
19
20
  ## Installation
20
21
 
@@ -22,6 +23,10 @@ projects. It aims at being developer friendly and easy to use.
22
23
  $ pip install -U pypaystack2
23
24
  # or install with uv
24
25
  $ uv add pypaystack2
26
+ # For webhook cli
27
+ $ pip install -U "pypaystack2[webhook]"
28
+ or install with uv
29
+ $ uv add "pypaystack2[webhook]"
25
30
  ```
26
31
 
27
32
  ## Usage Preview
@@ -39,7 +44,7 @@ you to provide a secret key. It also does not handle likely exceptions that call
39
44
  for network related issues and `ValueError` for validation related issues.
40
45
 
41
46
  ```bash
42
- Python 3.11.11 (main, Feb 12 2025, 14:51:05) [Clang 19.1.6 ] on linux
47
+ Python 3.11.13 (main, Sep 2 2025, 14:20:25) [Clang 20.1.4 ] on linux
43
48
  Type "help", "copyright", "credits" or "license" for more information.
44
49
  >>> from pypaystack2 import __version__
45
50
  >>> print(__version__)
@@ -65,59 +70,34 @@ Response(
65
70
  message='Subscription successfully created',
66
71
  data=Subscription(
67
72
  customer=87934333,
68
- plan=2237384,
69
- integration=630606,
70
- domain=<Domain.TEST: 'test'>,
71
- start=1741208073,
72
- status='active',
73
- quantity=1,
74
- amount=100000,
75
- subscription_code='SUB_4sje2s7kb30m5bt',
76
- email_token='uqzg0vneparuxtm',
77
- authorization=368220905,
78
- easy_cron_id=None,
79
- cron_expression='54 20 5 3 *',
80
- next_payment_date=datetime.datetime(2026, 3, 5, 20, 54, tzinfo=TzInfo(UTC)),
81
- open_invoice=None,
82
- invoice_limit=0,
83
- id=759264,
84
- split_code=None,
85
- cancelled_at=None,
86
- updated_at=datetime.datetime(2025, 3, 5, 20, 54, 33, tzinfo=TzInfo(UTC)),
87
- payments_count=None,
88
- most_recent_invoice=None,
89
- invoices=None,
90
- invoice_history=None),
91
- meta=None,
92
- type=None,
93
- code=None,
94
- raw={
95
- 'status': True,
96
- 'message': 'Subscription successfully created',
97
- 'data': {
98
- 'customer': 87934333,
99
- 'plan': 2237384,
100
- 'integration': 630606,
101
- 'domain': 'test',
102
- 'start': 1741208073,
103
- 'status': 'active',
104
- 'quantity': 1,
105
- 'amount': 100000,
106
- 'authorization': 368220905,
107
- 'invoice_limit': 0,
108
- 'split_code': None,
109
- 'metadata': None,
110
- 'subscription_code': 'SUB_4sje2s7kb30m5bt',
111
- 'email_token': 'uqzg0vneparuxtm',
112
- 'id': 759264,
113
- 'cancelledAt': None,
114
- 'createdAt': '2025-03-05T20:54:33.000Z',
115
- 'updatedAt': '2025-03-05T20:54:33.000Z',
116
- 'cron_expression': '54 20 5 3 *',
117
- 'next_payment_date': '2026-03-05T20:54:00.000Z',
118
- 'easy_cron_id': None,
119
- 'open_invoice': None}
120
- })
73
+ plan=2237384,...
74
+ ```
75
+
76
+ ### Webhook
77
+
78
+ PyPaystack2 now supports verifying the authenticity of a webhook payload and a CLI to make working with webhooks locally
79
+ seamless
80
+
81
+ #### Verifying a webhook payload
82
+
83
+ ```bash
84
+ Python 3.11.13 (main, Sep 2 2025, 14:20:25) [Clang 20.1.4 ] on linux
85
+ Type "help", "copyright", "credits" or "license" for more information.
86
+ >>> from pypaystack2 import PaystackClient
87
+ >>> client = PaystackClient()
88
+ >>> payload = ... # webhook payload e.g., b'{"event": "customeridentification.success", "data": {"customer_id": 324345768, "customer_code": "CUS_e7urjebaoyk1ze2", "email": "jddae8446e-e54c-42ab-bf37-e5abff14527e@example.com", "identification": {"country": "NG", "type": "bank_account", "bvn": "123*****543", "account_number": "342****22", "bank_code": "121"}}}'
89
+ >>> signature = ... # x-paystack-signature e.g., "5d049eb93c7c71fa098f5215d7297bda401710b62df8b392b9052adf8d1a02ff308f6ca57a1db14ffeabd5b66264e9c42de029b7067b9c71eb9c231fb2a8e383"
90
+ >>> is_verified_webhook_payload = client.is_verified_webhook_payload(payload,signature)
91
+ >>> print(is_verified_webhook_payload)
92
+ True
93
+ ```
94
+
95
+ #### Forward webhook events from paystack to your app running locally
96
+
97
+ **Note:** This requires that you install `pypaystack2[webhook]`
98
+
99
+ ```bash
100
+ pypaystack2 webhook start-tunnel-server --addr localhost:8000 --ngrok-auth-token
121
101
  ```
122
102
 
123
103
  ## Documentation
@@ -0,0 +1,60 @@
1
+ [project]
2
+ name = "pypaystack2"
3
+ version = "3.2.0"
4
+ description = "A developer-friendly client library for Paystack"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ authors = [
8
+ { name = "Gbenga Adeyi", email = "adeyigbenga005@gmail.com" }
9
+ ]
10
+ keywords = ["paystack-python", "pypaystack", "paystack", "paystackapi"]
11
+ classifiers = [
12
+ "License :: OSI Approved :: MIT License",
13
+ "Programming Language :: Python",
14
+ "Programming Language :: Python :: 3",
15
+ ]
16
+
17
+
18
+ requires-python = ">= 3.11"
19
+ dependencies = [
20
+ "httpx>=0.28.1",
21
+ "pydantic>=2.12.5",
22
+ ]
23
+
24
+ [project.scripts]
25
+ pypaystack2 = "pypaystack2.cli:cli_app"
26
+
27
+ [project.optional-dependencies]
28
+ webhook = [
29
+ "fastapi[standard]>=0.123.10",
30
+ "ngrok>=1.4.0",
31
+ "python-dotenv>=1.2.1",
32
+ ]
33
+
34
+ [build-system]
35
+ requires = ["uv_build>=0.9.10,<0.10.0"]
36
+ build-backend = "uv_build"
37
+
38
+ [dependency-groups]
39
+ dev = [
40
+ "pre-commit>=4.5.0",
41
+ { include-group = "format" },
42
+ { include-group = "test" },
43
+ { include-group = "coverage" },
44
+ ]
45
+ format = [
46
+ "ruff>=0.14.8",
47
+ ]
48
+ test = [
49
+ "python-dotenv>=1.2.1",
50
+ "tomli>=2.3.0",
51
+ ]
52
+ coverage = []
53
+ doc = [
54
+ "mike>=2.1.3",
55
+ "mkdocs>=1.6.1",
56
+ "mkdocs-glightbox>=0.5.2",
57
+ "mkdocs-material>=9.7.0",
58
+ "mkdocstrings>=1.0.0",
59
+ "mkdocstrings-python>=2.0.1",
60
+ ]
@@ -1,5 +1,5 @@
1
1
  __title__ = "pypaystack2"
2
- __version__ = "3.0.2"
2
+ __version__ = "3.2.0"
3
3
  __author__ = [{"name": "Gbenga Adeyi", "email": "adeyigbenga005@gmail.com"}]
4
4
  __license__ = "MIT"
5
5
  __copyright__ = "Copyright 2025."
@@ -1,3 +1,5 @@
1
+ import hashlib
2
+ import hmac
1
3
  import logging
2
4
  import os
3
5
  import re
@@ -6,32 +8,49 @@ from abc import ABC, abstractmethod
6
8
  from functools import reduce
7
9
  from http import HTTPMethod, HTTPStatus
8
10
  from json import JSONDecodeError
9
- from typing import Type, Any, cast
11
+ from typing import Any, Type, cast
10
12
 
11
13
  import httpx
12
- from httpx import NetworkError
14
+ from httpx import HTTPError
13
15
  from pydantic import ValidationError
14
16
 
15
17
  from pypaystack2._metadata import __version__
16
- from pypaystack2.exceptions import MissingSecretKeyException, ClientNetworkError
18
+ from pypaystack2.exceptions import ClientNetworkError, MissingSecretKeyException
17
19
  from pypaystack2.fees_calculation_mixin import FeesCalculationMixin
18
20
  from pypaystack2.models import Response
19
21
  from pypaystack2.types import PaystackDataModel
20
22
 
21
23
  logger = logging.getLogger(__name__)
22
24
 
23
- SERIALIZATION_FAILED_WARNING_MESSAGE = """An validation error occurred while trying to serialize the data returned
24
- by paystack with the pydantic model `%s` but has been allowed to
25
- fail silently. `Response.data` has been set to `None` but this data is still available in
26
- `Response.raw`. If the pydantic model that raised this error is from the
27
- library, It's not your fault, Its either I goofed up in the model definitions
28
- or the response data doesn't match the model.
29
- please create an issue at https://github.com/gray-adeyi/pypaystack2/issues
30
- If you're using a custom pydantic model other than the one from the library,
31
- please see that your model definitions match the data returned by paystack
32
-
33
- These are the validation errors:
34
- %s
25
+ SERIALIZATION_FAILED_ON_SUCCESSFUL_RESPONSE_WARNING_MESSAGE_TEMPLATE = """\
26
+ A validation error occurred while attempting to deserialize the data returned
27
+ by Paystack using the Pydantic model `{response_data_model_class}`. The error
28
+ was allowed to fail silently. As a result, `Response.data` has been set to
29
+ `None`, but the original payload is still available in `Response.raw`.
30
+
31
+ If this Pydantic model is provided by the library, this is not your fault—
32
+ either the model definition is incorrect or Paystack returned data that
33
+ does not match the expected schema. In this case, please open an issue at:
34
+ https://github.com/gray-adeyi/pypaystack2/issues
35
+
36
+ If you are using a custom Pydantic model, ensure that its fields match the
37
+ structure of the data returned by Paystack.
38
+
39
+ Validation errors:
40
+ {error}
41
+
42
+ """
43
+
44
+ SERIALIZATION_FAILED_ON_FAILURE_RESPONSE_WARNING_TEMPLATE = """\
45
+ Deserializing the response returned by Paystack using the Pydantic model
46
+ `{response_data_model_class}` may fail because the request did not return a
47
+ successful HTTP status code. Instead, Paystack responded with
48
+ `{http_status_code}`, which may indicate a different response schema than the
49
+ one expected for a successful request.
50
+
51
+ If a serialization error occurs, `Response.data` will be set to `None`, but the
52
+ original response content will still be available in `Response.raw`.
53
+
35
54
  """
36
55
 
37
56
  # When the function that converts the payload keys that are on in snake_case from
@@ -63,6 +82,19 @@ class AbstractAPIClient(FeesCalculationMixin, ABC):
63
82
  f"or set in env variables as `{self._SECRET_KEY_IN_ENV_KEY}`"
64
83
  )
65
84
 
85
+ def is_verified_webhook_payload(self, payload: bytes, signature: str) -> bool:
86
+ """Checks if the webhook payload is indeed sent by paystack
87
+
88
+ Args:
89
+ payload: is the raw webhook data received that needs validation for authenticity.
90
+ signature: is the `x-paystack-signature` in the response headers of the
91
+ response that included the payload
92
+ """
93
+ digest = hmac.new(
94
+ self._secret_key.encode(), payload, hashlib.sha512
95
+ ).hexdigest()
96
+ return signature == digest
97
+
66
98
  @abstractmethod
67
99
  def _handle_request(
68
100
  self,
@@ -123,6 +155,7 @@ class AbstractAPIClient(FeesCalculationMixin, ABC):
123
155
  if data := response_body.get("data", None):
124
156
  data = self._to_pydantic_model(
125
157
  self._normalize_data(data),
158
+ raw_response.status_code,
126
159
  response_data_model_class,
127
160
  raise_serialization_exception,
128
161
  )
@@ -142,6 +175,7 @@ class AbstractAPIClient(FeesCalculationMixin, ABC):
142
175
  def _to_pydantic_model(
143
176
  self,
144
177
  data: dict[str, Any] | list[Any],
178
+ http_status_code: int,
145
179
  response_data_model_class: Type[PaystackDataModel] | None = None,
146
180
  raise_serialization_exception: bool = False,
147
181
  ) -> PaystackDataModel | list[PaystackDataModel] | None:
@@ -156,12 +190,21 @@ class AbstractAPIClient(FeesCalculationMixin, ABC):
156
190
  if isinstance(data, list):
157
191
  return [response_data_model_class.model_validate(item) for item in data]
158
192
  except ValidationError as error:
193
+ if 200 <= http_status_code <= 299:
194
+ logger.warning(
195
+ SERIALIZATION_FAILED_ON_SUCCESSFUL_RESPONSE_WARNING_MESSAGE_TEMPLATE.format(
196
+ response_data_model_class=response_data_model_class, error=error
197
+ )
198
+ )
199
+ else:
200
+ logger.warning(
201
+ SERIALIZATION_FAILED_ON_FAILURE_RESPONSE_WARNING_TEMPLATE.format(
202
+ response_data_model_class=response_data_model_class,
203
+ http_status_code=http_status_code,
204
+ )
205
+ )
159
206
  if raise_serialization_exception:
160
207
  raise error
161
- logger.warning(
162
- SERIALIZATION_FAILED_WARNING_MESSAGE
163
- % (response_data_model_class, error)
164
- )
165
208
  return None
166
209
 
167
210
  def _serialize_request_kwargs(
@@ -244,7 +287,7 @@ class BaseAPIClient(AbstractAPIClient):
244
287
 
245
288
  try:
246
289
  response = http_method_handler(**request_kwargs) # type: ignore
247
- except NetworkError as error:
290
+ except HTTPError as error:
248
291
  raise ClientNetworkError(f"network error occurred: {error}", error)
249
292
  return self._deserialize_response(
250
293
  response, response_data_model_class, raise_serialization_exception
@@ -284,7 +327,7 @@ class BaseAsyncAPIClient(AbstractAPIClient):
284
327
  raise ValueError("HTTP Request method not recognised or implemented")
285
328
  try:
286
329
  response = await http_method_handler(**request_kwargs)
287
- except NetworkError as error:
330
+ except HTTPError as error:
288
331
  raise ClientNetworkError(f"network error occurred: {error}", error)
289
332
 
290
333
  return self._deserialize_response(
@@ -0,0 +1,21 @@
1
+ from pypaystack2.utils import (
2
+ WEBHOOK_DEPENDENCY_IMPORT_ERROR_MESSAGE_TEMPLATE,
3
+ try_import_module,
4
+ )
5
+ from pypaystack2.webhook.cli import webhook_cli_app
6
+
7
+ # for now only the webhook feature needs the cli from a consumer standpoint so the error message is sufficient
8
+ typer_module = try_import_module(
9
+ "typer",
10
+ error_msg=WEBHOOK_DEPENDENCY_IMPORT_ERROR_MESSAGE_TEMPLATE.format(
11
+ package_name="typer"
12
+ ),
13
+ )
14
+
15
+
16
+ cli_app = typer_module.Typer()
17
+ cli_app.add_typer(
18
+ webhook_cli_app,
19
+ name="webhook",
20
+ help="Webhook CLI app for working with paystack webhooks. Try `pypaystack2 webhook --help`",
21
+ )
@@ -44,10 +44,13 @@ class Channel(StrEnum):
44
44
 
45
45
  CARD = "card"
46
46
  BANK = "bank"
47
+ APPLE_PAY = "apple_pay"
47
48
  USSD = "ussd"
48
49
  QR = "qr"
49
50
  MOBILE_MONEY = "mobile_money"
50
51
  BANK_TRANSFER = "bank_transfer"
52
+ EFT = "eft"
53
+ PAYATTITUDE = "payattitude"
51
54
 
52
55
 
53
56
  class Bearer(StrEnum):
@@ -1,3 +1,9 @@
1
+ from pypaystack2.sub_clients.async_clients.direct_debits import AsyncDirectDebitClient
2
+ from pypaystack2.sub_clients.sync_clients.direct_debits import DirectDebitClient
3
+ from pypaystack2.sub_clients.async_clients.virtual_terminals import (
4
+ AsyncVirtualTerminalClient,
5
+ )
6
+ from pypaystack2.sub_clients.sync_clients.virtual_terminals import VirtualTerminalClient
1
7
  from pypaystack2.base_clients import BaseAPIClient, BaseAsyncAPIClient
2
8
  from pypaystack2.sub_clients import (
3
9
  ApplePayClient,
@@ -102,6 +108,10 @@ class PaystackClient(BaseAPIClient):
102
108
  Transfers control API e.g. `PaystackClient.transfer_control.check_balance`.
103
109
  verification: A binding to `VerificationClient` providing methods for interacting Paystack's Verification API
104
110
  e.g. `PaystackClient.verification.resolve_account_number`.
111
+ virtual_terminals: A binding to `VirtualTerminalClient` providing methods for interacting with Paystack's
112
+ Virtual Terminal API e.g. `VirtualTerminalClient.list`.
113
+ direct_debits: A binding to `DirectDebitClient` providing methods for interacting with Paystack's
114
+ Direct Debit API e.g. `DirectDebitClient.trigger_activation_charge`.
105
115
  """
106
116
 
107
117
  def __init__(self, secret_key: str | None = None):
@@ -157,6 +167,8 @@ class PaystackClient(BaseAPIClient):
157
167
  self.verification: VerificationClient = VerificationClient(
158
168
  secret_key=self._secret_key
159
169
  )
170
+ self.virtual_terminals = VirtualTerminalClient(secret_key=self._secret_key)
171
+ self.direct_debits = DirectDebitClient(secret_key=self._secret_key)
160
172
 
161
173
 
162
174
  class AsyncPaystackClient(BaseAsyncAPIClient):
@@ -167,51 +179,56 @@ class AsyncPaystackClient(BaseAsyncAPIClient):
167
179
 
168
180
  Attributes:
169
181
  apple_pay: A binding to `AsyncApplePayClient` providing methods for interacting Paystack's Apple Pay API
170
- e.g. `PaystackClient.apple_pay.get_domains`.
182
+ e.g. `AsyncPaystackClient.apple_pay.get_domains`.
171
183
  bulk_charges: A binding to `AsyncBulkChargeClient` providing methods for interacting Paystack's Bulk charge API
172
- e.g. `PaystackClient.bulk_charges.initiate`.
184
+ e.g. `AsyncPaystackClient.bulk_charges.initiate`.
173
185
  charge: A binding to `AsyncChargeClient` providing methods for interacting Paystack's Charge API
174
- e.g. `PaystackClient.charge.charge`.
186
+ e.g. `AsyncPaystackClient.charge.charge`.
175
187
  integration: A binding to `AsyncIntegrationClient` providing methods for interacting Paystack's Integration API
176
- e.g. `PaystackClient.integration.get_payment_session_timeout`.
188
+ e.g. `AsyncPaystackClient.integration.get_payment_session_timeout`.
177
189
  customers: A binding to `AsyncCustomerClient` providing methods for interacting Paystack's Customer API
178
- e.g. `PaystackClient.customers.create`.
190
+ e.g. `AsyncPaystackClient.customers.create`.
179
191
  dedicated_accounts: A binding to `AsyncDedicatedAccountClient` providing methods for interacting
180
192
  Paystack's Dedicated account API e.g. `PaystackClient.dedicated_accounts.create`.
181
193
  disputes: A binding to `AsyncDisputeClient` providing methods for interacting Paystack's Dispute API
182
- e.g. `PaystackClient.disputes.`.
194
+ e.g. `AsyncPaystackClient.disputes.`.
183
195
  payment_requests: A binding to `AsyncPaymentRequestClient` providing methods for interacting Paystack's Payment
184
- request API e.g. `PaystackClient.payment_requests.create`.
196
+ request API e.g. `AsyncPaystackClient.payment_requests.create`.
185
197
  miscellaneous: A binding to `AsyncApplePayClient` providing methods for interacting Paystack's Apple Pay API
186
- e.g. `PaystackClient.miscellaneous.get_banks`.
198
+ e.g. `AsyncPaystackClient.miscellaneous.get_banks`.
187
199
  payment_pages: A binding to `AsyncPaymentPageClient` providing methods for interacting Paystack's Payment Page
188
200
  API e.g. `PaystackClient.payment_pages.create`.
189
201
  plans: A binding to `AsyncPlanClient` providing methods for interacting Paystack's Plan API
190
- e.g. `PaystackClient.plans.get_plans`.
202
+ e.g. `AsyncPaystackClient.plans.get_plans`.
191
203
  products: A binding to `AsyncProductClient` providing methods for interacting Paystack's Product API
192
204
  e.g. `PaystackClient.products.get_product`.
193
205
  refunds: A binding to `AsyncRefundClient` providing methods for interacting Paystack's Refund API
194
- e.g. `PaystackClient.refunds.create`.
206
+ e.g. `AsyncPaystackClient.refunds.create`.
195
207
  settlements: A binding to `AsyncSettlementClient` providing methods for interacting Paystack's Settlement API
196
- e.g. `PaystackClient.settlements.get_settlements`.
208
+ e.g. `AsyncPaystackClient.settlements.get_settlements`.
197
209
  splits: A binding to `AsyncTransactionSplitClient` providing methods for interacting Paystack's Transaction
198
- split API e.g. `PaystackClient.splits.create`.
210
+ split API e.g. `AsyncPaystackClient.splits.create`.
199
211
  subaccounts: A binding to `AsyncSubAccountClient` providing methods for interacting Paystack's subaccount API
200
- e.g. `PaystackClient.subaccounts.create`.
212
+ e.g. `AsyncPaystackClient.subaccounts.create`.
201
213
  subscriptions: A binding to `AsyncSubscriptionClient` providing methods for interacting Paystack's Subscription
202
- API e.g. `PaystackClient.subscriptions.create`.
214
+ API e.g. `AsyncPaystackClient.subscriptions.create`.
203
215
  terminals: A binding to `AsyncTerminalClient` providing methods for interacting Paystack's Terminal API
204
- e.g. `PaystackClient.terminals.send_event`.
216
+ e.g. `AsyncPaystackClient.terminals.send_event`.
205
217
  transactions: A binding to `AsyncTransactionClient` providing methods for interacting Paystack's Transaction
206
- API e.g. `PaystackClient.transactions.initiate`.
218
+ API e.g. `AsyncPaystackClient.transactions.initiate`.
207
219
  transfer_recipients: A binding to `AsyncTransferRecipientClient` providing methods for interacting Paystack's
208
- Transfer recipients API e.g. `PaystackClient.transfer_recipients.create`.
220
+ Transfer recipients API e.g. `AsyncPaystackClient.transfer_recipients.create`.
209
221
  transfers: A binding to `AsyncTransferClient` providing methods for interacting Paystack's Transfer API
210
222
  e.g. `PaystackClient.transfers.finalize`.
211
223
  transfer_control: A binding to `AsyncTransferControlClient` providing methods for interacting Paystack's
212
- Transfers control API e.g. `PaystackClient.transfer_control.check_balance`.
224
+ Transfers control API e.g. `AsyncPaystackClient.transfer_control.check_balance`.
213
225
  verification: A binding to `AsyncVerificationClient` providing methods for interacting Paystack's Verification
214
- API e.g. `PaystackClient.verification.resolve_account_number`.
226
+ API e.g. `AsyncPaystackClient.verification.resolve_account_number`.
227
+ virtual_terminals: A binding to `VirtualTerminalClient` providing methods for interacting with Paystack's
228
+ Virtual Terminal API e.g. `AsyncVirtualTerminalClient.list`.
229
+ direct_debits: A binding to `AsyncDirectDebitClient` providing methods for interacting with Paystack's
230
+ Direct Debit API e.g. `AsyncDirectDebitClient.trigger_activation_charge`.
231
+
215
232
  """
216
233
 
217
234
  def __init__(self, secret_key: str | None = None):
@@ -243,3 +260,5 @@ class AsyncPaystackClient(BaseAsyncAPIClient):
243
260
  self.transfers = AsyncTransferClient(secret_key=self._secret_key)
244
261
  self.transfer_control = AsyncTransferControlClient(secret_key=self._secret_key)
245
262
  self.verification = AsyncVerificationClient(secret_key=self._secret_key)
263
+ self.virtual_terminals = AsyncVirtualTerminalClient(secret_key=self._secret_key)
264
+ self.direct_debits = AsyncDirectDebitClient(secret_key=self._secret_key)
@@ -1,5 +1,6 @@
1
1
  # ruff: noqa: F401
2
2
  from pypaystack2.models.payload_models import (
3
+ RefundAccount,
3
4
  BulkChargeInstruction,
4
5
  LineItem,
5
6
  Tax,
@@ -5,6 +5,22 @@ from pydantic import BaseModel, model_validator
5
5
  from pypaystack2.enums import RecipientType, Currency
6
6
 
7
7
 
8
+ class RefundAccount(BaseModel):
9
+ """A dataclass for representing refund account
10
+ details
11
+
12
+ Attributes:
13
+ currency:The currency of the customer's bank account.
14
+ It should be the same as the currency the payment was made
15
+ account_number: The customer's account number
16
+ bank_id: The ID representing the customer's bank.
17
+ """
18
+
19
+ currency: Currency
20
+ account_number: str
21
+ bank_id: str
22
+
23
+
8
24
  class BulkChargeInstruction(BaseModel):
9
25
  """A dataclass for bulk charge instruction.
10
26