zai_payment 2.7.0 → 2.8.0

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.
@@ -0,0 +1,1530 @@
1
+ # Virtual Account Management Examples
2
+
3
+ This document provides practical examples for managing virtual accounts in Zai Payment.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Setup](#setup)
8
+ - [List Virtual Accounts Example](#list-virtual-accounts-example)
9
+ - [Show Virtual Account Example](#show-virtual-account-example)
10
+ - [Create Virtual Account Example](#create-virtual-account-example)
11
+ - [Update AKA Names Example](#update-aka-names-example)
12
+ - [Update Account Name Example](#update-account-name-example)
13
+ - [Update Status Example](#update-status-example)
14
+ - [Common Patterns](#common-patterns)
15
+
16
+ ## Setup
17
+
18
+ ```ruby
19
+ require 'zai_payment'
20
+
21
+ # Configure ZaiPayment
22
+ ZaiPayment.configure do |config|
23
+ config.environment = :prelive # or :production
24
+ config.client_id = ENV['ZAI_CLIENT_ID']
25
+ config.client_secret = ENV['ZAI_CLIENT_SECRET']
26
+ config.scope = ENV['ZAI_SCOPE']
27
+ end
28
+ ```
29
+
30
+ ## List Virtual Accounts Example
31
+
32
+ ### Example 1: List All Virtual Accounts
33
+
34
+ List all virtual accounts for a given wallet account.
35
+
36
+ ```ruby
37
+ # List virtual accounts
38
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
39
+
40
+ response = virtual_accounts.list('ae07556e-22ef-11eb-adc1-0242ac120002')
41
+
42
+ if response.success?
43
+ accounts = response.data
44
+
45
+ puts "Found #{accounts.length} virtual account(s)"
46
+ puts "Total: #{response.meta['total']}"
47
+ puts "─" * 60
48
+
49
+ accounts.each_with_index do |account, index|
50
+ puts "\nVirtual Account ##{index + 1}:"
51
+ puts " ID: #{account['id']}"
52
+ puts " Account Name: #{account['account_name']}"
53
+ puts " BSB: #{account['routing_number']}"
54
+ puts " Account Number: #{account['account_number']}"
55
+ puts " Status: #{account['status']}"
56
+ puts " Currency: #{account['currency']}"
57
+ puts " Created: #{account['created_at']}"
58
+ end
59
+ else
60
+ puts "Failed to retrieve virtual accounts"
61
+ puts "Error: #{response.error}"
62
+ end
63
+ ```
64
+
65
+ ### Example 2: Check if Virtual Accounts Exist
66
+
67
+ Check if a wallet account has any virtual accounts.
68
+
69
+ ```ruby
70
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
71
+
72
+ begin
73
+ response = virtual_accounts.list('ae07556e-22ef-11eb-adc1-0242ac120002')
74
+
75
+ if response.success?
76
+ if response.data.empty?
77
+ puts "No virtual accounts found for this wallet"
78
+ puts "You can create one using the create method"
79
+ else
80
+ puts "Found #{response.data.length} virtual account(s)"
81
+
82
+ # Check if any are active
83
+ active_accounts = response.data.select { |a| a['status'] == 'active' }
84
+ puts "#{active_accounts.length} active account(s)"
85
+
86
+ # Check if any are pending
87
+ pending_accounts = response.data.select { |a| a['status'] == 'pending_activation' }
88
+ puts "#{pending_accounts.length} pending activation"
89
+ end
90
+ end
91
+
92
+ rescue ZaiPayment::Errors::NotFoundError => e
93
+ puts "Wallet account not found: #{e.message}"
94
+ rescue ZaiPayment::Errors::ApiError => e
95
+ puts "API Error: #{e.message}"
96
+ end
97
+ ```
98
+
99
+ ### Example 3: Find Active Virtual Accounts
100
+
101
+ Find and display only active virtual accounts.
102
+
103
+ ```ruby
104
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
105
+
106
+ response = virtual_accounts.list('ae07556e-22ef-11eb-adc1-0242ac120002')
107
+
108
+ if response.success?
109
+ active_accounts = response.data.select { |account| account['status'] == 'active' }
110
+
111
+ if active_accounts.any?
112
+ puts "Active Virtual Accounts:"
113
+ puts "─" * 60
114
+
115
+ active_accounts.each do |account|
116
+ puts "\n#{account['account_name']}"
117
+ puts " BSB: #{account['routing_number']} | Account: #{account['account_number']}"
118
+ puts " ID: #{account['id']}"
119
+
120
+ if account['aka_names'] && account['aka_names'].any?
121
+ puts " AKA Names: #{account['aka_names'].join(', ')}"
122
+ end
123
+ end
124
+ else
125
+ puts "No active virtual accounts found"
126
+ end
127
+ end
128
+ ```
129
+
130
+ ### Example 4: Using Convenience Method
131
+
132
+ Use the convenience method from ZaiPayment module.
133
+
134
+ ```ruby
135
+ # Using convenience accessor
136
+ response = ZaiPayment.virtual_accounts.list('ae07556e-22ef-11eb-adc1-0242ac120002')
137
+
138
+ if response.success?
139
+ puts "Virtual Accounts: #{response.data.length}"
140
+ puts "Total from meta: #{response.meta['total']}"
141
+
142
+ response.data.each do |account|
143
+ puts "- #{account['account_name']} (#{account['status']})"
144
+ end
145
+ end
146
+ ```
147
+
148
+ ### Example 5: Export Virtual Accounts to CSV
149
+
150
+ Export virtual account details to CSV format.
151
+
152
+ ```ruby
153
+ require 'csv'
154
+
155
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
156
+
157
+ response = virtual_accounts.list('ae07556e-22ef-11eb-adc1-0242ac120002')
158
+
159
+ if response.success?
160
+ CSV.open('virtual_accounts.csv', 'w') do |csv|
161
+ # Header
162
+ csv << ['ID', 'Account Name', 'BSB', 'Account Number', 'Status', 'Currency', 'Created At']
163
+
164
+ # Data rows
165
+ response.data.each do |account|
166
+ csv << [
167
+ account['id'],
168
+ account['account_name'],
169
+ account['routing_number'],
170
+ account['account_number'],
171
+ account['status'],
172
+ account['currency'],
173
+ account['created_at']
174
+ ]
175
+ end
176
+ end
177
+
178
+ puts "Exported #{response.data.length} virtual accounts to virtual_accounts.csv"
179
+ else
180
+ puts "Failed to retrieve virtual accounts"
181
+ end
182
+ ```
183
+
184
+ ## Show Virtual Account Example
185
+
186
+ ### Example 1: Get Virtual Account Details
187
+
188
+ Retrieve details of a specific virtual account by its ID.
189
+
190
+ ```ruby
191
+ # Get virtual account details
192
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
193
+
194
+ response = virtual_accounts.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
195
+
196
+ if response.success?
197
+ account = response.data
198
+
199
+ puts "Virtual Account Details:"
200
+ puts "─" * 60
201
+ puts "ID: #{account['id']}"
202
+ puts "Account Name: #{account['account_name']}"
203
+ puts "Status: #{account['status']}"
204
+ puts ""
205
+ puts "Banking Details:"
206
+ puts " BSB (Routing Number): #{account['routing_number']}"
207
+ puts " Account Number: #{account['account_number']}"
208
+ puts " Currency: #{account['currency']}"
209
+ puts ""
210
+ puts "Account Information:"
211
+ puts " Account Type: #{account['account_type']}"
212
+ puts " Full Legal Name: #{account['full_legal_account_name']}"
213
+ puts " Merchant ID: #{account['merchant_id']}"
214
+ puts ""
215
+ puts "Associated IDs:"
216
+ puts " Wallet Account ID: #{account['wallet_account_id']}"
217
+ puts " User External ID: #{account['user_external_id']}"
218
+ puts ""
219
+ puts "AKA Names:"
220
+ account['aka_names'].each do |aka_name|
221
+ puts " - #{aka_name}"
222
+ end
223
+ puts ""
224
+ puts "Timestamps:"
225
+ puts " Created: #{account['created_at']}"
226
+ puts " Updated: #{account['updated_at']}"
227
+ puts "─" * 60
228
+ else
229
+ puts "Failed to retrieve virtual account"
230
+ puts "Error: #{response.error}"
231
+ end
232
+ ```
233
+
234
+ ### Example 2: Check Virtual Account Status
235
+
236
+ Check if a virtual account is active before proceeding with operations.
237
+
238
+ ```ruby
239
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
240
+
241
+ begin
242
+ response = virtual_accounts.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
243
+
244
+ if response.success?
245
+ account = response.data
246
+
247
+ case account['status']
248
+ when 'active'
249
+ puts "✓ Virtual account is active and ready to receive payments"
250
+ puts " BSB: #{account['routing_number']}"
251
+ puts " Account: #{account['account_number']}"
252
+ puts " Name: #{account['account_name']}"
253
+ when 'pending_activation'
254
+ puts "⏳ Virtual account is pending activation"
255
+ puts " Please wait for activation to complete"
256
+ when 'inactive'
257
+ puts "✗ Virtual account is inactive"
258
+ puts " Cannot receive payments at this time"
259
+ else
260
+ puts "⚠ Unknown status: #{account['status']}"
261
+ end
262
+ end
263
+
264
+ rescue ZaiPayment::Errors::NotFoundError => e
265
+ puts "Virtual account not found: #{e.message}"
266
+ rescue ZaiPayment::Errors::ApiError => e
267
+ puts "API Error: #{e.message}"
268
+ end
269
+ ```
270
+
271
+ ### Example 3: Get Payment Instructions
272
+
273
+ Generate payment instructions for customers based on virtual account details.
274
+
275
+ ```ruby
276
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
277
+
278
+ response = virtual_accounts.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
279
+
280
+ if response.success?
281
+ account = response.data
282
+
283
+ if account['status'] == 'active'
284
+ puts "Payment Instructions for #{account['account_name']}"
285
+ puts "=" * 60
286
+ puts ""
287
+ puts "To make a payment, please transfer funds to:"
288
+ puts ""
289
+ puts " Account Name: #{account['account_name']}"
290
+ puts " BSB: #{account['routing_number']}"
291
+ puts " Account Number: #{account['account_number']}"
292
+ puts ""
293
+ puts "Please use one of the following names when making the transfer:"
294
+ account['aka_names'].each_with_index do |aka_name, index|
295
+ puts " #{index + 1}. #{aka_name}"
296
+ end
297
+ puts ""
298
+ puts "Currency: #{account['currency']}"
299
+ puts "=" * 60
300
+ else
301
+ puts "This virtual account is not active yet."
302
+ puts "Status: #{account['status']}"
303
+ end
304
+ end
305
+ ```
306
+
307
+ ### Example 4: Using Convenience Method
308
+
309
+ Use the convenience method from ZaiPayment module.
310
+
311
+ ```ruby
312
+ # Using convenience accessor
313
+ response = ZaiPayment.virtual_accounts.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
314
+
315
+ if response.success?
316
+ account = response.data
317
+ puts "Account: #{account['account_name']}"
318
+ puts "Status: #{account['status']}"
319
+ puts "BSB: #{account['routing_number']} | Account: #{account['account_number']}"
320
+ end
321
+ ```
322
+
323
+ ### Example 5: Validate Virtual Account Before Payment
324
+
325
+ Validate virtual account details before initiating a payment.
326
+
327
+ ```ruby
328
+ def validate_virtual_account(virtual_account_id)
329
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
330
+
331
+ begin
332
+ response = virtual_accounts.show(virtual_account_id)
333
+
334
+ if response.success?
335
+ account = response.data
336
+
337
+ # Validation checks
338
+ errors = []
339
+ errors << "Account is not active" unless account['status'] == 'active'
340
+ errors << "Missing routing number" unless account['routing_number']
341
+ errors << "Missing account number" unless account['account_number']
342
+ errors << "Currency mismatch" unless account['currency'] == 'AUD'
343
+
344
+ if errors.empty?
345
+ {
346
+ valid: true,
347
+ account: account,
348
+ payment_details: {
349
+ bsb: account['routing_number'],
350
+ account_number: account['account_number'],
351
+ account_name: account['account_name']
352
+ }
353
+ }
354
+ else
355
+ {
356
+ valid: false,
357
+ errors: errors,
358
+ account: account
359
+ }
360
+ end
361
+ else
362
+ {
363
+ valid: false,
364
+ errors: ['Failed to retrieve virtual account']
365
+ }
366
+ end
367
+
368
+ rescue ZaiPayment::Errors::NotFoundError
369
+ {
370
+ valid: false,
371
+ errors: ['Virtual account not found']
372
+ }
373
+ rescue ZaiPayment::Errors::ApiError => e
374
+ {
375
+ valid: false,
376
+ errors: ["API Error: #{e.message}"]
377
+ }
378
+ end
379
+ end
380
+
381
+ # Usage
382
+ result = validate_virtual_account('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
383
+
384
+ if result[:valid]
385
+ puts "✓ Virtual account is valid"
386
+ puts "Payment Details:"
387
+ puts " BSB: #{result[:payment_details][:bsb]}"
388
+ puts " Account: #{result[:payment_details][:account_number]}"
389
+ puts " Name: #{result[:payment_details][:account_name]}"
390
+ else
391
+ puts "✗ Virtual account validation failed:"
392
+ result[:errors].each { |error| puts " - #{error}" }
393
+ end
394
+ ```
395
+
396
+ ### Example 6: Compare Multiple Virtual Accounts
397
+
398
+ Retrieve and compare multiple virtual accounts.
399
+
400
+ ```ruby
401
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
402
+
403
+ account_ids = [
404
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
405
+ 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
406
+ ]
407
+
408
+ puts "Virtual Account Comparison"
409
+ puts "=" * 80
410
+
411
+ account_ids.each do |account_id|
412
+ begin
413
+ response = virtual_accounts.show(account_id)
414
+
415
+ if response.success?
416
+ account = response.data
417
+ puts "\n#{account['account_name']}"
418
+ puts " ID: #{account_id[0..7]}..."
419
+ puts " Status: #{account['status']}"
420
+ puts " BSB: #{account['routing_number']} | Account: #{account['account_number']}"
421
+ puts " Created: #{Date.parse(account['created_at']).strftime('%Y-%m-%d')}"
422
+ end
423
+ rescue ZaiPayment::Errors::NotFoundError
424
+ puts "\n#{account_id[0..7]}..."
425
+ puts " Status: Not Found"
426
+ end
427
+ end
428
+
429
+ puts "\n#{'=' * 80}"
430
+ ```
431
+
432
+ ## Create Virtual Account Example
433
+
434
+ ### Example 1: Create a Basic Virtual Account
435
+
436
+ Create a virtual account for a given wallet account with a name.
437
+
438
+ ```ruby
439
+ # Create virtual account
440
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
441
+
442
+ response = virtual_accounts.create(
443
+ 'ae07556e-22ef-11eb-adc1-0242ac120002', # wallet_account_id
444
+ account_name: 'Real Estate Agency X'
445
+ )
446
+
447
+ if response.success?
448
+ virtual_account = response.data
449
+ puts "Virtual Account Created!"
450
+ puts "ID: #{virtual_account['id']}"
451
+ puts "Account Name: #{virtual_account['account_name']}"
452
+ puts "Routing Number: #{virtual_account['routing_number']}"
453
+ puts "Account Number: #{virtual_account['account_number']}"
454
+ puts "Currency: #{virtual_account['currency']}"
455
+ puts "Status: #{virtual_account['status']}"
456
+ puts "Created At: #{virtual_account['created_at']}"
457
+ else
458
+ puts "Failed to create virtual account"
459
+ puts "Error: #{response.error}"
460
+ end
461
+ ```
462
+
463
+ ### Example 2: Create Virtual Account with AKA Names
464
+
465
+ Create a virtual account with alternative names (AKA names) for CoP lookups.
466
+
467
+ ```ruby
468
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
469
+
470
+ response = virtual_accounts.create(
471
+ 'ae07556e-22ef-11eb-adc1-0242ac120002',
472
+ account_name: 'Real Estate Agency X',
473
+ aka_names: ['Realestate agency X', 'RE Agency X', 'Agency X']
474
+ )
475
+
476
+ if response.success?
477
+ virtual_account = response.data
478
+ puts "Virtual Account Created!"
479
+ puts "ID: #{virtual_account['id']}"
480
+ puts "Account Name: #{virtual_account['account_name']}"
481
+ puts "AKA Names: #{virtual_account['aka_names'].join(', ')}"
482
+ puts "Routing Number: #{virtual_account['routing_number']}"
483
+ puts "Account Number: #{virtual_account['account_number']}"
484
+ puts "Merchant ID: #{virtual_account['merchant_id']}"
485
+ else
486
+ puts "Failed to create virtual account"
487
+ puts "Error: #{response.error}"
488
+ end
489
+ ```
490
+
491
+ ### Example 3: Using Convenience Method
492
+
493
+ Use the convenience method from ZaiPayment module.
494
+
495
+ ```ruby
496
+ # Using convenience accessor
497
+ response = ZaiPayment.virtual_accounts.create(
498
+ 'ae07556e-22ef-11eb-adc1-0242ac120002',
499
+ account_name: 'Property Management Co',
500
+ aka_names: ['PropMgmt Co']
501
+ )
502
+
503
+ if response.success?
504
+ puts "Virtual Account ID: #{response.data['id']}"
505
+ puts "Status: #{response.data['status']}"
506
+ end
507
+ ```
508
+
509
+ ### Example 4: Complete Workflow
510
+
511
+ Complete workflow showing user creation, wallet account reference, and virtual account creation.
512
+
513
+ ```ruby
514
+ begin
515
+ # Assume we already have a wallet account ID from previous steps
516
+ wallet_account_id = 'ae07556e-22ef-11eb-adc1-0242ac120002'
517
+
518
+ # Create virtual account
519
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
520
+
521
+ response = virtual_accounts.create(
522
+ wallet_account_id,
523
+ account_name: 'Real Estate Trust Account',
524
+ aka_names: ['RE Trust', 'Trust Account']
525
+ )
526
+
527
+ if response.success?
528
+ virtual_account = response.data
529
+
530
+ # Store important information
531
+ virtual_account_id = virtual_account['id']
532
+ routing_number = virtual_account['routing_number']
533
+ account_number = virtual_account['account_number']
534
+
535
+ puts "✓ Virtual Account Created Successfully!"
536
+ puts "─" * 50
537
+ puts "Virtual Account ID: #{virtual_account_id}"
538
+ puts "Wallet Account ID: #{virtual_account['wallet_account_id']}"
539
+ puts "User External ID: #{virtual_account['user_external_id']}"
540
+ puts ""
541
+ puts "Banking Details:"
542
+ puts " Account Name: #{virtual_account['account_name']}"
543
+ puts " Routing Number: #{routing_number}"
544
+ puts " Account Number: #{account_number}"
545
+ puts " Currency: #{virtual_account['currency']}"
546
+ puts ""
547
+ puts "Additional Information:"
548
+ puts " Status: #{virtual_account['status']}"
549
+ puts " Account Type: #{virtual_account['account_type']}"
550
+ puts " Full Legal Name: #{virtual_account['full_legal_account_name']}"
551
+ puts " AKA Names: #{virtual_account['aka_names'].join(', ')}"
552
+ puts " Merchant ID: #{virtual_account['merchant_id']}"
553
+ puts "─" * 50
554
+
555
+ # Now customers can transfer funds using these details
556
+ puts "\nCustomers can transfer funds to:"
557
+ puts " BSB: #{routing_number}"
558
+ puts " Account: #{account_number}"
559
+ puts " Name: #{virtual_account['account_name']}"
560
+ end
561
+
562
+ rescue ZaiPayment::Errors::ValidationError => e
563
+ puts "Validation Error: #{e.message}"
564
+ puts "Please check your input parameters"
565
+ rescue ZaiPayment::Errors::NotFoundError => e
566
+ puts "Not Found: #{e.message}"
567
+ puts "The wallet account may not exist"
568
+ rescue ZaiPayment::Errors::UnauthorizedError => e
569
+ puts "Unauthorized: #{e.message}"
570
+ puts "Please check your API credentials"
571
+ rescue ZaiPayment::Errors::ApiError => e
572
+ puts "API Error: #{e.message}"
573
+ end
574
+ ```
575
+
576
+ ## Update AKA Names Example
577
+
578
+ ### Example 1: Update AKA Names for a Virtual Account
579
+
580
+ Replace the list of AKA names for a virtual account.
581
+
582
+ ```ruby
583
+ # Update AKA names
584
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
585
+
586
+ response = virtual_accounts.update_aka_names(
587
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
588
+ ['Updated Name 1', 'Updated Name 2', 'Updated Name 3']
589
+ )
590
+
591
+ if response.success?
592
+ account = response.data
593
+ puts "AKA Names Updated Successfully!"
594
+ puts "Virtual Account: #{account['account_name']}"
595
+ puts "New AKA Names:"
596
+ account['aka_names'].each_with_index do |aka_name, index|
597
+ puts " #{index + 1}. #{aka_name}"
598
+ end
599
+ else
600
+ puts "Failed to update AKA names"
601
+ puts "Error: #{response.error}"
602
+ end
603
+ ```
604
+
605
+ ### Example 2: Clear All AKA Names
606
+
607
+ Remove all AKA names from a virtual account by passing an empty array.
608
+
609
+ ```ruby
610
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
611
+
612
+ response = virtual_accounts.update_aka_names(
613
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
614
+ []
615
+ )
616
+
617
+ if response.success?
618
+ puts "All AKA names cleared successfully"
619
+ puts "Current AKA names: #{response.data['aka_names'].inspect}"
620
+ end
621
+ ```
622
+
623
+ ### Example 3: Set Single AKA Name
624
+
625
+ Update to have just one AKA name.
626
+
627
+ ```ruby
628
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
629
+
630
+ response = virtual_accounts.update_aka_names(
631
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
632
+ ['Preferred Name']
633
+ )
634
+
635
+ if response.success?
636
+ account = response.data
637
+ puts "✓ AKA names updated to single name"
638
+ puts " Account: #{account['account_name']}"
639
+ puts " AKA: #{account['aka_names'].first}"
640
+ end
641
+ ```
642
+
643
+ ### Example 4: Using Convenience Method
644
+
645
+ Use the convenience method from ZaiPayment module.
646
+
647
+ ```ruby
648
+ # Using convenience accessor
649
+ response = ZaiPayment.virtual_accounts.update_aka_names(
650
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
651
+ ['New Name 1', 'New Name 2']
652
+ )
653
+
654
+ if response.success?
655
+ puts "Updated AKA names: #{response.data['aka_names'].join(', ')}"
656
+ end
657
+ ```
658
+
659
+ ### Example 5: Update After Checking Current Names
660
+
661
+ Check current AKA names before updating.
662
+
663
+ ```ruby
664
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
665
+ virtual_account_id = '46deb476-c1a6-41eb-8eb7-26a695bbe5bc'
666
+
667
+ begin
668
+ # First, show current virtual account
669
+ show_response = virtual_accounts.show(virtual_account_id)
670
+
671
+ if show_response.success?
672
+ current_account = show_response.data
673
+
674
+ puts "Current AKA names:"
675
+ current_account['aka_names'].each { |name| puts " - #{name}" }
676
+
677
+ # Update with new names
678
+ new_aka_names = [
679
+ 'Real Estate Agency',
680
+ 'RE Agency',
681
+ 'Property Management'
682
+ ]
683
+
684
+ update_response = virtual_accounts.update_aka_names(virtual_account_id, new_aka_names)
685
+
686
+ if update_response.success?
687
+ puts "\n✓ Successfully updated AKA names"
688
+ puts "New AKA names:"
689
+ update_response.data['aka_names'].each { |name| puts " - #{name}" }
690
+ end
691
+ end
692
+
693
+ rescue ZaiPayment::Errors::ValidationError => e
694
+ puts "Validation Error: #{e.message}"
695
+ rescue ZaiPayment::Errors::ApiError => e
696
+ puts "API Error: #{e.message}"
697
+ end
698
+ ```
699
+
700
+ ### Example 6: Bulk Update with Validation
701
+
702
+ Update AKA names with pre-validation and error handling.
703
+
704
+ ```ruby
705
+ def safely_update_aka_names(virtual_account_id, new_aka_names)
706
+ # Pre-validate
707
+ errors = []
708
+ errors << "aka_names must be an array" unless new_aka_names.is_a?(Array)
709
+ errors << "Maximum 3 AKA names allowed" if new_aka_names.length > 3
710
+ errors << "AKA names cannot be empty strings" if new_aka_names.any? { |name| name.to_s.strip.empty? }
711
+
712
+ if errors.any?
713
+ return {
714
+ success: false,
715
+ errors: errors
716
+ }
717
+ end
718
+
719
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
720
+
721
+ begin
722
+ response = virtual_accounts.update_aka_names(virtual_account_id, new_aka_names)
723
+
724
+ {
725
+ success: true,
726
+ account: response.data,
727
+ aka_names: response.data['aka_names']
728
+ }
729
+ rescue ZaiPayment::Errors::ValidationError => e
730
+ {
731
+ success: false,
732
+ errors: [e.message]
733
+ }
734
+ rescue ZaiPayment::Errors::NotFoundError => e
735
+ {
736
+ success: false,
737
+ errors: ['Virtual account not found']
738
+ }
739
+ rescue ZaiPayment::Errors::ApiError => e
740
+ {
741
+ success: false,
742
+ errors: ["API Error: #{e.message}"]
743
+ }
744
+ end
745
+ end
746
+
747
+ # Usage
748
+ result = safely_update_aka_names(
749
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
750
+ ['Agency A', 'Agency B']
751
+ )
752
+
753
+ if result[:success]
754
+ puts "✓ AKA names updated successfully"
755
+ puts "New names: #{result[:aka_names].join(', ')}"
756
+ else
757
+ puts "✗ Update failed:"
758
+ result[:errors].each { |error| puts " - #{error}" }
759
+ end
760
+ ```
761
+
762
+ ## Update Account Name Example
763
+
764
+ ### Example 1: Update Account Name for a Virtual Account
765
+
766
+ Change the name of a virtual account.
767
+
768
+ ```ruby
769
+ # Update account name
770
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
771
+
772
+ response = virtual_accounts.update_account_name(
773
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
774
+ 'New Real Estate Agency Name'
775
+ )
776
+
777
+ if response.success?
778
+ account = response.data
779
+ puts "Account Name Updated Successfully!"
780
+ puts "Virtual Account ID: #{account['id']}"
781
+ puts "New Account Name: #{account['account_name']}"
782
+ puts "Status: #{account['status']}"
783
+ else
784
+ puts "Failed to update account name"
785
+ puts "Error: #{response.error}"
786
+ end
787
+ ```
788
+
789
+ ### Example 2: Update After Business Name Change
790
+
791
+ Update account name after a business rebranding or name change.
792
+
793
+ ```ruby
794
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
795
+
796
+ begin
797
+ # Show current account first
798
+ show_response = virtual_accounts.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
799
+
800
+ if show_response.success?
801
+ old_name = show_response.data['account_name']
802
+ puts "Current account name: #{old_name}"
803
+
804
+ # Update to new name
805
+ new_name = 'Premium Real Estate Partners'
806
+ update_response = virtual_accounts.update_account_name(
807
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
808
+ new_name
809
+ )
810
+
811
+ if update_response.success?
812
+ puts "✓ Successfully updated account name"
813
+ puts " From: #{old_name}"
814
+ puts " To: #{update_response.data['account_name']}"
815
+ end
816
+ end
817
+
818
+ rescue ZaiPayment::Errors::ValidationError => e
819
+ puts "Validation Error: #{e.message}"
820
+ rescue ZaiPayment::Errors::ApiError => e
821
+ puts "API Error: #{e.message}"
822
+ end
823
+ ```
824
+
825
+ ### Example 3: Using Convenience Method
826
+
827
+ Use the convenience method from ZaiPayment module.
828
+
829
+ ```ruby
830
+ # Using convenience accessor
831
+ response = ZaiPayment.virtual_accounts.update_account_name(
832
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
833
+ 'Updated Property Management Co'
834
+ )
835
+
836
+ if response.success?
837
+ puts "Updated account name: #{response.data['account_name']}"
838
+ end
839
+ ```
840
+
841
+ ### Example 4: Update with Maximum Length Name
842
+
843
+ Update with a name at the maximum allowed length (140 characters).
844
+
845
+ ```ruby
846
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
847
+
848
+ # Create a name at exactly 140 characters
849
+ long_name = 'A' * 140
850
+
851
+ response = virtual_accounts.update_account_name(
852
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
853
+ long_name
854
+ )
855
+
856
+ if response.success?
857
+ account = response.data
858
+ puts "✓ Account name updated"
859
+ puts " Length: #{account['account_name'].length} characters"
860
+ puts " Name: #{account['account_name'][0..50]}..." # Show first 50 chars
861
+ end
862
+ ```
863
+
864
+ ### Example 5: Validate Before Updating
865
+
866
+ Pre-validate the account name before making the API call.
867
+
868
+ ```ruby
869
+ def safely_update_account_name(virtual_account_id, new_account_name)
870
+ # Pre-validate
871
+ errors = []
872
+
873
+ if new_account_name.nil? || new_account_name.strip.empty?
874
+ errors << "Account name cannot be blank"
875
+ elsif new_account_name.length > 140
876
+ errors << "Account name must be 140 characters or less (currently #{new_account_name.length})"
877
+ end
878
+
879
+ if errors.any?
880
+ return {
881
+ success: false,
882
+ errors: errors
883
+ }
884
+ end
885
+
886
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
887
+
888
+ begin
889
+ response = virtual_accounts.update_account_name(virtual_account_id, new_account_name)
890
+
891
+ {
892
+ success: true,
893
+ account: response.data,
894
+ account_name: response.data['account_name']
895
+ }
896
+ rescue ZaiPayment::Errors::ValidationError => e
897
+ {
898
+ success: false,
899
+ errors: [e.message]
900
+ }
901
+ rescue ZaiPayment::Errors::NotFoundError => e
902
+ {
903
+ success: false,
904
+ errors: ['Virtual account not found']
905
+ }
906
+ rescue ZaiPayment::Errors::ApiError => e
907
+ {
908
+ success: false,
909
+ errors: ["API Error: #{e.message}"]
910
+ }
911
+ end
912
+ end
913
+
914
+ # Usage
915
+ result = safely_update_account_name(
916
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
917
+ 'New Business Name'
918
+ )
919
+
920
+ if result[:success]
921
+ puts "✓ Account name updated successfully"
922
+ puts "New name: #{result[:account_name]}"
923
+ else
924
+ puts "✗ Update failed:"
925
+ result[:errors].each { |error| puts " - #{error}" }
926
+ end
927
+ ```
928
+
929
+ ### Example 6: Update Multiple Virtual Accounts
930
+
931
+ Update account names for multiple virtual accounts in bulk.
932
+
933
+ ```ruby
934
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
935
+
936
+ updates = [
937
+ { id: '46deb476-c1a6-41eb-8eb7-26a695bbe5bc', name: 'Property A Trust' },
938
+ { id: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', name: 'Property B Trust' }
939
+ ]
940
+
941
+ results = updates.map do |update|
942
+ begin
943
+ response = virtual_accounts.update_account_name(update[:id], update[:name])
944
+
945
+ {
946
+ id: update[:id],
947
+ success: true,
948
+ new_name: response.data['account_name']
949
+ }
950
+ rescue ZaiPayment::Errors::ApiError => e
951
+ {
952
+ id: update[:id],
953
+ success: false,
954
+ error: e.message
955
+ }
956
+ end
957
+ end
958
+
959
+ # Display results
960
+ results.each do |result|
961
+ if result[:success]
962
+ puts "✓ #{result[:id][0..7]}... → #{result[:new_name]}"
963
+ else
964
+ puts "✗ #{result[:id][0..7]}... → #{result[:error]}"
965
+ end
966
+ end
967
+
968
+ successes = results.count { |r| r[:success] }
969
+ puts "\nUpdated #{successes} out of #{results.length} virtual accounts"
970
+ ```
971
+
972
+ ## Update Status Example
973
+
974
+ ### Example 1: Close a Virtual Account
975
+
976
+ Close a virtual account by setting its status to 'closed'. This is an asynchronous operation.
977
+
978
+ ```ruby
979
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
980
+
981
+ begin
982
+ response = virtual_accounts.update_status(
983
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
984
+ 'closed'
985
+ )
986
+
987
+ if response.success?
988
+ puts "Virtual account closure initiated"
989
+ puts "ID: #{response.data['id']}"
990
+ puts "Message: #{response.data['message']}"
991
+ puts "Link: #{response.data['links']['self']}"
992
+ puts "\nNote: The status update is being processed asynchronously."
993
+ puts "Use the show method to check the current status."
994
+ end
995
+
996
+ rescue ZaiPayment::Errors::NotFoundError => e
997
+ puts "Virtual account not found: #{e.message}"
998
+ rescue ZaiPayment::Errors::ValidationError => e
999
+ puts "Validation error: #{e.message}"
1000
+ rescue ZaiPayment::Errors::ApiError => e
1001
+ puts "API Error: #{e.message}"
1002
+ end
1003
+ ```
1004
+
1005
+ ### Example 2: Close and Verify Status
1006
+
1007
+ Close a virtual account and verify the status change.
1008
+
1009
+ ```ruby
1010
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1011
+ virtual_account_id = '46deb476-c1a6-41eb-8eb7-26a695bbe5bc'
1012
+
1013
+ begin
1014
+ # Get current status
1015
+ current_response = virtual_accounts.show(virtual_account_id)
1016
+ current_status = current_response.data['status']
1017
+
1018
+ puts "Current status: #{current_status}"
1019
+
1020
+ if current_status == 'closed'
1021
+ puts "Virtual account is already closed"
1022
+ elsif current_status == 'pending_activation'
1023
+ puts "Virtual account is still pending activation. Cannot close yet."
1024
+ else
1025
+ # Close the account
1026
+ close_response = virtual_accounts.update_status(virtual_account_id, 'closed')
1027
+
1028
+ if close_response.success?
1029
+ puts "✓ Closure request submitted successfully"
1030
+ puts "Message: #{close_response.data['message']}"
1031
+
1032
+ # Wait a moment for processing
1033
+ sleep(2)
1034
+
1035
+ # Check new status
1036
+ updated_response = virtual_accounts.show(virtual_account_id)
1037
+ new_status = updated_response.data['status']
1038
+
1039
+ puts "\nUpdated status: #{new_status}"
1040
+ puts "Status changed: #{current_status} → #{new_status}"
1041
+ end
1042
+ end
1043
+
1044
+ rescue ZaiPayment::Errors::ApiError => e
1045
+ puts "Error: #{e.message}"
1046
+ end
1047
+ ```
1048
+
1049
+ ### Example 3: Close Multiple Virtual Accounts
1050
+
1051
+ Close multiple virtual accounts in batch.
1052
+
1053
+ ```ruby
1054
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1055
+
1056
+ account_ids_to_close = [
1057
+ '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
1058
+ 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
1059
+ 'cccccccc-dddd-eeee-ffff-000000000000'
1060
+ ]
1061
+
1062
+ results = []
1063
+
1064
+ puts "Closing #{account_ids_to_close.length} virtual accounts..."
1065
+ puts "─" * 60
1066
+
1067
+ account_ids_to_close.each_with_index do |account_id, index|
1068
+ begin
1069
+ response = virtual_accounts.update_status(account_id, 'closed')
1070
+
1071
+ if response.success?
1072
+ results << {
1073
+ id: account_id,
1074
+ success: true,
1075
+ message: response.data['message']
1076
+ }
1077
+ puts "✓ Account #{index + 1}: #{account_id[0..7]}... - Closure initiated"
1078
+ end
1079
+
1080
+ rescue ZaiPayment::Errors::NotFoundError => e
1081
+ results << { id: account_id, success: false, error: 'Not found' }
1082
+ puts "✗ Account #{index + 1}: #{account_id[0..7]}... - Not found"
1083
+ rescue ZaiPayment::Errors::ApiError => e
1084
+ results << { id: account_id, success: false, error: e.message }
1085
+ puts "✗ Account #{index + 1}: #{account_id[0..7]}... - #{e.message}"
1086
+ end
1087
+ end
1088
+
1089
+ puts "─" * 60
1090
+ successes = results.count { |r| r[:success] }
1091
+ failures = results.count { |r| !r[:success] }
1092
+
1093
+ puts "\nResults:"
1094
+ puts " Successful closures: #{successes}"
1095
+ puts " Failed closures: #{failures}"
1096
+ ```
1097
+
1098
+ ### Example 4: Safe Close with Confirmation
1099
+
1100
+ Close a virtual account with additional safety checks.
1101
+
1102
+ ```ruby
1103
+ def close_virtual_account_safely(virtual_account_id)
1104
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1105
+
1106
+ begin
1107
+ # First, retrieve the account details
1108
+ account_response = virtual_accounts.show(virtual_account_id)
1109
+ account = account_response.data
1110
+
1111
+ puts "Virtual Account Details:"
1112
+ puts " ID: #{account['id']}"
1113
+ puts " Account Name: #{account['account_name']}"
1114
+ puts " BSB: #{account['routing_number']}"
1115
+ puts " Account Number: #{account['account_number']}"
1116
+ puts " Current Status: #{account['status']}"
1117
+ puts " Created: #{account['created_at']}"
1118
+
1119
+ # Check if already closed
1120
+ if account['status'] == 'closed'
1121
+ puts "\n⚠ Account is already closed."
1122
+ return { success: false, reason: 'already_closed' }
1123
+ end
1124
+
1125
+ # Check if pending activation
1126
+ if account['status'] == 'pending_activation'
1127
+ puts "\n⚠ Account is still pending activation."
1128
+ puts "Consider waiting for activation before closing."
1129
+ return { success: false, reason: 'pending_activation' }
1130
+ end
1131
+
1132
+ # Proceed with closing
1133
+ puts "\nProceeding to close account..."
1134
+ close_response = virtual_accounts.update_status(virtual_account_id, 'closed')
1135
+
1136
+ if close_response.success?
1137
+ puts "✓ Account closure initiated successfully"
1138
+ puts "Message: #{close_response.data['message']}"
1139
+
1140
+ return {
1141
+ success: true,
1142
+ id: close_response.data['id'],
1143
+ message: close_response.data['message']
1144
+ }
1145
+ end
1146
+
1147
+ rescue ZaiPayment::Errors::NotFoundError => e
1148
+ puts "✗ Virtual account not found: #{virtual_account_id}"
1149
+ return { success: false, reason: 'not_found', error: e.message }
1150
+ rescue ZaiPayment::Errors::ValidationError => e
1151
+ puts "✗ Validation error: #{e.message}"
1152
+ return { success: false, reason: 'validation_error', error: e.message }
1153
+ rescue ZaiPayment::Errors::ApiError => e
1154
+ puts "✗ API Error: #{e.message}"
1155
+ return { success: false, reason: 'api_error', error: e.message }
1156
+ end
1157
+ end
1158
+
1159
+ # Usage
1160
+ result = close_virtual_account_safely('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
1161
+ puts "\nFinal result: #{result.inspect}"
1162
+ ```
1163
+
1164
+ ### Example 5: Close with Status Polling
1165
+
1166
+ Close an account and poll for status confirmation.
1167
+
1168
+ ```ruby
1169
+ def close_and_wait_for_confirmation(virtual_account_id, max_attempts = 10, wait_seconds = 3)
1170
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1171
+
1172
+ begin
1173
+ # Initiate closure
1174
+ puts "Initiating closure for virtual account #{virtual_account_id[0..7]}..."
1175
+ close_response = virtual_accounts.update_status(virtual_account_id, 'closed')
1176
+
1177
+ unless close_response.success?
1178
+ puts "✗ Failed to initiate closure"
1179
+ return { success: false, reason: 'closure_failed' }
1180
+ end
1181
+
1182
+ puts "✓ Closure request accepted"
1183
+ puts "Message: #{close_response.data['message']}"
1184
+ puts "\nPolling for status confirmation..."
1185
+
1186
+ # Poll for status
1187
+ max_attempts.times do |attempt|
1188
+ sleep(wait_seconds)
1189
+
1190
+ show_response = virtual_accounts.show(virtual_account_id)
1191
+ current_status = show_response.data['status']
1192
+
1193
+ puts " Attempt #{attempt + 1}/#{max_attempts}: Status = #{current_status}"
1194
+
1195
+ if current_status == 'closed'
1196
+ puts "\n✓ Account successfully closed!"
1197
+ return {
1198
+ success: true,
1199
+ status: current_status,
1200
+ attempts: attempt + 1,
1201
+ elapsed_time: (attempt + 1) * wait_seconds
1202
+ }
1203
+ end
1204
+ end
1205
+
1206
+ puts "\n⚠ Timeout: Status not confirmed as 'closed' after #{max_attempts} attempts"
1207
+ puts "The account may still be processing. Check again later."
1208
+
1209
+ return {
1210
+ success: false,
1211
+ reason: 'timeout',
1212
+ max_attempts: max_attempts,
1213
+ elapsed_time: max_attempts * wait_seconds
1214
+ }
1215
+
1216
+ rescue ZaiPayment::Errors::ApiError => e
1217
+ puts "✗ Error: #{e.message}"
1218
+ return { success: false, reason: 'api_error', error: e.message }
1219
+ end
1220
+ end
1221
+
1222
+ # Usage
1223
+ result = close_and_wait_for_confirmation('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
1224
+ puts "\nResult: #{result.inspect}"
1225
+ ```
1226
+
1227
+ ### Example 6: Validate Status Before Closing
1228
+
1229
+ Ensure only valid status transitions.
1230
+
1231
+ ```ruby
1232
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1233
+ virtual_account_id = '46deb476-c1a6-41eb-8eb7-26a695bbe5bc'
1234
+
1235
+ # Note: Only 'closed' is a valid status value for the update_status method
1236
+ valid_status = 'closed'
1237
+
1238
+ begin
1239
+ # Attempt to use an invalid status (for demonstration)
1240
+ invalid_status = 'active'
1241
+
1242
+ begin
1243
+ virtual_accounts.update_status(virtual_account_id, invalid_status)
1244
+ rescue ZaiPayment::Errors::ValidationError => e
1245
+ puts "Expected validation error for invalid status:"
1246
+ puts " Error: #{e.message}"
1247
+ puts " Only 'closed' is allowed as a status value"
1248
+ end
1249
+
1250
+ # Now use the correct status
1251
+ puts "\nUsing valid status: '#{valid_status}'"
1252
+ response = virtual_accounts.update_status(virtual_account_id, valid_status)
1253
+
1254
+ if response.success?
1255
+ puts "✓ Status update successful"
1256
+ puts "Message: #{response.data['message']}"
1257
+ end
1258
+
1259
+ rescue ZaiPayment::Errors::ApiError => e
1260
+ puts "API Error: #{e.message}"
1261
+ end
1262
+ ```
1263
+
1264
+ ## Common Patterns
1265
+
1266
+ ### Pattern 1: Validate Parameters Before Creating
1267
+
1268
+ ```ruby
1269
+ def create_virtual_account(wallet_account_id, account_name, aka_names = [])
1270
+ # Validate inputs
1271
+ raise ArgumentError, 'wallet_account_id cannot be empty' if wallet_account_id.nil? || wallet_account_id.empty?
1272
+ raise ArgumentError, 'account_name cannot be empty' if account_name.nil? || account_name.empty?
1273
+ raise ArgumentError, 'account_name too long (max 140 chars)' if account_name.length > 140
1274
+ raise ArgumentError, 'too many aka_names (max 3)' if aka_names.length > 3
1275
+
1276
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1277
+
1278
+ params = { account_name: account_name }
1279
+ params[:aka_names] = aka_names unless aka_names.empty?
1280
+
1281
+ response = virtual_accounts.create(wallet_account_id, **params)
1282
+
1283
+ if response.success?
1284
+ response.data
1285
+ else
1286
+ nil
1287
+ end
1288
+ end
1289
+
1290
+ # Usage
1291
+ virtual_account = create_virtual_account(
1292
+ 'ae07556e-22ef-11eb-adc1-0242ac120002',
1293
+ 'My Business Account',
1294
+ ['Business', 'Company Account']
1295
+ )
1296
+
1297
+ puts "Created: #{virtual_account['id']}" if virtual_account
1298
+ ```
1299
+
1300
+ ### Pattern 2: Store Virtual Account Details
1301
+
1302
+ ```ruby
1303
+ class VirtualAccountManager
1304
+ attr_reader :virtual_accounts
1305
+
1306
+ def initialize
1307
+ @virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1308
+ end
1309
+
1310
+ def create_and_store(wallet_account_id, account_name, aka_names = [])
1311
+ response = virtual_accounts.create(
1312
+ wallet_account_id,
1313
+ account_name: account_name,
1314
+ aka_names: aka_names
1315
+ )
1316
+
1317
+ return nil unless response.success?
1318
+
1319
+ virtual_account = response.data
1320
+
1321
+ # Store in your database
1322
+ store_in_database(virtual_account)
1323
+
1324
+ virtual_account
1325
+ end
1326
+
1327
+ private
1328
+
1329
+ def store_in_database(virtual_account)
1330
+ # Example: Store in your application database
1331
+ # VirtualAccountRecord.create!(
1332
+ # external_id: virtual_account['id'],
1333
+ # wallet_account_id: virtual_account['wallet_account_id'],
1334
+ # routing_number: virtual_account['routing_number'],
1335
+ # account_number: virtual_account['account_number'],
1336
+ # account_name: virtual_account['account_name'],
1337
+ # status: virtual_account['status']
1338
+ # )
1339
+ puts "Storing virtual account #{virtual_account['id']} in database..."
1340
+ end
1341
+ end
1342
+
1343
+ # Usage
1344
+ manager = VirtualAccountManager.new
1345
+ virtual_account = manager.create_and_store(
1346
+ 'ae07556e-22ef-11eb-adc1-0242ac120002',
1347
+ 'Client Trust Account'
1348
+ )
1349
+ ```
1350
+
1351
+ ### Pattern 3: Handle Different Response Scenarios
1352
+
1353
+ ```ruby
1354
+ def create_virtual_account_with_handling(wallet_account_id, account_name, aka_names = [])
1355
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1356
+
1357
+ begin
1358
+ response = virtual_accounts.create(
1359
+ wallet_account_id,
1360
+ account_name: account_name,
1361
+ aka_names: aka_names
1362
+ )
1363
+
1364
+ {
1365
+ success: true,
1366
+ virtual_account: response.data,
1367
+ message: 'Virtual account created successfully'
1368
+ }
1369
+ rescue ZaiPayment::Errors::ValidationError => e
1370
+ {
1371
+ success: false,
1372
+ error: 'validation_error',
1373
+ message: e.message
1374
+ }
1375
+ rescue ZaiPayment::Errors::NotFoundError => e
1376
+ {
1377
+ success: false,
1378
+ error: 'not_found',
1379
+ message: 'Wallet account not found'
1380
+ }
1381
+ rescue ZaiPayment::Errors::BadRequestError => e
1382
+ {
1383
+ success: false,
1384
+ error: 'bad_request',
1385
+ message: e.message
1386
+ }
1387
+ rescue ZaiPayment::Errors::ApiError => e
1388
+ {
1389
+ success: false,
1390
+ error: 'api_error',
1391
+ message: e.message
1392
+ }
1393
+ end
1394
+ end
1395
+
1396
+ # Usage
1397
+ result = create_virtual_account_with_handling(
1398
+ 'ae07556e-22ef-11eb-adc1-0242ac120002',
1399
+ 'Test Account'
1400
+ )
1401
+
1402
+ if result[:success]
1403
+ puts "Success! Virtual Account ID: #{result[:virtual_account]['id']}"
1404
+ else
1405
+ puts "Error (#{result[:error]}): #{result[:message]}"
1406
+ end
1407
+ ```
1408
+
1409
+ ### Pattern 4: Batch Virtual Account Creation
1410
+
1411
+ ```ruby
1412
+ def create_multiple_virtual_accounts(wallet_account_id, account_configs)
1413
+ virtual_accounts = ZaiPayment::Resources::VirtualAccount.new
1414
+ results = []
1415
+
1416
+ account_configs.each do |config|
1417
+ begin
1418
+ response = virtual_accounts.create(
1419
+ wallet_account_id,
1420
+ account_name: config[:account_name],
1421
+ aka_names: config[:aka_names] || []
1422
+ )
1423
+
1424
+ if response.success?
1425
+ results << {
1426
+ success: true,
1427
+ name: config[:account_name],
1428
+ virtual_account: response.data
1429
+ }
1430
+ else
1431
+ results << {
1432
+ success: false,
1433
+ name: config[:account_name],
1434
+ error: 'Creation failed'
1435
+ }
1436
+ end
1437
+ rescue ZaiPayment::Errors::ApiError => e
1438
+ results << {
1439
+ success: false,
1440
+ name: config[:account_name],
1441
+ error: e.message
1442
+ }
1443
+ end
1444
+
1445
+ # Be nice to the API - small delay between requests
1446
+ sleep(0.5)
1447
+ end
1448
+
1449
+ results
1450
+ end
1451
+
1452
+ # Usage
1453
+ configs = [
1454
+ { account_name: 'Property 123 Trust', aka_names: ['Prop 123'] },
1455
+ { account_name: 'Property 456 Trust', aka_names: ['Prop 456'] },
1456
+ { account_name: 'Property 789 Trust', aka_names: ['Prop 789'] }
1457
+ ]
1458
+
1459
+ results = create_multiple_virtual_accounts(
1460
+ 'ae07556e-22ef-11eb-adc1-0242ac120002',
1461
+ configs
1462
+ )
1463
+
1464
+ successes = results.count { |r| r[:success] }
1465
+ puts "Created #{successes} out of #{results.length} virtual accounts"
1466
+
1467
+ results.each do |result|
1468
+ if result[:success]
1469
+ puts "✓ #{result[:name]}: #{result[:virtual_account]['id']}"
1470
+ else
1471
+ puts "✗ #{result[:name]}: #{result[:error]}"
1472
+ end
1473
+ end
1474
+ ```
1475
+
1476
+ ## Error Handling
1477
+
1478
+ ### Common Errors and Solutions
1479
+
1480
+ ```ruby
1481
+ begin
1482
+ response = ZaiPayment.virtual_accounts.create(
1483
+ wallet_account_id,
1484
+ account_name: 'Test Account'
1485
+ )
1486
+ rescue ZaiPayment::Errors::ValidationError => e
1487
+ # Handle validation errors
1488
+ # - wallet_account_id is blank
1489
+ # - account_name is blank or too long
1490
+ # - aka_names is not an array or has more than 3 items
1491
+ puts "Validation Error: #{e.message}"
1492
+ rescue ZaiPayment::Errors::NotFoundError => e
1493
+ # Handle not found errors
1494
+ # - wallet account does not exist
1495
+ puts "Not Found: #{e.message}"
1496
+ rescue ZaiPayment::Errors::UnauthorizedError => e
1497
+ # Handle authentication errors
1498
+ # - Invalid credentials
1499
+ # - Expired token
1500
+ puts "Unauthorized: #{e.message}"
1501
+ rescue ZaiPayment::Errors::ForbiddenError => e
1502
+ # Handle authorization errors
1503
+ # - Insufficient permissions
1504
+ puts "Forbidden: #{e.message}"
1505
+ rescue ZaiPayment::Errors::BadRequestError => e
1506
+ # Handle bad request errors
1507
+ # - Invalid request format
1508
+ puts "Bad Request: #{e.message}"
1509
+ rescue ZaiPayment::Errors::TimeoutError => e
1510
+ # Handle timeout errors
1511
+ puts "Timeout: #{e.message}"
1512
+ rescue ZaiPayment::Errors::ApiError => e
1513
+ # Handle general API errors
1514
+ puts "API Error: #{e.message}"
1515
+ end
1516
+ ```
1517
+
1518
+ ## Best Practices
1519
+
1520
+ 1. **Always validate input** before making API calls
1521
+ 2. **Handle errors gracefully** with proper error messages
1522
+ 3. **Store virtual account details** in your database for reference
1523
+ 4. **Use meaningful account names** that help identify the purpose
1524
+ 5. **Add AKA names** when you need multiple name variations for CoP lookups
1525
+ 6. **Monitor account status** after creation (should be `pending_activation`)
1526
+ 7. **Keep routing and account numbers secure** - they're like bank account details
1527
+ 8. **Use environment variables** for sensitive configuration
1528
+ 9. **Test in prelive environment** before using in production
1529
+ 10. **Implement proper logging** for audit trails
1530
+