zai_payment 1.3.2 → 2.0.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/items.md ADDED
@@ -0,0 +1,666 @@
1
+ # Item Management
2
+
3
+ The Item resource provides methods for managing Zai items, which represent transactions or payments between buyers and sellers on your platform.
4
+
5
+ ## Overview
6
+
7
+ Items are the core transactional objects in Zai that represent a payment agreement between a buyer (payin user) and a seller (payout user). Each item tracks:
8
+ - Transaction amount
9
+ - Payment type
10
+ - Buyer and seller information
11
+ - Fees and charges
12
+ - Transaction state and history
13
+ - Wire transfer details (if applicable)
14
+
15
+ ## References
16
+
17
+ - [Zai Items API](https://developer.hellozai.com/reference/listitems)
18
+ - [Create Item](https://developer.hellozai.com/reference/createitem)
19
+ - [Update Item](https://developer.hellozai.com/reference/updateitem)
20
+
21
+ ## Usage
22
+
23
+ ### Initialize the Item Resource
24
+
25
+ ```ruby
26
+ # Using the singleton instance (recommended)
27
+ items = ZaiPayment.items
28
+
29
+ # Or create a new instance
30
+ items = ZaiPayment::Resources::Item.new
31
+ ```
32
+
33
+ ## Methods
34
+
35
+ ### Create Item
36
+
37
+ Create a new item (transaction/payment) between a buyer and a seller.
38
+
39
+ #### Required Fields
40
+
41
+ - `name` - Name/description of the item
42
+ - `amount` - Amount in cents (e.g., 10000 = $100.00)
43
+ - `payment_type` - Payment type (1-7, default: 2 for credit card)
44
+ - `buyer_id` - Buyer user ID
45
+ - `seller_id` - Seller user ID
46
+
47
+ #### Optional Fields
48
+
49
+ - `id` - Custom unique ID for the item
50
+ - `fee_ids` - Array of fee IDs to apply
51
+ - `description` - Detailed description
52
+ - `currency` - Currency code (e.g., 'AUD', 'USD')
53
+ - `custom_descriptor` - Custom text for bank statements
54
+ - `buyer_url` - URL for buyer to access transaction
55
+ - `seller_url` - URL for seller to access transaction
56
+ - `tax_invoice` - Whether to generate a tax invoice (boolean)
57
+
58
+ #### Example
59
+
60
+ ```ruby
61
+ response = ZaiPayment.items.create(
62
+ name: "Product Purchase",
63
+ amount: 10000, # $100.00 in cents
64
+ payment_type: 2, # Credit card
65
+ buyer_id: "buyer-123",
66
+ seller_id: "seller-456",
67
+ description: "Purchase of premium product XYZ",
68
+ currency: "AUD",
69
+ buyer_url: "https://buyer.example.com",
70
+ seller_url: "https://seller.example.com",
71
+ tax_invoice: true
72
+ )
73
+
74
+ if response.success?
75
+ item = response.data
76
+ puts "Item created: #{item['id']}"
77
+ puts "Amount: #{item['amount']}"
78
+ puts "State: #{item['state']}"
79
+ end
80
+ ```
81
+
82
+ #### Create Item with Custom ID
83
+
84
+ ```ruby
85
+ response = ZaiPayment.items.create(
86
+ id: "my-custom-item-#{Time.now.to_i}",
87
+ name: "Custom ID Product",
88
+ amount: 15000,
89
+ payment_type: 2,
90
+ buyer_id: "buyer-123",
91
+ seller_id: "seller-456"
92
+ )
93
+ ```
94
+
95
+ ### List Items
96
+
97
+ Retrieve a list of all items with pagination and optional filtering.
98
+
99
+ ```ruby
100
+ # List items with default pagination (10 items)
101
+ response = ZaiPayment.items.list
102
+
103
+ if response.success?
104
+ items_list = response.data
105
+ items_list.each do |item|
106
+ puts "Item: #{item['name']} - $#{item['amount'] / 100.0}"
107
+ end
108
+
109
+ # Access pagination metadata
110
+ meta = response.meta
111
+ puts "Total items: #{meta['total']}"
112
+ end
113
+ ```
114
+
115
+ #### List with Pagination
116
+
117
+ ```ruby
118
+ # Get 20 items starting from offset 40
119
+ response = ZaiPayment.items.list(limit: 20, offset: 40)
120
+ ```
121
+
122
+ #### Search Items
123
+
124
+ ```ruby
125
+ # Search items by description
126
+ response = ZaiPayment.items.list(search: "product")
127
+
128
+ # Filter by creation date
129
+ response = ZaiPayment.items.list(
130
+ created_after: "2024-01-01T00:00:00Z",
131
+ created_before: "2024-12-31T23:59:59Z"
132
+ )
133
+
134
+ # Combine filters
135
+ response = ZaiPayment.items.list(
136
+ limit: 50,
137
+ search: "premium",
138
+ created_after: "2024-01-01T00:00:00Z"
139
+ )
140
+ ```
141
+
142
+ ### Show Item
143
+
144
+ Get details of a specific item by ID.
145
+
146
+ ```ruby
147
+ response = ZaiPayment.items.show("item-123")
148
+
149
+ if response.success?
150
+ item = response.data
151
+ puts "Item ID: #{item['id']}"
152
+ puts "Name: #{item['name']}"
153
+ puts "Amount: #{item['amount']}"
154
+ puts "Payment Type: #{item['payment_type']}"
155
+ puts "State: #{item['state']}"
156
+ puts "Buyer ID: #{item['buyer_id']}"
157
+ puts "Seller ID: #{item['seller_id']}"
158
+ end
159
+ ```
160
+
161
+ ### Update Item
162
+
163
+ Update an existing item's details.
164
+
165
+ ```ruby
166
+ response = ZaiPayment.items.update(
167
+ "item-123",
168
+ name: "Updated Product Name",
169
+ description: "Updated product description",
170
+ amount: 12000,
171
+ buyer_url: "https://new-buyer.example.com",
172
+ tax_invoice: false
173
+ )
174
+
175
+ if response.success?
176
+ item = response.data
177
+ puts "Item updated: #{item['id']}"
178
+ end
179
+ ```
180
+
181
+ ### Delete Item
182
+
183
+ Delete an item by ID.
184
+
185
+ ```ruby
186
+ response = ZaiPayment.items.delete("item-123")
187
+
188
+ if response.success?
189
+ puts "Item deleted successfully"
190
+ end
191
+ ```
192
+
193
+ ### Show Item Seller
194
+
195
+ Get the seller (user) details for a specific item.
196
+
197
+ ```ruby
198
+ response = ZaiPayment.items.show_seller("item-123")
199
+
200
+ if response.success?
201
+ seller = response.data
202
+ puts "Seller: #{seller['first_name']} #{seller['last_name']}"
203
+ puts "Email: #{seller['email']}"
204
+ puts "Country: #{seller['country']}"
205
+ end
206
+ ```
207
+
208
+ ### Show Item Buyer
209
+
210
+ Get the buyer (user) details for a specific item.
211
+
212
+ ```ruby
213
+ response = ZaiPayment.items.show_buyer("item-123")
214
+
215
+ if response.success?
216
+ buyer = response.data
217
+ puts "Buyer: #{buyer['first_name']} #{buyer['last_name']}"
218
+ puts "Email: #{buyer['email']}"
219
+ end
220
+ ```
221
+
222
+ ### Show Item Fees
223
+
224
+ Get the fees associated with an item.
225
+
226
+ ```ruby
227
+ response = ZaiPayment.items.show_fees("item-123")
228
+
229
+ if response.success?
230
+ fees = response.data
231
+
232
+ if fees && fees.any?
233
+ puts "Item has #{fees.length} fee(s):"
234
+ fees.each do |fee|
235
+ puts " #{fee['name']}: $#{fee['amount'] / 100.0}"
236
+ end
237
+ end
238
+ end
239
+ ```
240
+
241
+ ### Show Item Wire Details
242
+
243
+ Get wire transfer details for an item (useful for bank transfers).
244
+
245
+ ```ruby
246
+ response = ZaiPayment.items.show_wire_details("item-123")
247
+
248
+ if response.success?
249
+ wire_details = response.data['wire_details']
250
+
251
+ if wire_details
252
+ puts "Account Number: #{wire_details['account_number']}"
253
+ puts "Routing Number: #{wire_details['routing_number']}"
254
+ puts "Bank Name: #{wire_details['bank_name']}"
255
+ end
256
+ end
257
+ ```
258
+
259
+ ### List Item Transactions
260
+
261
+ Get all transactions associated with an item.
262
+
263
+ ```ruby
264
+ # List transactions with default pagination
265
+ response = ZaiPayment.items.list_transactions("item-123")
266
+
267
+ if response.success?
268
+ transactions = response.data
269
+
270
+ transactions.each do |transaction|
271
+ puts "Transaction #{transaction['id']}: #{transaction['state']}"
272
+ puts " Amount: $#{transaction['amount'] / 100.0}"
273
+ puts " Type: #{transaction['type']}"
274
+ end
275
+ end
276
+
277
+ # List with custom pagination
278
+ response = ZaiPayment.items.list_transactions("item-123", limit: 50, offset: 100)
279
+ ```
280
+
281
+ ### List Item Batch Transactions
282
+
283
+ Get all batch transactions associated with an item.
284
+
285
+ ```ruby
286
+ response = ZaiPayment.items.list_batch_transactions("item-123")
287
+
288
+ if response.success?
289
+ batch_transactions = response.data
290
+
291
+ batch_transactions.each do |batch|
292
+ puts "Batch #{batch['id']}: #{batch['state']}"
293
+ puts " Amount: $#{batch['amount'] / 100.0}"
294
+ end
295
+ end
296
+
297
+ # List with pagination
298
+ response = ZaiPayment.items.list_batch_transactions("item-123", limit: 25, offset: 50)
299
+ ```
300
+
301
+ ### Show Item Status
302
+
303
+ Get the current status of an item.
304
+
305
+ ```ruby
306
+ response = ZaiPayment.items.show_status("item-123")
307
+
308
+ if response.success?
309
+ status = response.data
310
+ puts "State: #{status['state']}"
311
+ puts "Payment State: #{status['payment_state']}"
312
+ puts "Disbursement State: #{status['disbursement_state']}" if status['disbursement_state']
313
+ end
314
+ ```
315
+
316
+ ## Field Reference
317
+
318
+ ### Item Fields
319
+
320
+ | Field | Type | Description | Required |
321
+ |-------|------|-------------|----------|
322
+ | `id` | String | Unique item ID (auto-generated if not provided) | Optional |
323
+ | `name` | String | Name/title of the item | ✓ |
324
+ | `amount` | Integer | Amount in cents (e.g., 10000 = $100.00) | ✓ |
325
+ | `payment_type` | Integer | Payment type (1-7, default: 2) | ✓ |
326
+ | `buyer_id` | String | Buyer user ID | ✓ |
327
+ | `seller_id` | String | Seller user ID | ✓ |
328
+ | `fee_ids` | Array | Array of fee IDs to apply | Optional |
329
+ | `description` | String | Detailed description | Optional |
330
+ | `currency` | String | Currency code (e.g., 'AUD', 'USD') | Optional |
331
+ | `custom_descriptor` | String | Custom text for bank statements | Optional |
332
+ | `buyer_url` | String | URL for buyer to access transaction | Optional |
333
+ | `seller_url` | String | URL for seller to access transaction | Optional |
334
+ | `tax_invoice` | Boolean | Whether to generate a tax invoice | Optional |
335
+
336
+ ### Payment Types
337
+
338
+ When creating items, you can specify different payment types:
339
+
340
+ | Type | Description |
341
+ |------|-------------|
342
+ | 1 | Direct Debit |
343
+ | 2 | Credit Card (default) |
344
+ | 3 | Bank Transfer |
345
+ | 4 | Wallet |
346
+ | 5 | BPay |
347
+ | 6 | PayPal |
348
+ | 7 | Other |
349
+
350
+ Example:
351
+
352
+ ```ruby
353
+ # Create item with bank transfer payment type
354
+ response = ZaiPayment.items.create(
355
+ name: "Bank Transfer Payment",
356
+ amount: 30000,
357
+ payment_type: 3, # Bank Transfer
358
+ buyer_id: "buyer-123",
359
+ seller_id: "seller-456"
360
+ )
361
+ ```
362
+
363
+ ## Item States
364
+
365
+ Items go through various states during their lifecycle:
366
+
367
+ - `pending` - Item created but not yet paid
368
+ - `payment_pending` - Payment in progress
369
+ - `payment_held` - Payment held (e.g., for review)
370
+ - `payment_deposited` - Payment received and deposited
371
+ - `work_completed` - Work/delivery completed
372
+ - `completed` - Transaction completed successfully
373
+ - `refunded` - Transaction refunded
374
+ - `cancelled` - Transaction cancelled
375
+
376
+ Check the item status using `show_status` method to track these state changes.
377
+
378
+ ## Error Handling
379
+
380
+ The Item resource will raise validation errors for:
381
+
382
+ - Missing required fields
383
+ - Invalid amount (must be positive integer in cents)
384
+ - Invalid payment type (must be 1-7)
385
+ - Invalid item ID format
386
+ - Item not found
387
+
388
+ ```ruby
389
+ begin
390
+ response = ZaiPayment.items.create(
391
+ name: "Product",
392
+ amount: -100, # Invalid: negative amount
393
+ payment_type: 2,
394
+ buyer_id: "buyer-123",
395
+ seller_id: "seller-456"
396
+ )
397
+ rescue ZaiPayment::Errors::ValidationError => e
398
+ puts "Validation error: #{e.message}"
399
+ rescue ZaiPayment::Errors::NotFoundError => e
400
+ puts "Item not found: #{e.message}"
401
+ rescue ZaiPayment::Errors::ApiError => e
402
+ puts "API error: #{e.message}"
403
+ end
404
+ ```
405
+
406
+ ## Best Practices
407
+
408
+ ### 1. Use Meaningful Names and Descriptions
409
+
410
+ Always provide clear, descriptive names and descriptions for items. This helps with:
411
+ - Transaction tracking
412
+ - Customer support
413
+ - Financial reconciliation
414
+
415
+ ```ruby
416
+ response = ZaiPayment.items.create(
417
+ name: "Order #12345 - Premium Widget",
418
+ description: "Premium widget with extended warranty - Customer: John Doe",
419
+ amount: 29900,
420
+ # ... other fields
421
+ )
422
+ ```
423
+
424
+ ### 2. Track Custom IDs
425
+
426
+ If you have your own order/transaction IDs, use the optional `id` field:
427
+
428
+ ```ruby
429
+ response = ZaiPayment.items.create(
430
+ id: "order-#{your_order_id}",
431
+ name: "Order #{your_order_id}",
432
+ # ... other fields
433
+ )
434
+ ```
435
+
436
+ ### 3. Set Buyer and Seller URLs
437
+
438
+ Provide URLs so users can access transaction details on your platform:
439
+
440
+ ```ruby
441
+ response = ZaiPayment.items.create(
442
+ buyer_url: "https://myapp.com/orders/#{order_id}",
443
+ seller_url: "https://myapp.com/sales/#{order_id}",
444
+ # ... other fields
445
+ )
446
+ ```
447
+
448
+ ### 4. Monitor Transaction Status
449
+
450
+ Regularly check item status to track payment and disbursement:
451
+
452
+ ```ruby
453
+ status_response = ZaiPayment.items.show_status(item_id)
454
+ puts "Payment: #{status_response.data['payment_state']}"
455
+ puts "Disbursement: #{status_response.data['disbursement_state']}"
456
+ ```
457
+
458
+ ### 5. Handle Fees Properly
459
+
460
+ If applying platform fees, create fee objects first and reference them:
461
+
462
+ ```ruby
463
+ # Assume you've created fees with IDs: "fee-platform", "fee-service"
464
+ response = ZaiPayment.items.create(
465
+ name: "Product Purchase",
466
+ amount: 50000,
467
+ fee_ids: ["fee-platform", "fee-service"],
468
+ # ... other fields
469
+ )
470
+ ```
471
+
472
+ ## Response Structure
473
+
474
+ ### Successful Response
475
+
476
+ ```ruby
477
+ response.success? # => true
478
+ response.status # => 200 or 201
479
+ response.data # => Item object hash
480
+ response.meta # => Pagination metadata (for list)
481
+ ```
482
+
483
+ ### Item Object Example
484
+
485
+ ```ruby
486
+ {
487
+ "id" => "item-abc123",
488
+ "name" => "Product Purchase",
489
+ "amount" => 10000,
490
+ "payment_type" => 2,
491
+ "buyer_id" => "buyer-123",
492
+ "seller_id" => "seller-456",
493
+ "description" => "Purchase of product XYZ",
494
+ "currency" => "AUD",
495
+ "state" => "pending",
496
+ "payment_state" => "pending",
497
+ "buyer_url" => "https://buyer.example.com",
498
+ "seller_url" => "https://seller.example.com",
499
+ "tax_invoice" => true,
500
+ "created_at" => "2025-01-01T00:00:00Z",
501
+ "updated_at" => "2025-01-01T00:00:00Z"
502
+ }
503
+ ```
504
+
505
+ ## Complete Workflow Example
506
+
507
+ Here's a complete example of creating an item and tracking it through its lifecycle:
508
+
509
+ ```ruby
510
+ require 'zai_payment'
511
+
512
+ # Configure
513
+ ZaiPayment.configure do |config|
514
+ config.client_id = ENV['ZAI_CLIENT_ID']
515
+ config.client_secret = ENV['ZAI_CLIENT_SECRET']
516
+ config.scope = ENV['ZAI_SCOPE']
517
+ config.environment = :prelive
518
+ end
519
+
520
+ items = ZaiPayment.items
521
+
522
+ # 1. Create an item
523
+ create_response = items.create(
524
+ name: "E-commerce Purchase - Order #12345",
525
+ amount: 50000, # $500.00
526
+ payment_type: 2, # Credit card
527
+ buyer_id: "buyer-abc123",
528
+ seller_id: "seller-xyz789",
529
+ description: "Online store purchase - Premium product bundle",
530
+ currency: "AUD",
531
+ buyer_url: "https://store.example.com/orders/12345",
532
+ seller_url: "https://seller.example.com/sales/12345",
533
+ tax_invoice: true
534
+ )
535
+
536
+ if create_response.success?
537
+ item_id = create_response.data['id']
538
+ puts "✓ Item created: #{item_id}"
539
+
540
+ # 2. Get item details
541
+ show_response = items.show(item_id)
542
+ puts "✓ Item: #{show_response.data['name']}"
543
+
544
+ # 3. Get seller details
545
+ seller_response = items.show_seller(item_id)
546
+ puts "✓ Seller: #{seller_response.data['email']}"
547
+
548
+ # 4. Get buyer details
549
+ buyer_response = items.show_buyer(item_id)
550
+ puts "✓ Buyer: #{buyer_response.data['email']}"
551
+
552
+ # 5. Check fees
553
+ fees_response = items.show_fees(item_id)
554
+ if fees_response.success? && fees_response.data&.any?
555
+ total_fees = fees_response.data.sum { |f| f['amount'] }
556
+ puts "✓ Total fees: $#{total_fees / 100.0}"
557
+ end
558
+
559
+ # 6. Monitor status
560
+ status_response = items.show_status(item_id)
561
+ puts "✓ Payment state: #{status_response.data['payment_state']}"
562
+
563
+ # 7. List transactions
564
+ txn_response = items.list_transactions(item_id)
565
+ puts "✓ Transactions: #{txn_response.data&.length || 0}"
566
+
567
+ # 8. Update if needed
568
+ update_response = items.update(
569
+ item_id,
570
+ description: "Updated: Order #12345 - Payment confirmed"
571
+ )
572
+ puts "✓ Item updated" if update_response.success?
573
+ else
574
+ puts "✗ Error: #{create_response.error_message}"
575
+ end
576
+ ```
577
+
578
+ ## Integration with Rails
579
+
580
+ ### In a Controller
581
+
582
+ ```ruby
583
+ class OrdersController < ApplicationController
584
+ def create
585
+ # Create users first (buyer and seller)
586
+ # ... user creation code ...
587
+
588
+ # Create item
589
+ response = ZaiPayment.items.create(
590
+ name: "Order ##{@order.id}",
591
+ amount: (@order.total * 100).to_i, # Convert to cents
592
+ payment_type: 2,
593
+ buyer_id: @buyer_zai_id,
594
+ seller_id: @seller_zai_id,
595
+ description: @order.description,
596
+ buyer_url: order_url(@order),
597
+ seller_url: seller_order_url(@order),
598
+ tax_invoice: @order.requires_tax_invoice?
599
+ )
600
+
601
+ if response.success?
602
+ @order.update(zai_item_id: response.data['id'])
603
+ redirect_to @order, notice: 'Order created successfully'
604
+ else
605
+ flash[:error] = "Payment error: #{response.error_message}"
606
+ render :new
607
+ end
608
+ end
609
+
610
+ def show
611
+ # Get item status from Zai
612
+ if @order.zai_item_id
613
+ response = ZaiPayment.items.show_status(@order.zai_item_id)
614
+ @payment_status = response.data if response.success?
615
+ end
616
+ end
617
+ end
618
+ ```
619
+
620
+ ### In a Background Job
621
+
622
+ ```ruby
623
+ class CheckItemStatusJob < ApplicationJob
624
+ def perform(order_id)
625
+ order = Order.find(order_id)
626
+
627
+ response = ZaiPayment.items.show_status(order.zai_item_id)
628
+
629
+ if response.success?
630
+ status = response.data
631
+
632
+ order.update(
633
+ payment_state: status['payment_state'],
634
+ disbursement_state: status['disbursement_state']
635
+ )
636
+
637
+ # Send notifications based on state
638
+ if status['payment_state'] == 'completed'
639
+ OrderMailer.payment_completed(order).deliver_later
640
+ end
641
+ end
642
+ end
643
+ end
644
+ ```
645
+
646
+ ## Testing
647
+
648
+ The Item resource includes comprehensive test coverage. Run the tests with:
649
+
650
+ ```bash
651
+ bundle exec rspec spec/zai_payment/resources/item_spec.rb
652
+ ```
653
+
654
+ ## See Also
655
+
656
+ - [User Management Guide](users.md) - Managing buyers and sellers
657
+ - [Webhook Documentation](webhooks.md) - Receiving item status updates
658
+ - [Authentication Documentation](authentication.md) - OAuth2 setup
659
+ - [Item Examples](../examples/items.md) - More code examples
660
+
661
+ ## External Resources
662
+
663
+ - [Zai Items API Reference](https://developer.hellozai.com/reference/listitems)
664
+ - [Zai Developer Portal](https://developer.hellozai.com/)
665
+ - [Payment Types Documentation](https://developer.hellozai.com/docs/payment-types)
666
+
@@ -47,7 +47,7 @@ response = ZaiPayment.users.create(
47
47
  first_name: 'Jane',
48
48
  last_name: 'Smith',
49
49
  country: 'AUS',
50
- dob: '19900101',
50
+ dob: '01/01/1990',
51
51
  address_line1: '123 Main St',
52
52
  city: 'Sydney',
53
53
  state: 'NSW',
@@ -83,7 +83,7 @@ response = ZaiPayment.users.update(
83
83
  | first_name | String | ✓ |
84
84
  | last_name | String | ✓ |
85
85
  | country | String (ISO 3166-1 alpha-3) | ✓ |
86
- | dob | String (YYYYMMDD) | ✓ |
86
+ | dob | String (DD/MM/YYYY) | ✓ |
87
87
  | address_line1 | String | ✓ |
88
88
  | city | String | ✓ |
89
89
  | state | String | ✓ |
@@ -106,9 +106,9 @@ country: 'GBR' # United Kingdom
106
106
  country: 'CAN' # Canada
107
107
  ```
108
108
 
109
- ### Date of Birth (YYYYMMDD)
109
+ ### Date of Birth (DD/MM/YYYY)
110
110
  ```ruby
111
- dob: '19900101' # January 1, 1990
111
+ dob: '01/01/1990' # January 1, 1990
112
112
  ```
113
113
 
114
114
  ## Error Handling
@@ -216,7 +216,7 @@ ruby examples/user_demo.rb
216
216
 
217
217
  ## Documentation Links
218
218
 
219
- - [Full User Guide](USERS.md)
219
+ - [Full User Guide](users.md)
220
220
  - [Usage Examples](../examples/users.md)
221
221
  - [Zai: Payin User](https://developer.hellozai.com/docs/onboarding-a-pay-in-user)
222
222
  - [Zai: Payout User](https://developer.hellozai.com/docs/onboarding-a-pay-out-user)
@@ -224,7 +224,7 @@ ruby examples/user_demo.rb
224
224
  ## Support
225
225
 
226
226
  For issues or questions:
227
- 1. Check the [User Management Guide](USERS.md)
227
+ 1. Check the [User Management Guide](users.md)
228
228
  2. Review [Examples](../examples/users.md)
229
229
  3. Visit [Zai Developer Portal](https://developer.hellozai.com/)
230
230
 
@@ -123,7 +123,7 @@ end
123
123
 
124
124
  ## 📚 Full Documentation
125
125
 
126
- - [Complete Setup Guide](WEBHOOKS.md#webhook-security-signature-verification)
126
+ - [Complete Setup Guide](webhooks.md#webhook-security-signature-verification)
127
127
  - [More Examples](../examples/webhooks.md#webhook-security-complete-setup-guide)
128
128
  - [Zai Official Docs](https://developer.hellozai.com/docs/verify-webhook-signatures)
129
129