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.
- checksums.yaml +4 -4
- data/lib/zai_payment/version.rb +1 -1
- metadata +6 -43
- data/.yardopts +0 -3
- data/IMPLEMENTATION_SUMMARY.md +0 -183
- data/RESPONSE_FORMAT_CORRECTION.md +0 -75
- data/Rakefile +0 -12
- data/badges/.gitkeep +0 -2
- data/badges/coverage.json +0 -1
- data/changelog.md +0 -750
- data/code_of_conduct.md +0 -132
- data/contributing.md +0 -383
- data/docs/architecture.md +0 -232
- data/docs/authentication.md +0 -647
- data/docs/bank_accounts.md +0 -496
- data/docs/batch_transactions.md +0 -340
- data/docs/bpay_accounts.md +0 -519
- data/docs/direct_api_usage.md +0 -489
- data/docs/items.md +0 -1241
- data/docs/pay_ids.md +0 -777
- data/docs/readme.md +0 -111
- data/docs/token_auths.md +0 -523
- data/docs/user_id_field.md +0 -284
- data/docs/user_quick_reference.md +0 -230
- data/docs/users.md +0 -750
- data/docs/virtual_accounts.md +0 -916
- data/docs/wallet_accounts.md +0 -493
- data/docs/webhook_security_quickstart.md +0 -136
- data/docs/webhook_signature.md +0 -244
- data/docs/webhooks.md +0 -417
- data/examples/bank_accounts.md +0 -637
- data/examples/batch_transactions.md +0 -450
- data/examples/bpay_accounts.md +0 -642
- data/examples/items.md +0 -2713
- data/examples/pay_ids.md +0 -871
- data/examples/rails_card_payment.md +0 -1252
- data/examples/token_auths.md +0 -687
- data/examples/users.md +0 -765
- data/examples/virtual_accounts.md +0 -1530
- data/examples/wallet_accounts.md +0 -733
- data/examples/webhooks.md +0 -635
- data/readme.md +0 -357
- data/sig/zai_payment.rbs +0 -4
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
|
-
|