zai_payment 2.9.0 → 2.9.1

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.
data/docs/architecture.md DELETED
@@ -1,232 +0,0 @@
1
- # Zai Payment Webhook Architecture
2
-
3
- ```
4
- ┌─────────────────────────────────────────────────────────────────┐
5
- │ Client Application │
6
- └────────────────────────┬────────────────────────────────────────┘
7
-
8
- │ ZaiPayment.webhooks.list()
9
- │ ZaiPayment.webhooks.create(...)
10
- │ ZaiPayment.webhooks.update(...)
11
- │ ZaiPayment.webhooks.delete(...)
12
-
13
-
14
- ┌─────────────────────────────────────────────────────────────────┐
15
- │ ZaiPayment (Module) │
16
- │ ┌───────────────────────────────────────────────────────────┐ │
17
- │ │ config() - Configuration singleton │ │
18
- │ │ auth() - TokenProvider singleton │ │
19
- │ │ webhooks() - Webhook resource singleton │ │
20
- │ └───────────────────────────────────────────────────────────┘ │
21
- └────────────────────────┬────────────────────────────────────────┘
22
-
23
- ┌───────────────┴───────────────┐
24
- │ │
25
- ▼ ▼
26
- ┌──────────────────┐ ┌──────────────────────┐
27
- │ Config │ │ Auth::TokenProvider │
28
- │ ───────────── │ │ ────────────────── │
29
- │ - environment │◄─────────│ Uses config │
30
- │ - client_id │ │ - bearer_token() │
31
- │ - client_secret │ │ - refresh_token() │
32
- │ - scope │ │ - clear_token() │
33
- │ - endpoints() │ │ │
34
- └──────────────────┘ └──────────────────────┘
35
-
36
-
37
-
38
- ┌──────────────────────┐
39
- │ TokenStore │
40
- │ ────────────────── │
41
- │ (MemoryStore) │
42
- │ - fetch() │
43
- │ - write() │
44
- │ - clear() │
45
- └──────────────────────┘
46
-
47
-
48
- ┌─────────────────────────────────────────────────────────────────┐
49
- │ Resources::Webhook (Resource Layer) │
50
- │ ┌───────────────────────────────────────────────────────────┐ │
51
- │ │ list(limit:, offset:) │ │
52
- │ │ show(webhook_id) │ │
53
- │ │ create(url:, object_type:, enabled:, description:) │ │
54
- │ │ update(webhook_id, ...) │ │
55
- │ │ delete(webhook_id) │ │
56
- │ │ │ │
57
- │ │ Private validation methods: │ │
58
- │ │ - validate_id!() │ │
59
- │ │ - validate_presence!() │ │
60
- │ │ - validate_url!() │ │
61
- │ └───────────────────────────────────────────────────────────┘ │
62
- └────────────────────────┬────────────────────────────────────────┘
63
-
64
-
65
- ┌─────────────────────────────────────────────────────────────────┐
66
- │ Client (HTTP Layer) │
67
- │ ┌───────────────────────────────────────────────────────────┐ │
68
- │ │ get(path, params:) │ │
69
- │ │ post(path, body:) │ │
70
- │ │ patch(path, body:) │ │
71
- │ │ delete(path) │ │
72
- │ │ │ │
73
- │ │ Private: │ │
74
- │ │ - connection() - Faraday with auth headers │ │
75
- │ │ - handle_faraday_error() │ │
76
- │ └───────────────────────────────────────────────────────────┘ │
77
- └────────────────────────┬────────────────────────────────────────┘
78
-
79
-
80
- ┌─────────────────────────────────────────────────────────────────┐
81
- │ Faraday (HTTP Client) │
82
- │ ┌───────────────────────────────────────────────────────────┐ │
83
- │ │ Authorization: Bearer <token> │ │
84
- │ │ Content-Type: application/json │ │
85
- │ │ Accept: application/json │ │
86
- │ └───────────────────────────────────────────────────────────┘ │
87
- └────────────────────────┬────────────────────────────────────────┘
88
-
89
-
90
- ┌─────────────────────────────────────────────────────────────────┐
91
- │ Zai API │
92
- │ sandbox.au-0000.api.assemblypay.com/webhooks │
93
- └────────────────────────┬────────────────────────────────────────┘
94
-
95
- │ HTTP Response
96
-
97
- ┌─────────────────────────────────────────────────────────────────┐
98
- │ Response (Wrapper) │
99
- │ ┌───────────────────────────────────────────────────────────┐ │
100
- │ │ status - HTTP status code │ │
101
- │ │ body - Raw response body │ │
102
- │ │ headers - Response headers │ │
103
- │ │ data() - Extracted data │ │
104
- │ │ meta() - Pagination metadata │ │
105
- │ │ success?() - 2xx status check │ │
106
- │ │ client_error?()- 4xx status check │ │
107
- │ │ server_error?()- 5xx status check │ │
108
- │ │ │ │
109
- │ │ Private: │ │
110
- │ │ - check_for_errors!() - Raises specific errors │ │
111
- │ └───────────────────────────────────────────────────────────┘ │
112
- └────────────────────────┬────────────────────────────────────────┘
113
-
114
-
115
- ┌─────────────────────────────────────────────────────────────────┐
116
- │ Error Hierarchy │
117
- │ ┌───────────────────────────────────────────────────────────┐ │
118
- │ │ Error (Base) │ │
119
- │ │ ├── AuthError │ │
120
- │ │ ├── ConfigurationError │ │
121
- │ │ ├── ApiError │ │
122
- │ │ │ ├── BadRequestError (400) │ │
123
- │ │ │ ├── UnauthorizedError (401) │ │
124
- │ │ │ ├── ForbiddenError (403) │ │
125
- │ │ │ ├── NotFoundError (404) │ │
126
- │ │ │ ├── ValidationError (422) │ │
127
- │ │ │ ├── RateLimitError (429) │ │
128
- │ │ │ └── ServerError (5xx) │ │
129
- │ │ ├── TimeoutError │ │
130
- │ │ └── ConnectionError │ │
131
- │ └───────────────────────────────────────────────────────────┘ │
132
- └─────────────────────────────────────────────────────────────────┘
133
- ```
134
-
135
- ## Request Flow
136
-
137
- 1. **Client calls** `ZaiPayment.webhooks.list()`
138
- 2. **Module** returns singleton `Resources::Webhook` instance
139
- 3. **Webhook resource** validates input and calls `client.get('/webhooks', params: {...})`
140
- 4. **Client** prepares HTTP request with authentication
141
- 5. **TokenProvider** provides valid bearer token (auto-refresh if expired)
142
- 6. **Faraday** makes HTTP request to Zai API
143
- 7. **Response** wraps Faraday response
144
- 8. **Response** checks status and raises error if needed
145
- 9. **Response** returns to client with `data()` and `meta()` methods
146
- 10. **Client application** receives response and processes data
147
-
148
- ## Key Design Decisions
149
-
150
- ### 1. Singleton Pattern for Resources
151
- ```ruby
152
- ZaiPayment.webhooks # Always returns same instance
153
- ```
154
- - Reduces object creation overhead
155
- - Consistent configuration across application
156
- - Easy to use in any context
157
-
158
- ### 2. Dependency Injection
159
- ```ruby
160
- Webhook.new(client: custom_client)
161
- ```
162
- - Testable (can inject mock client)
163
- - Flexible (can use different configs)
164
- - Follows SOLID principles
165
-
166
- ### 3. Response Wrapper
167
- ```ruby
168
- response = webhooks.list
169
- response.success? # Boolean check
170
- response.data # Extracted data
171
- response.meta # Pagination info
172
- ```
173
- - Consistent interface across all resources
174
- - Rich API for checking status
175
- - Automatic error handling
176
-
177
- ### 4. Fail Fast Validation
178
- ```ruby
179
- validate_url!(url) # Before API call
180
- ```
181
- - Catches errors early
182
- - Better error messages
183
- - Reduces unnecessary API calls
184
-
185
- ### 5. Resource-Based Organization
186
- ```ruby
187
- lib/zai_payment/resources/
188
- ├── webhook.rb
189
- ├── user.rb # Future
190
- └── item.rb # Future
191
- ```
192
- - Easy to extend
193
- - Clear separation of concerns
194
- - Follows REST principles
195
-
196
- ## Thread Safety
197
-
198
- - ✅ **TokenProvider**: Uses Mutex for thread-safe token refresh
199
- - ✅ **MemoryStore**: Thread-safe token storage
200
- - ✅ **Client**: Creates new Faraday connection per instance
201
- - ✅ **Webhook**: Stateless, no shared mutable state
202
-
203
- ## Extension Points
204
-
205
- Add new resources by following the same pattern:
206
-
207
- ```ruby
208
- # lib/zai_payment/resources/user.rb
209
- module ZaiPayment
210
- module Resources
211
- class User
212
- def initialize(client: nil)
213
- @client = client || Client.new
214
- end
215
-
216
- def list
217
- client.get('/users')
218
- end
219
-
220
- def show(user_id)
221
- client.get("/users/#{user_id}")
222
- end
223
- end
224
- end
225
- end
226
-
227
- # lib/zai_payment.rb
228
- def users
229
- @users ||= Resources::User.new
230
- end
231
- ```
232
-