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/items.md DELETED
@@ -1,1241 +0,0 @@
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
- ### Make Payment
317
-
318
- Process a payment for an item using a card account.
319
-
320
- #### Required Parameters
321
-
322
- - `account_id` - The card account ID to charge (Required)
323
-
324
- #### Optional Parameters
325
-
326
- - `device_id` - Device identifier for fraud detection
327
- - `ip_address` - IP address of the customer
328
- - `cvv` - Card CVV for additional verification
329
- - `merchant_phone` - Merchant contact phone number
330
-
331
- ```ruby
332
- # Make a payment with required parameters
333
- response = ZaiPayment.items.make_payment(
334
- "item-123",
335
- account_id: "card_account-456" # Required
336
- )
337
-
338
- if response.success?
339
- item = response.data
340
- puts "Payment initiated for item: #{item['id']}"
341
- puts "State: #{item['state']}"
342
- puts "Payment State: #{item['payment_state']}"
343
- end
344
- ```
345
-
346
- #### With Optional Parameters
347
-
348
- For enhanced fraud protection, include device and IP address information:
349
-
350
- ```ruby
351
- response = ZaiPayment.items.make_payment(
352
- "item-123",
353
- account_id: "card_account-456", # Required
354
- device_id: "device_789",
355
- ip_address: "192.168.1.1",
356
- cvv: "123",
357
- merchant_phone: "+61412345678"
358
- )
359
-
360
- if response.success?
361
- item = response.data
362
- puts "Payment initiated successfully"
363
- puts "Item State: #{item['state']}"
364
- puts "Payment State: #{item['payment_state']}"
365
- end
366
- ```
367
-
368
- ### Make Async Payment
369
-
370
- Initiate a card payment with 3D Secure 2.0 (3DS2) authentication support. This endpoint initiates the payment process and returns a `payment_token` that is required for 3DS2 component initialisation on the client side.
371
-
372
- This method is specifically designed for payments that require 3D Secure verification, providing enhanced security for card transactions.
373
-
374
- #### Required Parameters
375
-
376
- - `account_id` - The card account ID to charge (Required). Note: This is the account ID, not the user ID.
377
-
378
- #### Optional Parameters
379
-
380
- - `request_three_d_secure` - Customise the 3DS preference for this payment. Allowed values:
381
- - `'automatic'` (default) - 3DS preference is determined automatically by the system
382
- - `'challenge'` - Request a 3DS challenge is presented to the user
383
- - `'any'` - Request a 3DS challenge regardless of the challenge flow
384
-
385
- #### Response
386
-
387
- The response includes:
388
- - `payment_id` - Unique identifier for the payment
389
- - `payment_token` - Token required for 3DS2 component initialisation
390
- - `account_id` - The account ID used for the payment
391
- - `items` - Complete item details including state, amount, and related information
392
-
393
- ```ruby
394
- # Make an async payment with required parameters
395
- response = ZaiPayment.items.make_payment_async(
396
- "item-123",
397
- account_id: "card_account-456" # Required
398
- )
399
-
400
- if response.success?
401
- payment_id = response.data['payment_id']
402
- payment_token = response.data['payment_token']
403
- item = response.data['items']
404
-
405
- puts "Payment initiated: #{payment_id}"
406
- puts "Payment token for 3DS2: #{payment_token}"
407
- puts "Item state: #{item['state']}"
408
- puts "Amount: $#{item['amount'] / 100.0}"
409
- end
410
- ```
411
-
412
- #### With 3DS Challenge
413
-
414
- To explicitly request a 3D Secure challenge:
415
-
416
- ```ruby
417
- response = ZaiPayment.items.make_payment_async(
418
- "item-123",
419
- account_id: "card_account-456",
420
- request_three_d_secure: "challenge"
421
- )
422
-
423
- if response.success?
424
- payment_token = response.data['payment_token']
425
-
426
- # Use the payment_token to initialise the 3DS2 web component
427
- puts "Payment token: #{payment_token}"
428
- puts "Initialise 3DS2 component on client side with this token"
429
- end
430
- ```
431
-
432
- #### Automatic 3DS Determination
433
-
434
- When using the default 'automatic' mode, the system determines whether 3DS is required:
435
-
436
- ```ruby
437
- response = ZaiPayment.items.make_payment_async(
438
- "item-123",
439
- account_id: "card_account-456",
440
- request_three_d_secure: "automatic"
441
- )
442
-
443
- if response.success?
444
- item = response.data['items']
445
- payment_token = response.data['payment_token']
446
-
447
- puts "3DS handled automatically"
448
- puts "Item state: #{item['state']}"
449
-
450
- # The payment_token will be provided if 3DS is required
451
- if payment_token
452
- puts "3DS verification required - use token: #{payment_token}"
453
- else
454
- puts "3DS verification not required - payment processed"
455
- end
456
- end
457
- ```
458
-
459
- #### Important Notes
460
-
461
- - The `payment_token` returned must be used to initialise the 3DS2 web component on the client side
462
- - After 3DS authentication is complete, the payment will automatically be processed
463
- - If 3DS verification fails or is abandoned, the payment will be cancelled
464
- - This endpoint supports 3D Secure 2.0, providing a better user experience than legacy 3DS 1.0
465
- - Always handle the response appropriately and provide clear instructions to users if 3DS verification is required
466
-
467
- **See also:** For more information on implementing 3D Secure on the client side, refer to the [Zai 3DS Integration Guide](https://developer.hellozai.com).
468
-
469
- ### Authorize Payment
470
-
471
- Authorize a payment without immediately capturing funds. This is useful for pre-authorization scenarios where you want to verify the card and hold funds before completing the transaction.
472
-
473
- #### Required Parameters
474
-
475
- - `account_id` - The card account ID to authorize (Required)
476
-
477
- #### Optional Parameters
478
-
479
- - `cvv` - Card CVV for additional verification
480
- - `merchant_phone` - Merchant contact phone number
481
-
482
- ```ruby
483
- # Authorize a payment
484
- response = ZaiPayment.items.authorize_payment(
485
- "item-123",
486
- account_id: "card_account-456" # Required
487
- )
488
-
489
- if response.success?
490
- item = response.data
491
- puts "Payment authorized for item: #{item['id']}"
492
- puts "State: #{item['state']}"
493
- puts "Payment State: #{item['payment_state']}"
494
- end
495
- ```
496
-
497
- #### Authorize with Optional Parameters
498
-
499
- ```ruby
500
- response = ZaiPayment.items.authorize_payment(
501
- "item-123",
502
- account_id: "card_account-456", # Required
503
- cvv: "123",
504
- merchant_phone: "+61412345678"
505
- )
506
-
507
- if response.success?
508
- item = response.data
509
- puts "Payment authorized with CVV verification"
510
- puts "Item State: #{item['state']}"
511
- puts "Payment State: #{item['payment_state']}"
512
- end
513
- ```
514
-
515
- **Note:** After authorizing a payment, you'll need to capture it separately to complete the transaction. Authorized funds are typically held for 7 days before being automatically released.
516
-
517
- ### Capture Payment
518
-
519
- Capture a previously authorized payment to complete the transaction and transfer funds. This is the second step in a two-step payment process (authorize → capture).
520
-
521
- #### Optional Parameters
522
-
523
- - `amount` - Amount to capture in cents (Optional). If not provided, captures the full authorized amount.
524
-
525
- ```ruby
526
- # Capture the full authorized amount
527
- response = ZaiPayment.items.capture_payment("item-123")
528
-
529
- if response.success?
530
- item = response.data
531
- puts "Payment captured for item: #{item['id']}"
532
- puts "State: #{item['state']}"
533
- puts "Payment State: #{item['payment_state']}"
534
- end
535
- ```
536
-
537
- #### Capture with Specific Amount (Partial Capture)
538
-
539
- You can capture a partial amount of the authorized funds:
540
-
541
- ```ruby
542
- # Capture only $50 of a $100 authorized payment
543
- response = ZaiPayment.items.capture_payment(
544
- "item-123",
545
- amount: 5000 # $50.00 in cents
546
- )
547
-
548
- if response.success?
549
- item = response.data
550
- puts "Partial payment captured: $#{item['amount'] / 100.0}"
551
- puts "Item State: #{item['state']}"
552
- puts "Payment State: #{item['payment_state']}"
553
- end
554
- ```
555
-
556
- #### Capture with Status Check
557
-
558
- Check authorization status before attempting to capture:
559
-
560
- ```ruby
561
- # Check current status
562
- status_response = ZaiPayment.items.show_status("item-123")
563
-
564
- if status_response.success?
565
- payment_state = status_response.data['payment_state']
566
-
567
- # Only capture if payment is authorized
568
- if payment_state == 'authorized' || payment_state == 'payment_authorized'
569
- capture_response = ZaiPayment.items.capture_payment("item-123")
570
-
571
- if capture_response.success?
572
- puts "✓ Payment captured successfully"
573
- else
574
- puts "✗ Capture failed: #{capture_response.error_message}"
575
- end
576
- else
577
- puts "Payment cannot be captured - current state: #{payment_state}"
578
- end
579
- end
580
- ```
581
-
582
- #### Authorization and Capture Workflow
583
-
584
- Complete example of the authorize → capture workflow:
585
-
586
- ```ruby
587
- # Step 1: Authorize the payment
588
- auth_response = ZaiPayment.items.authorize_payment(
589
- "item-123",
590
- account_id: "card_account-456",
591
- cvv: "123"
592
- )
593
-
594
- if auth_response.success?
595
- puts "✓ Payment authorized"
596
-
597
- # Step 2: Verify authorization
598
- status = ZaiPayment.items.show_status("item-123")
599
- puts "Payment State: #{status.data['payment_state']}"
600
-
601
- # Step 3: Capture the payment (can be done immediately or later)
602
- capture_response = ZaiPayment.items.capture_payment("item-123")
603
-
604
- if capture_response.success?
605
- puts "✓ Payment captured and completed"
606
- puts "Final State: #{capture_response.data['payment_state']}"
607
- else
608
- puts "✗ Capture failed: #{capture_response.error_message}"
609
- end
610
- end
611
- ```
612
-
613
- #### Capture States and Conditions
614
-
615
- Payments can be captured when in these states:
616
-
617
- | State | Can Capture? | Description |
618
- |-------|-------------|-------------|
619
- | `authorized` | ✓ Yes | Payment authorized and ready to capture |
620
- | `payment_authorized` | ✓ Yes | Payment authorized and ready to capture |
621
- | `pending` | ✗ No | Payment not authorized yet |
622
- | `payment_pending` | ✗ No | Payment processing, not authorized |
623
- | `completed` | ✗ No | Already captured |
624
- | `payment_deposited` | ✗ No | Already captured and deposited |
625
- | `cancelled` | ✗ No | Authorization cancelled |
626
- | `refunded` | ✗ No | Payment refunded |
627
-
628
- **Important Notes:**
629
- - Authorizations typically expire after 7 days if not captured
630
- - Partial captures are supported (capturing less than the authorized amount)
631
- - Once captured, the payment cannot be un-captured (but can be refunded)
632
- - Some card networks may support multiple partial captures, check with Zai support
633
- - The remaining authorized amount (if any) is automatically released after capture
634
-
635
- ### Void Payment
636
-
637
- Void a previously authorized payment to immediately release the held funds without capturing them. This is typically used when you need to cancel an authorized payment before capturing it.
638
-
639
- ```ruby
640
- # Void an authorized payment
641
- response = ZaiPayment.items.void_payment("item-123")
642
-
643
- if response.success?
644
- item = response.data
645
- puts "Payment voided successfully"
646
- puts "Item ID: #{item['id']}"
647
- puts "State: #{item['state']}"
648
- puts "Payment State: #{item['payment_state']}"
649
- else
650
- puts "Void failed: #{response.error_message}"
651
- end
652
- ```
653
-
654
- #### Void with Status Check
655
-
656
- Check authorization status before attempting to void:
657
-
658
- ```ruby
659
- # Check current status
660
- status_response = ZaiPayment.items.show_status("item-123")
661
-
662
- if status_response.success?
663
- payment_state = status_response.data['payment_state']
664
-
665
- # Only void if payment is authorized
666
- if payment_state == 'authorized' || payment_state == 'payment_authorized'
667
- void_response = ZaiPayment.items.void_payment("item-123")
668
-
669
- if void_response.success?
670
- puts "✓ Payment voided successfully"
671
- else
672
- puts "✗ Void failed: #{void_response.error_message}"
673
- end
674
- else
675
- puts "Payment cannot be voided - current state: #{payment_state}"
676
- end
677
- end
678
- ```
679
-
680
- #### Authorization Management Workflow
681
-
682
- Complete example showing authorize → void workflow:
683
-
684
- ```ruby
685
- # Step 1: Authorize the payment
686
- auth_response = ZaiPayment.items.authorize_payment(
687
- "item-123",
688
- account_id: "card_account-456",
689
- cvv: "123"
690
- )
691
-
692
- if auth_response.success?
693
- puts "✓ Payment authorized"
694
-
695
- # Step 2: Verify authorization
696
- status = ZaiPayment.items.show_status("item-123")
697
- puts "Payment State: #{status.data['payment_state']}"
698
-
699
- # Step 3: Void the payment (cancel the authorization)
700
- void_response = ZaiPayment.items.void_payment("item-123")
701
-
702
- if void_response.success?
703
- puts "✓ Payment voided - funds released"
704
- puts "Final State: #{void_response.data['payment_state']}"
705
- else
706
- puts "✗ Void failed: #{void_response.error_message}"
707
- end
708
- end
709
- ```
710
-
711
- #### Void vs Cancel vs Refund
712
-
713
- Understanding when to use each operation:
714
-
715
- | Operation | Use When | Payment State | Funds Status |
716
- |-----------|----------|---------------|--------------|
717
- | **Void** | Payment is authorized but not captured | `authorized`, `payment_authorized` | Funds held but not transferred |
718
- | **Cancel** | Item created but payment not yet authorized | `pending`, `payment_pending` | No funds involved |
719
- | **Refund** | Payment captured and completed | `completed`, `payment_deposited` | Funds already transferred |
720
-
721
- **Key Differences:**
722
- - **Void**: Releases authorized (held) funds immediately without any transfer
723
- - **Cancel**: Cancels the entire transaction before any payment authorization
724
- - **Refund**: Returns funds after they've been captured and transferred
725
-
726
- #### Void States and Conditions
727
-
728
- Payments can be voided when in these states:
729
-
730
- | State | Can Void? | Description |
731
- |-------|-----------|-------------|
732
- | `authorized` | ✓ Yes | Payment authorized and ready to void |
733
- | `payment_authorized` | ✓ Yes | Payment authorized and ready to void |
734
- | `pending` | ✗ No | Payment not authorized yet, use cancel |
735
- | `payment_pending` | ✗ No | Payment processing, use cancel |
736
- | `completed` | ✗ No | Already captured, use refund |
737
- | `payment_deposited` | ✗ No | Already captured, use refund |
738
- | `cancelled` | ✗ No | Already cancelled |
739
- | `refunded` | ✗ No | Already refunded |
740
- | `voided` | ✗ No | Already voided |
741
-
742
- **Important Notes:**
743
- - Voiding a payment immediately releases the held funds to the cardholder
744
- - Once voided, the authorization cannot be reversed or captured
745
- - Void is instant - no settlement period required
746
- - No fees are charged for voiding an authorization
747
- - Voided authorizations do not appear on cardholder statements
748
-
749
- ### Cancel Item
750
-
751
- Cancel a pending item/payment. This operation is typically used to cancel an item before payment has been processed or completed.
752
-
753
- ```ruby
754
- response = ZaiPayment.items.cancel("item-123")
755
-
756
- if response.success?
757
- item = response.data
758
- puts "Item cancelled successfully"
759
- puts "Item ID: #{item['id']}"
760
- puts "State: #{item['state']}"
761
- puts "Payment State: #{item['payment_state']}"
762
- else
763
- puts "Cancel failed: #{response.error_message}"
764
- end
765
- ```
766
-
767
- #### Cancel with Status Check
768
-
769
- Check item status before attempting to cancel:
770
-
771
- ```ruby
772
- # Check current status
773
- status_response = ZaiPayment.items.show_status("item-123")
774
-
775
- if status_response.success?
776
- current_state = status_response.data['state']
777
-
778
- # Only cancel if in a cancellable state
779
- if ['pending', 'payment_pending'].include?(current_state)
780
- cancel_response = ZaiPayment.items.cancel("item-123")
781
-
782
- if cancel_response.success?
783
- puts "✓ Item cancelled successfully"
784
- else
785
- puts "✗ Cancel failed: #{cancel_response.error_message}"
786
- end
787
- else
788
- puts "Item cannot be cancelled - current state: #{current_state}"
789
- end
790
- end
791
- ```
792
-
793
- #### Cancel States and Conditions
794
-
795
- Items can typically be cancelled when in these states:
796
-
797
- | State | Can Cancel? | Description |
798
- |-------|-------------|-------------|
799
- | `pending` | ✓ Yes | Item created but no payment initiated |
800
- | `payment_pending` | ✓ Yes | Payment initiated but not yet processed |
801
- | `payment_processing` | Maybe | Depends on payment processor |
802
- | `completed` | ✗ No | Payment completed, must refund instead |
803
- | `payment_held` | Maybe | May require admin approval |
804
- | `cancelled` | ✗ No | Already cancelled |
805
- | `refunded` | ✗ No | Already refunded |
806
-
807
- **Note:** If an item is already completed or funds have been disbursed, you cannot cancel it. In those cases, you may need to process a refund instead (contact Zai support for refund procedures).
808
-
809
- ### Refund Item
810
-
811
- Process a refund for a completed payment. This operation returns funds to the buyer and is typically used for customer returns, disputes, or service issues.
812
-
813
- ```ruby
814
- response = ZaiPayment.items.refund("item-123")
815
-
816
- if response.success?
817
- item = response.data
818
- puts "Item refunded successfully"
819
- puts "Item ID: #{item['id']}"
820
- puts "State: #{item['state']}"
821
- puts "Payment State: #{item['payment_state']}"
822
- else
823
- puts "Refund failed: #{response.error_message}"
824
- end
825
- ```
826
-
827
- #### Refund with Optional Parameters
828
-
829
- You can optionally specify a refund amount (for partial refunds), a refund message, and the account to refund to:
830
-
831
- ```ruby
832
- response = ZaiPayment.items.refund(
833
- "item-123",
834
- refund_amount: 5000, # Partial refund of $50.00 (in cents)
835
- refund_message: "Refund for damaged product",
836
- account_id: "account_789" # Specific account to refund to
837
- )
838
-
839
- if response.success?
840
- item = response.data
841
- puts "✓ Partial refund processed: $#{item['refund_amount'] / 100.0}"
842
- puts " State: #{item['state']}"
843
- puts " Payment State: #{item['payment_state']}"
844
- end
845
- ```
846
-
847
- #### Refund with Status Check
848
-
849
- Check item status before attempting to refund:
850
-
851
- ```ruby
852
- # Check current status
853
- status_response = ZaiPayment.items.show_status("item-123")
854
-
855
- if status_response.success?
856
- current_state = status_response.data['state']
857
- payment_state = status_response.data['payment_state']
858
-
859
- # Only refund if in a refundable state
860
- if ['completed', 'payment_deposited'].include?(payment_state)
861
- refund_response = ZaiPayment.items.refund("item-123")
862
-
863
- if refund_response.success?
864
- puts "✓ Item refunded successfully"
865
- else
866
- puts "✗ Refund failed: #{refund_response.error_message}"
867
- end
868
- else
869
- puts "Item cannot be refunded - payment state: #{payment_state}"
870
- end
871
- end
872
- ```
873
-
874
- #### Refund States and Conditions
875
-
876
- Items can typically be refunded when in these states:
877
-
878
- | State | Can Refund? | Description |
879
- |-------|-------------|-------------|
880
- | `pending` | ✗ No | Item not yet paid, cancel instead |
881
- | `payment_pending` | ✗ No | Payment not completed, cancel instead |
882
- | `completed` | ✓ Yes | Payment completed successfully |
883
- | `payment_deposited` | ✓ Yes | Payment received and deposited |
884
- | `work_completed` | ✓ Yes | Work completed, funds can be refunded |
885
- | `cancelled` | ✗ No | Already cancelled |
886
- | `refunded` | ✗ No | Already refunded |
887
- | `payment_held` | Maybe | May require admin approval |
888
-
889
- **Note:** Full refunds return the entire item amount. Partial refunds return a specified amount less than the total. Multiple partial refunds may be possible depending on your Zai configuration.
890
-
891
- ## Field Reference
892
-
893
- ### Item Fields
894
-
895
- | Field | Type | Description | Required |
896
- |-------|------|-------------|----------|
897
- | `id` | String | Unique item ID (auto-generated if not provided) | Optional |
898
- | `name` | String | Name/title of the item | ✓ |
899
- | `amount` | Integer | Amount in cents (e.g., 10000 = $100.00) | ✓ |
900
- | `payment_type` | Integer | Payment type (1-7, default: 2) | ✓ |
901
- | `buyer_id` | String | Buyer user ID | ✓ |
902
- | `seller_id` | String | Seller user ID | ✓ |
903
- | `fee_ids` | Array | Array of fee IDs to apply | Optional |
904
- | `description` | String | Detailed description | Optional |
905
- | `currency` | String | Currency code (e.g., 'AUD', 'USD') | Optional |
906
- | `custom_descriptor` | String | Custom text for bank statements | Optional |
907
- | `buyer_url` | String | URL for buyer to access transaction | Optional |
908
- | `seller_url` | String | URL for seller to access transaction | Optional |
909
- | `tax_invoice` | Boolean | Whether to generate a tax invoice | Optional |
910
-
911
- ### Payment Types
912
-
913
- When creating items, you can specify different payment types:
914
-
915
- | Type | Description |
916
- |------|-------------|
917
- | 1 | Direct Debit |
918
- | 2 | Credit Card (default) |
919
- | 3 | Bank Transfer |
920
- | 4 | Wallet |
921
- | 5 | BPay |
922
- | 6 | PayPal |
923
- | 7 | Other |
924
-
925
- Example:
926
-
927
- ```ruby
928
- # Create item with bank transfer payment type
929
- response = ZaiPayment.items.create(
930
- name: "Bank Transfer Payment",
931
- amount: 30000,
932
- payment_type: 3, # Bank Transfer
933
- buyer_id: "buyer-123",
934
- seller_id: "seller-456"
935
- )
936
- ```
937
-
938
- ## Item States
939
-
940
- Items go through various states during their lifecycle:
941
-
942
- - `pending` - Item created but not yet paid
943
- - `payment_pending` - Payment in progress
944
- - `payment_held` - Payment held (e.g., for review)
945
- - `payment_deposited` - Payment received and deposited
946
- - `work_completed` - Work/delivery completed
947
- - `completed` - Transaction completed successfully
948
- - `refunded` - Transaction refunded
949
- - `cancelled` - Transaction cancelled
950
-
951
- Check the item status using `show_status` method to track these state changes.
952
-
953
- ## Error Handling
954
-
955
- The Item resource will raise validation errors for:
956
-
957
- - Missing required fields
958
- - Invalid amount (must be positive integer in cents)
959
- - Invalid payment type (must be 1-7)
960
- - Invalid item ID format
961
- - Item not found
962
-
963
- ```ruby
964
- begin
965
- response = ZaiPayment.items.create(
966
- name: "Product",
967
- amount: -100, # Invalid: negative amount
968
- payment_type: 2,
969
- buyer_id: "buyer-123",
970
- seller_id: "seller-456"
971
- )
972
- rescue ZaiPayment::Errors::ValidationError => e
973
- puts "Validation error: #{e.message}"
974
- rescue ZaiPayment::Errors::NotFoundError => e
975
- puts "Item not found: #{e.message}"
976
- rescue ZaiPayment::Errors::ApiError => e
977
- puts "API error: #{e.message}"
978
- end
979
- ```
980
-
981
- ## Best Practices
982
-
983
- ### 1. Use Meaningful Names and Descriptions
984
-
985
- Always provide clear, descriptive names and descriptions for items. This helps with:
986
- - Transaction tracking
987
- - Customer support
988
- - Financial reconciliation
989
-
990
- ```ruby
991
- response = ZaiPayment.items.create(
992
- name: "Order #12345 - Premium Widget",
993
- description: "Premium widget with extended warranty - Customer: John Doe",
994
- amount: 29900,
995
- # ... other fields
996
- )
997
- ```
998
-
999
- ### 2. Track Custom IDs
1000
-
1001
- If you have your own order/transaction IDs, use the optional `id` field:
1002
-
1003
- ```ruby
1004
- response = ZaiPayment.items.create(
1005
- id: "order-#{your_order_id}",
1006
- name: "Order #{your_order_id}",
1007
- # ... other fields
1008
- )
1009
- ```
1010
-
1011
- ### 3. Set Buyer and Seller URLs
1012
-
1013
- Provide URLs so users can access transaction details on your platform:
1014
-
1015
- ```ruby
1016
- response = ZaiPayment.items.create(
1017
- buyer_url: "https://myapp.com/orders/#{order_id}",
1018
- seller_url: "https://myapp.com/sales/#{order_id}",
1019
- # ... other fields
1020
- )
1021
- ```
1022
-
1023
- ### 4. Monitor Transaction Status
1024
-
1025
- Regularly check item status to track payment and disbursement:
1026
-
1027
- ```ruby
1028
- status_response = ZaiPayment.items.show_status(item_id)
1029
- puts "Payment: #{status_response.data['payment_state']}"
1030
- puts "Disbursement: #{status_response.data['disbursement_state']}"
1031
- ```
1032
-
1033
- ### 5. Handle Fees Properly
1034
-
1035
- If applying platform fees, create fee objects first and reference them:
1036
-
1037
- ```ruby
1038
- # Assume you've created fees with IDs: "fee-platform", "fee-service"
1039
- response = ZaiPayment.items.create(
1040
- name: "Product Purchase",
1041
- amount: 50000,
1042
- fee_ids: ["fee-platform", "fee-service"],
1043
- # ... other fields
1044
- )
1045
- ```
1046
-
1047
- ## Response Structure
1048
-
1049
- ### Successful Response
1050
-
1051
- ```ruby
1052
- response.success? # => true
1053
- response.status # => 200 or 201
1054
- response.data # => Item object hash
1055
- response.meta # => Pagination metadata (for list)
1056
- ```
1057
-
1058
- ### Item Object Example
1059
-
1060
- ```ruby
1061
- {
1062
- "id" => "item-abc123",
1063
- "name" => "Product Purchase",
1064
- "amount" => 10000,
1065
- "payment_type" => 2,
1066
- "buyer_id" => "buyer-123",
1067
- "seller_id" => "seller-456",
1068
- "description" => "Purchase of product XYZ",
1069
- "currency" => "AUD",
1070
- "state" => "pending",
1071
- "payment_state" => "pending",
1072
- "buyer_url" => "https://buyer.example.com",
1073
- "seller_url" => "https://seller.example.com",
1074
- "tax_invoice" => true,
1075
- "created_at" => "2025-01-01T00:00:00Z",
1076
- "updated_at" => "2025-01-01T00:00:00Z"
1077
- }
1078
- ```
1079
-
1080
- ## Complete Workflow Example
1081
-
1082
- Here's a complete example of creating an item and tracking it through its lifecycle:
1083
-
1084
- ```ruby
1085
- require 'zai_payment'
1086
-
1087
- # Configure
1088
- ZaiPayment.configure do |config|
1089
- config.client_id = ENV['ZAI_CLIENT_ID']
1090
- config.client_secret = ENV['ZAI_CLIENT_SECRET']
1091
- config.scope = ENV['ZAI_SCOPE']
1092
- config.environment = :prelive
1093
- end
1094
-
1095
- items = ZaiPayment.items
1096
-
1097
- # 1. Create an item
1098
- create_response = items.create(
1099
- name: "E-commerce Purchase - Order #12345",
1100
- amount: 50000, # $500.00
1101
- payment_type: 2, # Credit card
1102
- buyer_id: "buyer-abc123",
1103
- seller_id: "seller-xyz789",
1104
- description: "Online store purchase - Premium product bundle",
1105
- currency: "AUD",
1106
- buyer_url: "https://store.example.com/orders/12345",
1107
- seller_url: "https://seller.example.com/sales/12345",
1108
- tax_invoice: true
1109
- )
1110
-
1111
- if create_response.success?
1112
- item_id = create_response.data['id']
1113
- puts "✓ Item created: #{item_id}"
1114
-
1115
- # 2. Get item details
1116
- show_response = items.show(item_id)
1117
- puts "✓ Item: #{show_response.data['name']}"
1118
-
1119
- # 3. Get seller details
1120
- seller_response = items.show_seller(item_id)
1121
- puts "✓ Seller: #{seller_response.data['email']}"
1122
-
1123
- # 4. Get buyer details
1124
- buyer_response = items.show_buyer(item_id)
1125
- puts "✓ Buyer: #{buyer_response.data['email']}"
1126
-
1127
- # 5. Check fees
1128
- fees_response = items.show_fees(item_id)
1129
- if fees_response.success? && fees_response.data&.any?
1130
- total_fees = fees_response.data.sum { |f| f['amount'] }
1131
- puts "✓ Total fees: $#{total_fees / 100.0}"
1132
- end
1133
-
1134
- # 6. Monitor status
1135
- status_response = items.show_status(item_id)
1136
- puts "✓ Payment state: #{status_response.data['payment_state']}"
1137
-
1138
- # 7. List transactions
1139
- txn_response = items.list_transactions(item_id)
1140
- puts "✓ Transactions: #{txn_response.data&.length || 0}"
1141
-
1142
- # 8. Update if needed
1143
- update_response = items.update(
1144
- item_id,
1145
- description: "Updated: Order #12345 - Payment confirmed"
1146
- )
1147
- puts "✓ Item updated" if update_response.success?
1148
- else
1149
- puts "✗ Error: #{create_response.error_message}"
1150
- end
1151
- ```
1152
-
1153
- ## Integration with Rails
1154
-
1155
- ### In a Controller
1156
-
1157
- ```ruby
1158
- class OrdersController < ApplicationController
1159
- def create
1160
- # Create users first (buyer and seller)
1161
- # ... user creation code ...
1162
-
1163
- # Create item
1164
- response = ZaiPayment.items.create(
1165
- name: "Order ##{@order.id}",
1166
- amount: (@order.total * 100).to_i, # Convert to cents
1167
- payment_type: 2,
1168
- buyer_id: @buyer_zai_id,
1169
- seller_id: @seller_zai_id,
1170
- description: @order.description,
1171
- buyer_url: order_url(@order),
1172
- seller_url: seller_order_url(@order),
1173
- tax_invoice: @order.requires_tax_invoice?
1174
- )
1175
-
1176
- if response.success?
1177
- @order.update(zai_item_id: response.data['id'])
1178
- redirect_to @order, notice: 'Order created successfully'
1179
- else
1180
- flash[:error] = "Payment error: #{response.error_message}"
1181
- render :new
1182
- end
1183
- end
1184
-
1185
- def show
1186
- # Get item status from Zai
1187
- if @order.zai_item_id
1188
- response = ZaiPayment.items.show_status(@order.zai_item_id)
1189
- @payment_status = response.data if response.success?
1190
- end
1191
- end
1192
- end
1193
- ```
1194
-
1195
- ### In a Background Job
1196
-
1197
- ```ruby
1198
- class CheckItemStatusJob < ApplicationJob
1199
- def perform(order_id)
1200
- order = Order.find(order_id)
1201
-
1202
- response = ZaiPayment.items.show_status(order.zai_item_id)
1203
-
1204
- if response.success?
1205
- status = response.data
1206
-
1207
- order.update(
1208
- payment_state: status['payment_state'],
1209
- disbursement_state: status['disbursement_state']
1210
- )
1211
-
1212
- # Send notifications based on state
1213
- if status['payment_state'] == 'completed'
1214
- OrderMailer.payment_completed(order).deliver_later
1215
- end
1216
- end
1217
- end
1218
- end
1219
- ```
1220
-
1221
- ## Testing
1222
-
1223
- The Item resource includes comprehensive test coverage. Run the tests with:
1224
-
1225
- ```bash
1226
- bundle exec rspec spec/zai_payment/resources/item_spec.rb
1227
- ```
1228
-
1229
- ## See Also
1230
-
1231
- - [User Management Guide](users.md) - Managing buyers and sellers
1232
- - [Webhook Documentation](webhooks.md) - Receiving item status updates
1233
- - [Authentication Documentation](authentication.md) - OAuth2 setup
1234
- - [Item Examples](../examples/items.md) - More code examples
1235
-
1236
- ## External Resources
1237
-
1238
- - [Zai Items API Reference](https://developer.hellozai.com/reference/listitems)
1239
- - [Zai Developer Portal](https://developer.hellozai.com/)
1240
- - [Payment Types Documentation](https://developer.hellozai.com/docs/payment-types)
1241
-