zai_payment 2.7.0 → 2.8.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/badges/coverage.json +1 -1
- data/changelog.md +94 -0
- data/docs/bank_accounts.md +13 -11
- data/docs/pay_ids.md +777 -0
- data/docs/virtual_accounts.md +916 -0
- data/examples/bank_accounts.md +3 -3
- data/examples/pay_ids.md +871 -0
- data/examples/virtual_accounts.md +1530 -0
- data/lib/zai_payment/resources/pay_id.rb +197 -0
- data/lib/zai_payment/resources/virtual_account.rb +212 -0
- data/lib/zai_payment/response.rb +1 -1
- data/lib/zai_payment/version.rb +1 -1
- data/lib/zai_payment.rb +12 -0
- data/readme.md +25 -1
- metadata +12 -3
data/examples/pay_ids.md
ADDED
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
# PayID Management Examples
|
|
2
|
+
|
|
3
|
+
This document provides practical examples for managing PayIDs in Zai Payment.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Setup](#setup)
|
|
8
|
+
- [Register PayID Example](#register-payid-example)
|
|
9
|
+
- [Common Patterns](#common-patterns)
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
require 'zai_payment'
|
|
15
|
+
|
|
16
|
+
# Configure ZaiPayment
|
|
17
|
+
ZaiPayment.configure do |config|
|
|
18
|
+
config.environment = :prelive # or :production
|
|
19
|
+
config.client_id = ENV['ZAI_CLIENT_ID']
|
|
20
|
+
config.client_secret = ENV['ZAI_CLIENT_SECRET']
|
|
21
|
+
config.scope = ENV['ZAI_SCOPE']
|
|
22
|
+
end
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Register PayID Example
|
|
26
|
+
|
|
27
|
+
### Example 1: Register an EMAIL PayID
|
|
28
|
+
|
|
29
|
+
Register a PayID for a given virtual account.
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
# Register PayID
|
|
33
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
34
|
+
|
|
35
|
+
response = pay_ids.create(
|
|
36
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc', # virtual_account_id
|
|
37
|
+
pay_id: 'jsmith@mydomain.com',
|
|
38
|
+
type: 'EMAIL',
|
|
39
|
+
details: {
|
|
40
|
+
pay_id_name: 'J Smith',
|
|
41
|
+
owner_legal_name: 'Mr John Smith'
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
if response.success?
|
|
46
|
+
pay_id = response.data
|
|
47
|
+
puts "PayID Registered!"
|
|
48
|
+
puts "ID: #{pay_id['id']}"
|
|
49
|
+
puts "PayID: #{pay_id['pay_id']}"
|
|
50
|
+
puts "Type: #{pay_id['type']}"
|
|
51
|
+
puts "Status: #{pay_id['status']}"
|
|
52
|
+
puts "PayID Name: #{pay_id['details']['pay_id_name']}"
|
|
53
|
+
puts "Owner Legal Name: #{pay_id['details']['owner_legal_name']}"
|
|
54
|
+
puts "Created At: #{pay_id['created_at']}"
|
|
55
|
+
else
|
|
56
|
+
puts "Failed to register PayID"
|
|
57
|
+
puts "Error: #{response.error}"
|
|
58
|
+
end
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Example 2: Register PayID with Error Handling
|
|
62
|
+
|
|
63
|
+
Register a PayID with comprehensive error handling.
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
67
|
+
|
|
68
|
+
begin
|
|
69
|
+
response = pay_ids.create(
|
|
70
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
71
|
+
pay_id: 'jsmith@mydomain.com',
|
|
72
|
+
type: 'EMAIL',
|
|
73
|
+
details: {
|
|
74
|
+
pay_id_name: 'J Smith',
|
|
75
|
+
owner_legal_name: 'Mr John Smith'
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
if response.success?
|
|
80
|
+
pay_id = response.data
|
|
81
|
+
|
|
82
|
+
puts "✓ PayID Registered Successfully!"
|
|
83
|
+
puts "─" * 50
|
|
84
|
+
puts "PayID ID: #{pay_id['id']}"
|
|
85
|
+
puts "PayID: #{pay_id['pay_id']}"
|
|
86
|
+
puts "Type: #{pay_id['type']}"
|
|
87
|
+
puts "Status: #{pay_id['status']}"
|
|
88
|
+
puts ""
|
|
89
|
+
puts "Details:"
|
|
90
|
+
puts " PayID Name: #{pay_id['details']['pay_id_name']}"
|
|
91
|
+
puts " Owner Legal Name: #{pay_id['details']['owner_legal_name']}"
|
|
92
|
+
puts ""
|
|
93
|
+
puts "Links:"
|
|
94
|
+
puts " Self: #{pay_id['links']['self']}"
|
|
95
|
+
puts " Virtual Account: #{pay_id['links']['virtual_accounts']}"
|
|
96
|
+
puts "─" * 50
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
rescue ZaiPayment::Errors::ValidationError => e
|
|
100
|
+
puts "Validation Error: #{e.message}"
|
|
101
|
+
puts "Please check your input parameters"
|
|
102
|
+
rescue ZaiPayment::Errors::NotFoundError => e
|
|
103
|
+
puts "Not Found: #{e.message}"
|
|
104
|
+
puts "The virtual account may not exist"
|
|
105
|
+
rescue ZaiPayment::Errors::UnauthorizedError => e
|
|
106
|
+
puts "Unauthorized: #{e.message}"
|
|
107
|
+
puts "Please check your API credentials"
|
|
108
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
109
|
+
puts "API Error: #{e.message}"
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Example 3: Register PayID for Business Email
|
|
114
|
+
|
|
115
|
+
Register a PayID using a business email address.
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
119
|
+
|
|
120
|
+
response = pay_ids.create(
|
|
121
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
122
|
+
pay_id: 'payments@mybusiness.com.au',
|
|
123
|
+
type: 'EMAIL',
|
|
124
|
+
details: {
|
|
125
|
+
pay_id_name: 'MyBusiness Pty Ltd',
|
|
126
|
+
owner_legal_name: 'MyBusiness Pty Ltd'
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
if response.success?
|
|
131
|
+
puts "Business PayID registered successfully"
|
|
132
|
+
puts "PayID: #{response.data['pay_id']}"
|
|
133
|
+
puts "Status: #{response.data['status']}"
|
|
134
|
+
puts "Use this PayID for receiving payments from customers"
|
|
135
|
+
end
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Example 4: Register PayID After Creating Virtual Account
|
|
139
|
+
|
|
140
|
+
Complete workflow showing virtual account creation followed by PayID registration.
|
|
141
|
+
|
|
142
|
+
```ruby
|
|
143
|
+
begin
|
|
144
|
+
# Step 1: Create a Virtual Account
|
|
145
|
+
virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
|
|
146
|
+
wallet_account_id = 'ae07556e-22ef-11eb-adc1-0242ac120002'
|
|
147
|
+
|
|
148
|
+
va_response = virtual_accounts.create(
|
|
149
|
+
wallet_account_id,
|
|
150
|
+
account_name: 'Real Estate Trust Account',
|
|
151
|
+
aka_names: ['RE Trust Account']
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
if va_response.success?
|
|
155
|
+
virtual_account = va_response.data
|
|
156
|
+
virtual_account_id = virtual_account['id']
|
|
157
|
+
|
|
158
|
+
puts "✓ Virtual Account Created"
|
|
159
|
+
puts " ID: #{virtual_account_id}"
|
|
160
|
+
puts " BSB: #{virtual_account['routing_number']}"
|
|
161
|
+
puts " Account: #{virtual_account['account_number']}"
|
|
162
|
+
|
|
163
|
+
# Step 2: Register PayID for the Virtual Account
|
|
164
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
165
|
+
|
|
166
|
+
payid_response = pay_ids.create(
|
|
167
|
+
virtual_account_id,
|
|
168
|
+
pay_id: 'trust@realestate.com.au',
|
|
169
|
+
type: 'EMAIL',
|
|
170
|
+
details: {
|
|
171
|
+
pay_id_name: 'RE Trust',
|
|
172
|
+
owner_legal_name: 'Real Estate Trust Account'
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
if payid_response.success?
|
|
177
|
+
pay_id = payid_response.data
|
|
178
|
+
|
|
179
|
+
puts "\n✓ PayID Registered"
|
|
180
|
+
puts " PayID: #{pay_id['pay_id']}"
|
|
181
|
+
puts " Type: #{pay_id['type']}"
|
|
182
|
+
puts " Status: #{pay_id['status']}"
|
|
183
|
+
puts ""
|
|
184
|
+
puts "Customers can now send payments to:"
|
|
185
|
+
puts " PayID: #{pay_id['pay_id']}"
|
|
186
|
+
puts " OR"
|
|
187
|
+
puts " BSB: #{virtual_account['routing_number']}"
|
|
188
|
+
puts " Account: #{virtual_account['account_number']}"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
193
|
+
puts "Error: #{e.message}"
|
|
194
|
+
end
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Example 5: Validate Before Registering
|
|
198
|
+
|
|
199
|
+
Pre-validate PayID data before making the API call.
|
|
200
|
+
|
|
201
|
+
```ruby
|
|
202
|
+
def validate_pay_id_params(pay_id, type, details)
|
|
203
|
+
errors = []
|
|
204
|
+
|
|
205
|
+
# Validate pay_id
|
|
206
|
+
if pay_id.nil? || pay_id.strip.empty?
|
|
207
|
+
errors << 'PayID is required'
|
|
208
|
+
elsif pay_id.length > 256
|
|
209
|
+
errors << 'PayID must be 256 characters or less'
|
|
210
|
+
elsif !pay_id.include?('@')
|
|
211
|
+
errors << 'Email PayID must contain @ symbol'
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Validate type
|
|
215
|
+
if type.nil? || type.strip.empty?
|
|
216
|
+
errors << 'Type is required'
|
|
217
|
+
elsif type.upcase != 'EMAIL'
|
|
218
|
+
errors << 'Type must be EMAIL'
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Validate details
|
|
222
|
+
if details.nil? || !details.is_a?(Hash)
|
|
223
|
+
errors << 'Details must be a hash'
|
|
224
|
+
else
|
|
225
|
+
if details[:pay_id_name] && details[:pay_id_name].length > 140
|
|
226
|
+
errors << 'PayID name must be 140 characters or less'
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
if details[:owner_legal_name] && details[:owner_legal_name].length > 140
|
|
230
|
+
errors << 'Owner legal name must be 140 characters or less'
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
errors
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Usage
|
|
238
|
+
virtual_account_id = '46deb476-c1a6-41eb-8eb7-26a695bbe5bc'
|
|
239
|
+
pay_id = 'customer@example.com'
|
|
240
|
+
type = 'EMAIL'
|
|
241
|
+
details = {
|
|
242
|
+
pay_id_name: 'Customer Name',
|
|
243
|
+
owner_legal_name: 'Customer Full Legal Name'
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
errors = validate_pay_id_params(pay_id, type, details)
|
|
247
|
+
|
|
248
|
+
if errors.empty?
|
|
249
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
250
|
+
response = pay_ids.create(
|
|
251
|
+
virtual_account_id,
|
|
252
|
+
pay_id: pay_id,
|
|
253
|
+
type: type,
|
|
254
|
+
details: details
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
puts "✓ PayID registered" if response.success?
|
|
258
|
+
else
|
|
259
|
+
puts "✗ Validation errors:"
|
|
260
|
+
errors.each { |error| puts " - #{error}" }
|
|
261
|
+
end
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Example 6: Register Multiple PayIDs
|
|
265
|
+
|
|
266
|
+
Register PayIDs for multiple virtual accounts.
|
|
267
|
+
|
|
268
|
+
```ruby
|
|
269
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
270
|
+
|
|
271
|
+
registrations = [
|
|
272
|
+
{
|
|
273
|
+
virtual_account_id: '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
274
|
+
pay_id: 'property1@realestate.com',
|
|
275
|
+
pay_id_name: 'Property 1 Trust',
|
|
276
|
+
owner_legal_name: 'Property 1 Trust Account'
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
virtual_account_id: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
|
|
280
|
+
pay_id: 'property2@realestate.com',
|
|
281
|
+
pay_id_name: 'Property 2 Trust',
|
|
282
|
+
owner_legal_name: 'Property 2 Trust Account'
|
|
283
|
+
}
|
|
284
|
+
]
|
|
285
|
+
|
|
286
|
+
results = []
|
|
287
|
+
|
|
288
|
+
puts "Registering #{registrations.length} PayIDs..."
|
|
289
|
+
puts "─" * 60
|
|
290
|
+
|
|
291
|
+
registrations.each_with_index do |reg, index|
|
|
292
|
+
begin
|
|
293
|
+
response = pay_ids.create(
|
|
294
|
+
reg[:virtual_account_id],
|
|
295
|
+
pay_id: reg[:pay_id],
|
|
296
|
+
type: 'EMAIL',
|
|
297
|
+
details: {
|
|
298
|
+
pay_id_name: reg[:pay_id_name],
|
|
299
|
+
owner_legal_name: reg[:owner_legal_name]
|
|
300
|
+
}
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
if response.success?
|
|
304
|
+
results << {
|
|
305
|
+
virtual_account_id: reg[:virtual_account_id],
|
|
306
|
+
pay_id: reg[:pay_id],
|
|
307
|
+
success: true,
|
|
308
|
+
status: response.data['status']
|
|
309
|
+
}
|
|
310
|
+
puts "✓ PayID #{index + 1}: #{reg[:pay_id]} - Registered"
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
rescue ZaiPayment::Errors::NotFoundError => e
|
|
314
|
+
results << { virtual_account_id: reg[:virtual_account_id], success: false, error: 'Not found' }
|
|
315
|
+
puts "✗ PayID #{index + 1}: #{reg[:pay_id]} - Virtual account not found"
|
|
316
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
317
|
+
results << { virtual_account_id: reg[:virtual_account_id], success: false, error: e.message }
|
|
318
|
+
puts "✗ PayID #{index + 1}: #{reg[:pay_id]} - #{e.message}"
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# Be nice to the API - small delay between requests
|
|
322
|
+
sleep(0.5) if index < registrations.length - 1
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
puts "─" * 60
|
|
326
|
+
successes = results.count { |r| r[:success] }
|
|
327
|
+
failures = results.count { |r| !r[:success] }
|
|
328
|
+
|
|
329
|
+
puts "\nResults:"
|
|
330
|
+
puts " Successful registrations: #{successes}"
|
|
331
|
+
puts " Failed registrations: #{failures}"
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Show PayID Examples
|
|
335
|
+
|
|
336
|
+
### Example 1: Get PayID Details
|
|
337
|
+
|
|
338
|
+
Retrieve details of a specific PayID by its ID.
|
|
339
|
+
|
|
340
|
+
```ruby
|
|
341
|
+
# Get PayID details
|
|
342
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
343
|
+
|
|
344
|
+
response = pay_ids.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
|
|
345
|
+
|
|
346
|
+
if response.success?
|
|
347
|
+
pay_id = response.data
|
|
348
|
+
|
|
349
|
+
puts "PayID Details:"
|
|
350
|
+
puts "─" * 60
|
|
351
|
+
puts "ID: #{pay_id['id']}"
|
|
352
|
+
puts "PayID: #{pay_id['pay_id']}"
|
|
353
|
+
puts "Type: #{pay_id['type']}"
|
|
354
|
+
puts "Status: #{pay_id['status']}"
|
|
355
|
+
puts ""
|
|
356
|
+
puts "Details:"
|
|
357
|
+
puts " PayID Name: #{pay_id['details']['pay_id_name']}"
|
|
358
|
+
puts " Owner Legal Name: #{pay_id['details']['owner_legal_name']}"
|
|
359
|
+
puts ""
|
|
360
|
+
puts "Timestamps:"
|
|
361
|
+
puts " Created: #{pay_id['created_at']}"
|
|
362
|
+
puts " Updated: #{pay_id['updated_at']}"
|
|
363
|
+
puts "─" * 60
|
|
364
|
+
else
|
|
365
|
+
puts "Failed to retrieve PayID"
|
|
366
|
+
puts "Error: #{response.error}"
|
|
367
|
+
end
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Example 2: Check PayID Status
|
|
371
|
+
|
|
372
|
+
Check if a PayID is active before proceeding with operations.
|
|
373
|
+
|
|
374
|
+
```ruby
|
|
375
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
376
|
+
|
|
377
|
+
begin
|
|
378
|
+
response = pay_ids.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
|
|
379
|
+
|
|
380
|
+
if response.success?
|
|
381
|
+
pay_id = response.data
|
|
382
|
+
|
|
383
|
+
case pay_id['status']
|
|
384
|
+
when 'active'
|
|
385
|
+
puts "✓ PayID is active and ready to receive payments"
|
|
386
|
+
puts " PayID: #{pay_id['pay_id']}"
|
|
387
|
+
puts " Type: #{pay_id['type']}"
|
|
388
|
+
when 'pending_activation'
|
|
389
|
+
puts "⏳ PayID is pending activation"
|
|
390
|
+
puts " Please wait for activation to complete"
|
|
391
|
+
when 'deregistered'
|
|
392
|
+
puts "✗ PayID has been deregistered"
|
|
393
|
+
puts " Cannot receive payments"
|
|
394
|
+
else
|
|
395
|
+
puts "⚠ Unknown status: #{pay_id['status']}"
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
rescue ZaiPayment::Errors::NotFoundError => e
|
|
400
|
+
puts "PayID not found: #{e.message}"
|
|
401
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
402
|
+
puts "API Error: #{e.message}"
|
|
403
|
+
end
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Example 3: Display PayID Information to Users
|
|
407
|
+
|
|
408
|
+
Generate payment instructions for customers based on PayID details.
|
|
409
|
+
|
|
410
|
+
```ruby
|
|
411
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
412
|
+
|
|
413
|
+
response = pay_ids.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
|
|
414
|
+
|
|
415
|
+
if response.success?
|
|
416
|
+
pay_id = response.data
|
|
417
|
+
|
|
418
|
+
if pay_id['status'] == 'active'
|
|
419
|
+
puts "Payment Information"
|
|
420
|
+
puts "=" * 60
|
|
421
|
+
puts ""
|
|
422
|
+
puts "You can send payments to:"
|
|
423
|
+
puts ""
|
|
424
|
+
puts " PayID: #{pay_id['pay_id']}"
|
|
425
|
+
puts " Type: #{pay_id['type']}"
|
|
426
|
+
puts " Name: #{pay_id['details']['pay_id_name']}"
|
|
427
|
+
puts ""
|
|
428
|
+
puts "This PayID is registered to:"
|
|
429
|
+
puts " #{pay_id['details']['owner_legal_name']}"
|
|
430
|
+
puts ""
|
|
431
|
+
puts "=" * 60
|
|
432
|
+
else
|
|
433
|
+
puts "This PayID is not active yet."
|
|
434
|
+
puts "Status: #{pay_id['status']}"
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Example 4: Validate PayID Before Payment
|
|
440
|
+
|
|
441
|
+
Validate PayID details before initiating a payment.
|
|
442
|
+
|
|
443
|
+
```ruby
|
|
444
|
+
def validate_pay_id(pay_id_id)
|
|
445
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
446
|
+
|
|
447
|
+
begin
|
|
448
|
+
response = pay_ids.show(pay_id_id)
|
|
449
|
+
|
|
450
|
+
if response.success?
|
|
451
|
+
pay_id = response.data
|
|
452
|
+
|
|
453
|
+
# Validation checks
|
|
454
|
+
errors = []
|
|
455
|
+
errors << "PayID is not active" unless pay_id['status'] == 'active'
|
|
456
|
+
errors << "Invalid PayID type" unless pay_id['type'] == 'EMAIL'
|
|
457
|
+
|
|
458
|
+
if errors.empty?
|
|
459
|
+
{
|
|
460
|
+
valid: true,
|
|
461
|
+
pay_id: pay_id,
|
|
462
|
+
payment_info: {
|
|
463
|
+
pay_id: pay_id['pay_id'],
|
|
464
|
+
type: pay_id['type'],
|
|
465
|
+
name: pay_id['details']['pay_id_name']
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
else
|
|
469
|
+
{
|
|
470
|
+
valid: false,
|
|
471
|
+
errors: errors,
|
|
472
|
+
pay_id: pay_id
|
|
473
|
+
}
|
|
474
|
+
end
|
|
475
|
+
else
|
|
476
|
+
{
|
|
477
|
+
valid: false,
|
|
478
|
+
errors: ['Failed to retrieve PayID']
|
|
479
|
+
}
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
rescue ZaiPayment::Errors::NotFoundError
|
|
483
|
+
{
|
|
484
|
+
valid: false,
|
|
485
|
+
errors: ['PayID not found']
|
|
486
|
+
}
|
|
487
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
488
|
+
{
|
|
489
|
+
valid: false,
|
|
490
|
+
errors: ["API Error: #{e.message}"]
|
|
491
|
+
}
|
|
492
|
+
end
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
# Usage
|
|
496
|
+
result = validate_pay_id('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
|
|
497
|
+
|
|
498
|
+
if result[:valid]
|
|
499
|
+
puts "✓ PayID is valid"
|
|
500
|
+
puts "Payment Info:"
|
|
501
|
+
puts " PayID: #{result[:payment_info][:pay_id]}"
|
|
502
|
+
puts " Type: #{result[:payment_info][:type]}"
|
|
503
|
+
puts " Name: #{result[:payment_info][:name]}"
|
|
504
|
+
else
|
|
505
|
+
puts "✗ PayID validation failed:"
|
|
506
|
+
result[:errors].each { |error| puts " - #{error}" }
|
|
507
|
+
end
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Example 5: Compare Multiple PayIDs
|
|
511
|
+
|
|
512
|
+
Retrieve and compare multiple PayIDs.
|
|
513
|
+
|
|
514
|
+
```ruby
|
|
515
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
516
|
+
|
|
517
|
+
pay_id_ids = [
|
|
518
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
519
|
+
'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
|
|
520
|
+
]
|
|
521
|
+
|
|
522
|
+
puts "PayID Comparison"
|
|
523
|
+
puts "=" * 80
|
|
524
|
+
|
|
525
|
+
pay_id_ids.each do |pay_id_id|
|
|
526
|
+
begin
|
|
527
|
+
response = pay_ids.show(pay_id_id)
|
|
528
|
+
|
|
529
|
+
if response.success?
|
|
530
|
+
pay_id = response.data
|
|
531
|
+
puts "\n#{pay_id['pay_id']}"
|
|
532
|
+
puts " ID: #{pay_id_id[0..7]}..."
|
|
533
|
+
puts " Status: #{pay_id['status']}"
|
|
534
|
+
puts " Type: #{pay_id['type']}"
|
|
535
|
+
puts " Created: #{Date.parse(pay_id['created_at']).strftime('%Y-%m-%d')}"
|
|
536
|
+
end
|
|
537
|
+
rescue ZaiPayment::Errors::NotFoundError
|
|
538
|
+
puts "\n#{pay_id_id[0..7]}..."
|
|
539
|
+
puts " Status: Not Found"
|
|
540
|
+
end
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
puts "\n#{'=' * 80}"
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## Update PayID Status Examples
|
|
547
|
+
|
|
548
|
+
### Example 1: Deregister a PayID
|
|
549
|
+
|
|
550
|
+
Deregister a PayID by setting its status to 'deregistered'.
|
|
551
|
+
|
|
552
|
+
```ruby
|
|
553
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
554
|
+
|
|
555
|
+
begin
|
|
556
|
+
response = pay_ids.update_status(
|
|
557
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
558
|
+
'deregistered'
|
|
559
|
+
)
|
|
560
|
+
|
|
561
|
+
if response.success?
|
|
562
|
+
puts "PayID deregistration initiated"
|
|
563
|
+
puts "ID: #{response.data['id']}"
|
|
564
|
+
puts "Message: #{response.data['message']}"
|
|
565
|
+
puts "\nNote: The status update is being processed asynchronously."
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
rescue ZaiPayment::Errors::NotFoundError => e
|
|
569
|
+
puts "PayID not found: #{e.message}"
|
|
570
|
+
rescue ZaiPayment::Errors::ValidationError => e
|
|
571
|
+
puts "Validation error: #{e.message}"
|
|
572
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
573
|
+
puts "API Error: #{e.message}"
|
|
574
|
+
end
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Example 2: Deregister Multiple PayIDs
|
|
578
|
+
|
|
579
|
+
Deregister multiple PayIDs in batch.
|
|
580
|
+
|
|
581
|
+
```ruby
|
|
582
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
583
|
+
|
|
584
|
+
pay_id_ids = [
|
|
585
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
586
|
+
'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
|
|
587
|
+
]
|
|
588
|
+
|
|
589
|
+
results = []
|
|
590
|
+
|
|
591
|
+
pay_id_ids.each_with_index do |pay_id_id, index|
|
|
592
|
+
begin
|
|
593
|
+
response = pay_ids.update_status(pay_id_id, 'deregistered')
|
|
594
|
+
|
|
595
|
+
if response.success?
|
|
596
|
+
results << { id: pay_id_id, success: true }
|
|
597
|
+
puts "✓ PayID #{index + 1}: Deregistered"
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
601
|
+
results << { id: pay_id_id, success: false, error: e.message }
|
|
602
|
+
puts "✗ PayID #{index + 1}: #{e.message}"
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
puts "\nDeregistered #{results.count { |r| r[:success] }} out of #{pay_id_ids.length} PayIDs"
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
## Common Patterns
|
|
610
|
+
|
|
611
|
+
### Pattern 1: Safe PayID Registration with Retry
|
|
612
|
+
|
|
613
|
+
```ruby
|
|
614
|
+
def register_pay_id_safely(virtual_account_id, pay_id, details, max_retries = 3)
|
|
615
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
616
|
+
retries = 0
|
|
617
|
+
|
|
618
|
+
begin
|
|
619
|
+
response = pay_ids.create(
|
|
620
|
+
virtual_account_id,
|
|
621
|
+
pay_id: pay_id,
|
|
622
|
+
type: 'EMAIL',
|
|
623
|
+
details: details
|
|
624
|
+
)
|
|
625
|
+
|
|
626
|
+
{
|
|
627
|
+
success: true,
|
|
628
|
+
pay_id: response.data,
|
|
629
|
+
message: 'PayID registered successfully'
|
|
630
|
+
}
|
|
631
|
+
rescue ZaiPayment::Errors::ValidationError => e
|
|
632
|
+
{
|
|
633
|
+
success: false,
|
|
634
|
+
error: 'validation_error',
|
|
635
|
+
message: e.message
|
|
636
|
+
}
|
|
637
|
+
rescue ZaiPayment::Errors::NotFoundError => e
|
|
638
|
+
{
|
|
639
|
+
success: false,
|
|
640
|
+
error: 'not_found',
|
|
641
|
+
message: 'Virtual account not found'
|
|
642
|
+
}
|
|
643
|
+
rescue ZaiPayment::Errors::TimeoutError => e
|
|
644
|
+
retries += 1
|
|
645
|
+
if retries < max_retries
|
|
646
|
+
sleep(2**retries) # Exponential backoff
|
|
647
|
+
retry
|
|
648
|
+
else
|
|
649
|
+
{
|
|
650
|
+
success: false,
|
|
651
|
+
error: 'timeout',
|
|
652
|
+
message: 'Request timed out after retries'
|
|
653
|
+
}
|
|
654
|
+
end
|
|
655
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
656
|
+
{
|
|
657
|
+
success: false,
|
|
658
|
+
error: 'api_error',
|
|
659
|
+
message: e.message
|
|
660
|
+
}
|
|
661
|
+
end
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
# Usage
|
|
665
|
+
result = register_pay_id_safely(
|
|
666
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
667
|
+
'customer@example.com',
|
|
668
|
+
{
|
|
669
|
+
pay_id_name: 'Customer Name',
|
|
670
|
+
owner_legal_name: 'Customer Full Name'
|
|
671
|
+
}
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
if result[:success]
|
|
675
|
+
puts "✓ Success! PayID: #{result[:pay_id]['pay_id']}"
|
|
676
|
+
else
|
|
677
|
+
puts "✗ Failed (#{result[:error]}): #{result[:message]}"
|
|
678
|
+
end
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
### Pattern 2: Store PayID Details in Database
|
|
682
|
+
|
|
683
|
+
```ruby
|
|
684
|
+
class PayIdManager
|
|
685
|
+
attr_reader :pay_ids
|
|
686
|
+
|
|
687
|
+
def initialize
|
|
688
|
+
@pay_ids = ZaiPayment::Resources::PayId.new
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
def register_and_store(virtual_account_id, pay_id_email, pay_id_name, owner_legal_name)
|
|
692
|
+
response = pay_ids.create(
|
|
693
|
+
virtual_account_id,
|
|
694
|
+
pay_id: pay_id_email,
|
|
695
|
+
type: 'EMAIL',
|
|
696
|
+
details: {
|
|
697
|
+
pay_id_name: pay_id_name,
|
|
698
|
+
owner_legal_name: owner_legal_name
|
|
699
|
+
}
|
|
700
|
+
)
|
|
701
|
+
|
|
702
|
+
return nil unless response.success?
|
|
703
|
+
|
|
704
|
+
pay_id = response.data
|
|
705
|
+
|
|
706
|
+
# Store in your database
|
|
707
|
+
store_in_database(pay_id)
|
|
708
|
+
|
|
709
|
+
pay_id
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
private
|
|
713
|
+
|
|
714
|
+
def store_in_database(pay_id)
|
|
715
|
+
# Example: Store in your application database
|
|
716
|
+
# PayIdRecord.create!(
|
|
717
|
+
# external_id: pay_id['id'],
|
|
718
|
+
# virtual_account_id: pay_id['links']['virtual_accounts'].split('/').last,
|
|
719
|
+
# pay_id: pay_id['pay_id'],
|
|
720
|
+
# pay_id_type: pay_id['type'],
|
|
721
|
+
# pay_id_name: pay_id['details']['pay_id_name'],
|
|
722
|
+
# owner_legal_name: pay_id['details']['owner_legal_name'],
|
|
723
|
+
# status: pay_id['status']
|
|
724
|
+
# )
|
|
725
|
+
puts "Storing PayID #{pay_id['id']} in database..."
|
|
726
|
+
end
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
# Usage
|
|
730
|
+
manager = PayIdManager.new
|
|
731
|
+
pay_id = manager.register_and_store(
|
|
732
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
733
|
+
'customer@example.com',
|
|
734
|
+
'Customer Name',
|
|
735
|
+
'Customer Full Legal Name'
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
puts "Registered and stored: #{pay_id['pay_id']}" if pay_id
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
### Pattern 3: Handle Different Response Scenarios
|
|
742
|
+
|
|
743
|
+
```ruby
|
|
744
|
+
def register_pay_id_with_handling(virtual_account_id, pay_id, details)
|
|
745
|
+
pay_ids = ZaiPayment::Resources::PayId.new
|
|
746
|
+
|
|
747
|
+
begin
|
|
748
|
+
response = pay_ids.create(
|
|
749
|
+
virtual_account_id,
|
|
750
|
+
pay_id: pay_id,
|
|
751
|
+
type: 'EMAIL',
|
|
752
|
+
details: details
|
|
753
|
+
)
|
|
754
|
+
|
|
755
|
+
{
|
|
756
|
+
success: true,
|
|
757
|
+
pay_id: response.data,
|
|
758
|
+
message: 'PayID registered successfully'
|
|
759
|
+
}
|
|
760
|
+
rescue ZaiPayment::Errors::ValidationError => e
|
|
761
|
+
{
|
|
762
|
+
success: false,
|
|
763
|
+
error: 'validation_error',
|
|
764
|
+
message: e.message,
|
|
765
|
+
user_message: 'Please check the PayID and details provided'
|
|
766
|
+
}
|
|
767
|
+
rescue ZaiPayment::Errors::NotFoundError => e
|
|
768
|
+
{
|
|
769
|
+
success: false,
|
|
770
|
+
error: 'not_found',
|
|
771
|
+
message: 'Virtual account not found',
|
|
772
|
+
user_message: 'The virtual account does not exist'
|
|
773
|
+
}
|
|
774
|
+
rescue ZaiPayment::Errors::BadRequestError => e
|
|
775
|
+
{
|
|
776
|
+
success: false,
|
|
777
|
+
error: 'bad_request',
|
|
778
|
+
message: e.message,
|
|
779
|
+
user_message: 'Invalid request. Please check your data'
|
|
780
|
+
}
|
|
781
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
782
|
+
{
|
|
783
|
+
success: false,
|
|
784
|
+
error: 'api_error',
|
|
785
|
+
message: e.message,
|
|
786
|
+
user_message: 'An error occurred. Please try again later'
|
|
787
|
+
}
|
|
788
|
+
end
|
|
789
|
+
end
|
|
790
|
+
|
|
791
|
+
# Usage
|
|
792
|
+
result = register_pay_id_with_handling(
|
|
793
|
+
'46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
794
|
+
'test@example.com',
|
|
795
|
+
{
|
|
796
|
+
pay_id_name: 'Test User',
|
|
797
|
+
owner_legal_name: 'Test User Full Name'
|
|
798
|
+
}
|
|
799
|
+
)
|
|
800
|
+
|
|
801
|
+
if result[:success]
|
|
802
|
+
puts "Success! PayID: #{result[:pay_id]['pay_id']}"
|
|
803
|
+
puts "Status: #{result[:pay_id]['status']}"
|
|
804
|
+
else
|
|
805
|
+
puts "Error: #{result[:user_message]}"
|
|
806
|
+
puts "Details: #{result[:message]}"
|
|
807
|
+
end
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
## Error Handling
|
|
811
|
+
|
|
812
|
+
### Common Errors and Solutions
|
|
813
|
+
|
|
814
|
+
```ruby
|
|
815
|
+
begin
|
|
816
|
+
response = ZaiPayment::Resources::PayId.new.create(
|
|
817
|
+
virtual_account_id,
|
|
818
|
+
pay_id: 'user@example.com',
|
|
819
|
+
type: 'EMAIL',
|
|
820
|
+
details: {
|
|
821
|
+
pay_id_name: 'User Name',
|
|
822
|
+
owner_legal_name: 'User Full Name'
|
|
823
|
+
}
|
|
824
|
+
)
|
|
825
|
+
rescue ZaiPayment::Errors::ValidationError => e
|
|
826
|
+
# Handle validation errors
|
|
827
|
+
# - virtual_account_id is blank
|
|
828
|
+
# - pay_id is blank or too long
|
|
829
|
+
# - type is invalid
|
|
830
|
+
# - details is missing or invalid
|
|
831
|
+
puts "Validation Error: #{e.message}"
|
|
832
|
+
rescue ZaiPayment::Errors::NotFoundError => e
|
|
833
|
+
# Handle not found errors
|
|
834
|
+
# - virtual account does not exist
|
|
835
|
+
puts "Not Found: #{e.message}"
|
|
836
|
+
rescue ZaiPayment::Errors::UnauthorizedError => e
|
|
837
|
+
# Handle authentication errors
|
|
838
|
+
# - Invalid credentials
|
|
839
|
+
# - Expired token
|
|
840
|
+
puts "Unauthorized: #{e.message}"
|
|
841
|
+
rescue ZaiPayment::Errors::ForbiddenError => e
|
|
842
|
+
# Handle authorization errors
|
|
843
|
+
# - Insufficient permissions
|
|
844
|
+
puts "Forbidden: #{e.message}"
|
|
845
|
+
rescue ZaiPayment::Errors::BadRequestError => e
|
|
846
|
+
# Handle bad request errors
|
|
847
|
+
# - Invalid request format
|
|
848
|
+
# - PayID already registered
|
|
849
|
+
puts "Bad Request: #{e.message}"
|
|
850
|
+
rescue ZaiPayment::Errors::TimeoutError => e
|
|
851
|
+
# Handle timeout errors
|
|
852
|
+
puts "Timeout: #{e.message}"
|
|
853
|
+
rescue ZaiPayment::Errors::ApiError => e
|
|
854
|
+
# Handle general API errors
|
|
855
|
+
puts "API Error: #{e.message}"
|
|
856
|
+
end
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
## Best Practices
|
|
860
|
+
|
|
861
|
+
1. **Always validate input** before making API calls
|
|
862
|
+
2. **Handle errors gracefully** with proper error messages
|
|
863
|
+
3. **Store PayID details** in your database for reference
|
|
864
|
+
4. **Use meaningful names** in pay_id_name and owner_legal_name
|
|
865
|
+
5. **Monitor PayID status** after registration (should be `pending_activation`)
|
|
866
|
+
6. **Keep PayID secure** - treat like sensitive payment information
|
|
867
|
+
7. **Use environment variables** for sensitive configuration
|
|
868
|
+
8. **Test in prelive environment** before using in production
|
|
869
|
+
9. **Implement proper logging** for audit trails
|
|
870
|
+
10. **Verify virtual account exists** before registering PayID
|
|
871
|
+
|