zai_payment 2.3.2 → 2.5.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.
data/docs/items.md CHANGED
@@ -313,6 +313,581 @@ if response.success?
313
313
  end
314
314
  ```
315
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
+
316
891
  ## Field Reference
317
892
 
318
893
  ### Item Fields