zai_payment 2.3.2 → 2.4.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.
- checksums.yaml +4 -4
- data/badges/coverage.json +1 -1
- data/changelog.md +32 -0
- data/docs/items.md +575 -0
- data/examples/items.md +2115 -0
- data/examples/rails_card_payment.md +550 -14
- data/lib/zai_payment/resources/item.rb +257 -0
- data/lib/zai_payment/version.rb +1 -1
- metadata +1 -2
- data/token_auth_implementation_summary.md +0 -249
|
@@ -25,6 +25,22 @@ module ZaiPayment
|
|
|
25
25
|
tax_invoice: :tax_invoice
|
|
26
26
|
}.freeze
|
|
27
27
|
|
|
28
|
+
ITEM_PAYMENT_ATTRIBUTES = {
|
|
29
|
+
account_id: :account_id,
|
|
30
|
+
device_id: :device_id,
|
|
31
|
+
ip_address: :ip_address,
|
|
32
|
+
cvv: :cvv,
|
|
33
|
+
merchant_phone: :merchant_phone
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
ITEM_ASYNC_PAYMENT_ATTRIBUTES = {
|
|
37
|
+
account_id: :account_id,
|
|
38
|
+
request_three_d_secure: :request_three_d_secure
|
|
39
|
+
}.freeze
|
|
40
|
+
|
|
41
|
+
# Valid values for request_three_d_secure parameter
|
|
42
|
+
REQUEST_THREE_D_SECURE_VALUES = %w[automatic challenge any].freeze
|
|
43
|
+
|
|
28
44
|
def initialize(client: nil)
|
|
29
45
|
@client = client || Client.new
|
|
30
46
|
end
|
|
@@ -299,6 +315,197 @@ module ZaiPayment
|
|
|
299
315
|
client.get("/items/#{item_id}/status")
|
|
300
316
|
end
|
|
301
317
|
|
|
318
|
+
# Make a payment
|
|
319
|
+
#
|
|
320
|
+
# @param item_id [String] the item ID
|
|
321
|
+
# @option attributes [String] :account_id Required account ID
|
|
322
|
+
# @option attributes [String] :device_id Optional device ID
|
|
323
|
+
# @option attributes [String] :ip_address Optional IP address
|
|
324
|
+
# @option attributes [String] :cvv Optional CVV
|
|
325
|
+
# @option attributes [String] :merchant_phone Optional merchant phone number
|
|
326
|
+
# @return [Response] the API response containing payment details
|
|
327
|
+
#
|
|
328
|
+
# @example Make a payment with required parameters
|
|
329
|
+
# items = ZaiPayment::Resources::Item.new
|
|
330
|
+
# response = items.make_payment("item_id", account_id: "account_id")
|
|
331
|
+
# response.data # => {"items" => {"id" => "...", "amount" => "...", ...}}
|
|
332
|
+
#
|
|
333
|
+
# @example Make a payment with optional parameters
|
|
334
|
+
# response = items.make_payment(
|
|
335
|
+
# "item_id",
|
|
336
|
+
# account_id: "account_id",
|
|
337
|
+
# device_id: "device_789",
|
|
338
|
+
# ip_address: "192.168.1.1",
|
|
339
|
+
# cvv: "123",
|
|
340
|
+
# merchant_phone: "+1234567890"
|
|
341
|
+
# )
|
|
342
|
+
#
|
|
343
|
+
# @see https://developer.hellozai.com/reference/makepayment
|
|
344
|
+
def make_payment(item_id, **attributes)
|
|
345
|
+
validate_id!(item_id, 'item_id')
|
|
346
|
+
|
|
347
|
+
body = build_item_payment_body(attributes)
|
|
348
|
+
|
|
349
|
+
client.patch("/items/#{item_id}/make_payment", body: body)
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
# Cancel an item
|
|
353
|
+
|
|
354
|
+
# @param item_id [String] the item ID
|
|
355
|
+
# @return [Response] the API response containing cancellation details
|
|
356
|
+
#
|
|
357
|
+
# @example Cancel a payment
|
|
358
|
+
# items = ZaiPayment::Resources::Item.new
|
|
359
|
+
# response = items.cancel("item_id")
|
|
360
|
+
# response.data # => {"items" => {"id" => "...", "state" => "...", ...}}
|
|
361
|
+
#
|
|
362
|
+
# @see https://developer.hellozai.com/reference/cancelitem
|
|
363
|
+
def cancel(item_id)
|
|
364
|
+
validate_id!(item_id, 'item_id')
|
|
365
|
+
client.patch("/items/#{item_id}/cancel")
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# Refund an item
|
|
369
|
+
#
|
|
370
|
+
# @param item_id [String] the item ID
|
|
371
|
+
# @option attributes [String] :refund_amount Optional refund amount
|
|
372
|
+
# @option attributes [String] :refund_message Optional refund message
|
|
373
|
+
# @option attributes [String] :account_id Optional account ID
|
|
374
|
+
# @return [Response] the API response containing refund details
|
|
375
|
+
#
|
|
376
|
+
# @example Refund an item
|
|
377
|
+
# items = ZaiPayment::Resources::Item.new
|
|
378
|
+
# response = items.refund("item_id")
|
|
379
|
+
# response.data # => {"items" => {"id" => "...", "state" => "...", ...}}
|
|
380
|
+
#
|
|
381
|
+
# @example Refund an item with optional parameters
|
|
382
|
+
# response = items.refund(
|
|
383
|
+
# "item_id",
|
|
384
|
+
# refund_amount: 10000,
|
|
385
|
+
# refund_message: "Refund for product XYZ",
|
|
386
|
+
# account_id: "account_789"
|
|
387
|
+
# )
|
|
388
|
+
#
|
|
389
|
+
# @see https://developer.hellozai.com/reference/refund
|
|
390
|
+
def refund(item_id, refund_amount: nil, refund_message: nil, account_id: nil)
|
|
391
|
+
validate_id!(item_id, 'item_id')
|
|
392
|
+
|
|
393
|
+
body = build_refund_body(
|
|
394
|
+
refund_amount: refund_amount,
|
|
395
|
+
refund_message: refund_message,
|
|
396
|
+
account_id: account_id
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
client.patch("/items/#{item_id}/refund", body: body)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
# Authorize Payment
|
|
403
|
+
#
|
|
404
|
+
# @param item_id [String] the item ID
|
|
405
|
+
# @option attributes [String] :account_id Required account ID
|
|
406
|
+
# @option attributes [String] :cvv Optional CVV
|
|
407
|
+
# @option attributes [String] :merchant_phone Optional merchant phone number
|
|
408
|
+
# @return [Response] the API response containing authorization details
|
|
409
|
+
#
|
|
410
|
+
# @example Authorize a payment
|
|
411
|
+
# items = ZaiPayment::Resources::Item.new
|
|
412
|
+
# response = items.authorize_payment("item_id", account_id: "account_id")
|
|
413
|
+
# response.data # => {"items" => {"id" => "...", "state" => "...", ...}}
|
|
414
|
+
#
|
|
415
|
+
# @example Authorize a payment with optional parameters
|
|
416
|
+
# response = items.authorize_payment(
|
|
417
|
+
# "item_id",
|
|
418
|
+
# account_id: "account_id",
|
|
419
|
+
# cvv: "123",
|
|
420
|
+
# merchant_phone: "+1234567890"
|
|
421
|
+
# )
|
|
422
|
+
#
|
|
423
|
+
# @see https://developer.hellozai.com/reference/authorizepayment
|
|
424
|
+
def authorize_payment(item_id, **attributes)
|
|
425
|
+
validate_id!(item_id, 'item_id')
|
|
426
|
+
|
|
427
|
+
client.patch("/items/#{item_id}/authorize_payment", body: build_item_payment_body(attributes))
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
# Capture Payment
|
|
431
|
+
#
|
|
432
|
+
# @param item_id [String] the item ID
|
|
433
|
+
# @option attributes [String] :amount Optional amount to capture
|
|
434
|
+
# @return [Response] the API response containing capture details
|
|
435
|
+
#
|
|
436
|
+
# @example Capture a payment
|
|
437
|
+
# items = ZaiPayment::Resources::Item.new
|
|
438
|
+
# response = items.capture_payment("item_id", amount: 10000)
|
|
439
|
+
# response.data # => {"items" => {"id" => "...", "state" => "...", ...}}
|
|
440
|
+
#
|
|
441
|
+
# @example Capture a payment with optional parameters
|
|
442
|
+
# response = items.capture_payment(
|
|
443
|
+
# "item_id",
|
|
444
|
+
# amount: 10000
|
|
445
|
+
# )
|
|
446
|
+
#
|
|
447
|
+
# @see https://developer.hellozai.com/reference/capturepayment
|
|
448
|
+
def capture_payment(item_id, **attributes)
|
|
449
|
+
validate_id!(item_id, 'item_id')
|
|
450
|
+
|
|
451
|
+
body = {}
|
|
452
|
+
body[:amount] = attributes[:amount] if attributes[:amount]
|
|
453
|
+
|
|
454
|
+
client.patch("/items/#{item_id}/capture_payment", body: body)
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
# Void Payment
|
|
458
|
+
#
|
|
459
|
+
# @param item_id [String] the item ID
|
|
460
|
+
# @return [Response] the API response containing void details
|
|
461
|
+
#
|
|
462
|
+
# @example Void a payment
|
|
463
|
+
# items = ZaiPayment::Resources::Item.new
|
|
464
|
+
# response = items.void_payment("item_id")
|
|
465
|
+
# response.data # => {"items" => {"id" => "...", "state" => "...", ...}}
|
|
466
|
+
#
|
|
467
|
+
# @see https://developer.hellozai.com/reference/voidpayment
|
|
468
|
+
def void_payment(item_id)
|
|
469
|
+
validate_id!(item_id, 'item_id')
|
|
470
|
+
client.patch("/items/#{item_id}/void_payment")
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
# Make an async Payment
|
|
474
|
+
#
|
|
475
|
+
# Initiate a card payment with 3D Secure 2.0 authentication support. This endpoint
|
|
476
|
+
# initiates the payment process and returns a payment_token required for 3DS2
|
|
477
|
+
# component initialisation.
|
|
478
|
+
#
|
|
479
|
+
# @param item_id [String] the item ID
|
|
480
|
+
# @param account_id [String] Account id of the bank account/credit card, etc making payment (not user id)
|
|
481
|
+
# @option attributes [String] :request_three_d_secure Customise the 3DS (3D Secure) preference for this payment.
|
|
482
|
+
# Allowed values: 'automatic', 'challenge', 'any'. Defaults to 'automatic'.
|
|
483
|
+
# - 'automatic': 3DS preference is determined automatically by the system
|
|
484
|
+
# - 'challenge': Request a 3DS challenge is presented to the user
|
|
485
|
+
# - 'any': Request a 3DS challenge regardless of the challenge flow
|
|
486
|
+
# @return [Response] the API response containing payment details with payment_token
|
|
487
|
+
#
|
|
488
|
+
# @example Make an async payment with required parameters
|
|
489
|
+
# items = ZaiPayment::Resources::Item.new
|
|
490
|
+
# response = items.make_payment_async("item_id", account_id: "account_id")
|
|
491
|
+
# response.data # => {"payment_id" => "...", "payment_token" => "...", "items" => {...}}
|
|
492
|
+
#
|
|
493
|
+
# @example Make an async payment with 3DS challenge
|
|
494
|
+
# response = items.make_payment_async(
|
|
495
|
+
# "item_id",
|
|
496
|
+
# account_id: "account_id",
|
|
497
|
+
# request_three_d_secure: "challenge"
|
|
498
|
+
# )
|
|
499
|
+
#
|
|
500
|
+
# @see https://developer.hellozai.com/reference/makepaymentasync
|
|
501
|
+
def make_payment_async(item_id, **attributes)
|
|
502
|
+
validate_id!(item_id, 'item_id')
|
|
503
|
+
|
|
504
|
+
body = build_async_payment_body(attributes)
|
|
505
|
+
|
|
506
|
+
client.patch("/items/#{item_id}/make_payment_async", body: body)
|
|
507
|
+
end
|
|
508
|
+
|
|
302
509
|
private
|
|
303
510
|
|
|
304
511
|
def validate_id!(value, field_name)
|
|
@@ -346,6 +553,28 @@ module ZaiPayment
|
|
|
346
553
|
raise Errors::ValidationError, 'payment_type must be between 1 and 7'
|
|
347
554
|
end
|
|
348
555
|
|
|
556
|
+
def validate_request_three_d_secure!(value)
|
|
557
|
+
return if REQUEST_THREE_D_SECURE_VALUES.include?(value.to_s)
|
|
558
|
+
|
|
559
|
+
raise Errors::ValidationError,
|
|
560
|
+
"request_three_d_secure must be one of: #{REQUEST_THREE_D_SECURE_VALUES.join(', ')}"
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
def build_item_payment_body(attributes)
|
|
564
|
+
validate_presence!(attributes[:account_id], 'account_id')
|
|
565
|
+
|
|
566
|
+
body = {}
|
|
567
|
+
|
|
568
|
+
attributes.each do |key, value|
|
|
569
|
+
next if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
|
570
|
+
|
|
571
|
+
api_field = ITEM_PAYMENT_ATTRIBUTES[key]
|
|
572
|
+
body[api_field] = value if api_field
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
body
|
|
576
|
+
end
|
|
577
|
+
|
|
349
578
|
def build_item_body(attributes)
|
|
350
579
|
body = {}
|
|
351
580
|
|
|
@@ -358,6 +587,34 @@ module ZaiPayment
|
|
|
358
587
|
|
|
359
588
|
body
|
|
360
589
|
end
|
|
590
|
+
|
|
591
|
+
def build_refund_body(refund_amount: nil, refund_message: nil, account_id: nil)
|
|
592
|
+
body = {}
|
|
593
|
+
|
|
594
|
+
body[:refund_amount] = refund_amount if refund_amount
|
|
595
|
+
body[:refund_message] = refund_message if refund_message
|
|
596
|
+
body[:account_id] = account_id if account_id
|
|
597
|
+
|
|
598
|
+
body
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
def build_async_payment_body(attributes)
|
|
602
|
+
validate_presence!(attributes[:account_id], 'account_id')
|
|
603
|
+
|
|
604
|
+
# Validate request_three_d_secure if provided
|
|
605
|
+
validate_request_three_d_secure!(attributes[:request_three_d_secure]) if attributes[:request_three_d_secure]
|
|
606
|
+
|
|
607
|
+
body = {}
|
|
608
|
+
|
|
609
|
+
attributes.each do |key, value|
|
|
610
|
+
next if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
|
611
|
+
|
|
612
|
+
api_field = ITEM_ASYNC_PAYMENT_ATTRIBUTES[key]
|
|
613
|
+
body[api_field] = value if api_field
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
body
|
|
617
|
+
end
|
|
361
618
|
end
|
|
362
619
|
end
|
|
363
620
|
end
|
data/lib/zai_payment/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zai_payment
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eddy Jaga
|
|
@@ -99,7 +99,6 @@ files:
|
|
|
99
99
|
- lib/zai_payment/version.rb
|
|
100
100
|
- readme.md
|
|
101
101
|
- sig/zai_payment.rbs
|
|
102
|
-
- token_auth_implementation_summary.md
|
|
103
102
|
homepage: https://github.com/Sentia/zai-payment
|
|
104
103
|
licenses:
|
|
105
104
|
- MIT
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
# Token Auth API Implementation Summary
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Successfully implemented the **Generate Token** endpoint from the Zai API (https://developer.hellozai.com/reference/generatetoken) to enable secure bank and card account data collection.
|
|
6
|
-
|
|
7
|
-
## What Was Implemented
|
|
8
|
-
|
|
9
|
-
### 1. Core Resource Implementation
|
|
10
|
-
|
|
11
|
-
**File:** `lib/zai_payment/resources/token_auth.rb`
|
|
12
|
-
|
|
13
|
-
- Created `TokenAuth` resource class following the project's resource pattern
|
|
14
|
-
- Implemented `generate(user_id:, token_type:)` method
|
|
15
|
-
- Added token type validation (bank or card)
|
|
16
|
-
- Added user ID validation
|
|
17
|
-
- Support for case-insensitive token types
|
|
18
|
-
- Default token type: 'bank'
|
|
19
|
-
|
|
20
|
-
**Key Features:**
|
|
21
|
-
```ruby
|
|
22
|
-
# Generate a bank token (default)
|
|
23
|
-
ZaiPayment.token_auths.generate(user_id: "seller-123")
|
|
24
|
-
|
|
25
|
-
# Generate a card token
|
|
26
|
-
ZaiPayment.token_auths.generate(user_id: "buyer-123", token_type: "card")
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### 2. Module Integration
|
|
30
|
-
|
|
31
|
-
**File:** `lib/zai_payment.rb`
|
|
32
|
-
|
|
33
|
-
- Added `require_relative` for token_auth resource
|
|
34
|
-
- Added `token_auths` accessor method
|
|
35
|
-
- Configured to use `core_base` endpoint (https://test.api.promisepay.com)
|
|
36
|
-
|
|
37
|
-
### 3. Test Suite
|
|
38
|
-
|
|
39
|
-
**File:** `spec/zai_payment/resources/token_auth_spec.rb`
|
|
40
|
-
|
|
41
|
-
- 15 comprehensive test cases covering:
|
|
42
|
-
- Bank token generation
|
|
43
|
-
- Card token generation
|
|
44
|
-
- Default token type behavior
|
|
45
|
-
- Validation errors (nil, empty, whitespace, invalid types)
|
|
46
|
-
- Case-insensitive token types
|
|
47
|
-
- Client initialization
|
|
48
|
-
- Constants verification
|
|
49
|
-
- All tests passing with 95.22% line coverage
|
|
50
|
-
- Follows project's testing pattern using Faraday test stubs
|
|
51
|
-
- RuboCop compliant
|
|
52
|
-
|
|
53
|
-
### 4. Documentation
|
|
54
|
-
|
|
55
|
-
**File:** `examples/token_auths.md` (600+ lines)
|
|
56
|
-
|
|
57
|
-
Comprehensive examples including:
|
|
58
|
-
- Basic usage patterns
|
|
59
|
-
- Bank token collection workflows
|
|
60
|
-
- Card token collection workflows
|
|
61
|
-
- Rails controller integration
|
|
62
|
-
- Service object pattern
|
|
63
|
-
- Frontend integration with PromisePay.js
|
|
64
|
-
- Complete payment flow examples
|
|
65
|
-
- Error handling strategies
|
|
66
|
-
- Retry logic with exponential backoff
|
|
67
|
-
- Security best practices:
|
|
68
|
-
- Token expiry management
|
|
69
|
-
- Audit logging
|
|
70
|
-
- Rate limiting protection
|
|
71
|
-
|
|
72
|
-
**File:** `docs/token_auths.md` (500+ lines)
|
|
73
|
-
|
|
74
|
-
Complete technical guide covering:
|
|
75
|
-
- When to use Token Auth
|
|
76
|
-
- How it works (flow diagram)
|
|
77
|
-
- API methods reference
|
|
78
|
-
- Token types (bank vs card) with use cases
|
|
79
|
-
- Security considerations (PCI compliance, token lifecycle)
|
|
80
|
-
- Integration guide (backend + frontend)
|
|
81
|
-
- Error handling patterns
|
|
82
|
-
- Best practices with code examples
|
|
83
|
-
- Related resources and API references
|
|
84
|
-
|
|
85
|
-
### 5. Version Updates
|
|
86
|
-
|
|
87
|
-
**File:** `lib/zai_payment/version.rb`
|
|
88
|
-
|
|
89
|
-
- Updated version from `2.0.2` to `2.1.0`
|
|
90
|
-
- Follows semantic versioning (minor version bump for new feature)
|
|
91
|
-
|
|
92
|
-
### 6. Changelog
|
|
93
|
-
|
|
94
|
-
**File:** `changelog.md`
|
|
95
|
-
|
|
96
|
-
Added comprehensive release notes for version 2.1.0:
|
|
97
|
-
- Feature description
|
|
98
|
-
- API methods
|
|
99
|
-
- Documentation additions
|
|
100
|
-
- Testing coverage
|
|
101
|
-
- Link to full changelog
|
|
102
|
-
|
|
103
|
-
### 7. README Updates
|
|
104
|
-
|
|
105
|
-
**File:** `readme.md`
|
|
106
|
-
|
|
107
|
-
- Added Token Auth to features list (🎫 emoji)
|
|
108
|
-
- Added Token Auth section with quick examples
|
|
109
|
-
- Updated roadmap (marked Token Auth as Done ✅)
|
|
110
|
-
- Added documentation links in Examples & Patterns section
|
|
111
|
-
|
|
112
|
-
### 8. Documentation Index
|
|
113
|
-
|
|
114
|
-
**File:** `docs/readme.md`
|
|
115
|
-
|
|
116
|
-
- Added token_auths.md to Architecture & Design section
|
|
117
|
-
- Added Token Auth Examples to Examples section
|
|
118
|
-
- Added Token Auth to Quick Links with guide, examples, and API reference
|
|
119
|
-
- Updated documentation structure tree
|
|
120
|
-
- Added tips for collecting payment data
|
|
121
|
-
|
|
122
|
-
## API Endpoint
|
|
123
|
-
|
|
124
|
-
**POST** `https://test.api.promisepay.com/token_auths`
|
|
125
|
-
|
|
126
|
-
**Request Body:**
|
|
127
|
-
```json
|
|
128
|
-
{
|
|
129
|
-
"token_type": "bank", // or "card"
|
|
130
|
-
"user_id": "seller-68611249"
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**Response:**
|
|
135
|
-
```json
|
|
136
|
-
{
|
|
137
|
-
"token_auth": {
|
|
138
|
-
"token": "tok_bank_abc123...",
|
|
139
|
-
"user_id": "seller-68611249",
|
|
140
|
-
"token_type": "bank",
|
|
141
|
-
"created_at": "2025-10-24T12:00:00Z",
|
|
142
|
-
"expires_at": "2025-10-24T13:00:00Z"
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Usage Example
|
|
148
|
-
|
|
149
|
-
```ruby
|
|
150
|
-
# Configure the gem
|
|
151
|
-
ZaiPayment.configure do |c|
|
|
152
|
-
c.environment = :prelive
|
|
153
|
-
c.client_id = ENV['ZAI_CLIENT_ID']
|
|
154
|
-
c.client_secret = ENV['ZAI_CLIENT_SECRET']
|
|
155
|
-
c.scope = ENV['ZAI_OAUTH_SCOPE']
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
# Generate a card token for buyer
|
|
159
|
-
response = ZaiPayment.token_auths.generate(
|
|
160
|
-
user_id: "buyer-12345",
|
|
161
|
-
token_type: "card"
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
token = response.data['token_auth']['token']
|
|
165
|
-
# Send token to frontend for use with PromisePay.js
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
## Integration with PromisePay.js
|
|
169
|
-
|
|
170
|
-
```javascript
|
|
171
|
-
// Frontend (JavaScript)
|
|
172
|
-
PromisePay.setToken(token_from_backend);
|
|
173
|
-
|
|
174
|
-
PromisePay.createCardAccount({
|
|
175
|
-
card_number: '4111111111111111',
|
|
176
|
-
expiry_month: '12',
|
|
177
|
-
expiry_year: '2025',
|
|
178
|
-
cvv: '123'
|
|
179
|
-
}, function(response) {
|
|
180
|
-
if (response.error) {
|
|
181
|
-
console.error('Error:', response.error);
|
|
182
|
-
} else {
|
|
183
|
-
const cardAccountId = response.card_accounts.id;
|
|
184
|
-
// Send cardAccountId back to backend
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
## Test Results
|
|
190
|
-
|
|
191
|
-
- **Total Tests:** 272 examples
|
|
192
|
-
- **Failures:** 0
|
|
193
|
-
- **Line Coverage:** 95.22% (518 / 544)
|
|
194
|
-
- **Branch Coverage:** 80.79% (143 / 177)
|
|
195
|
-
- **RuboCop:** No offenses detected
|
|
196
|
-
|
|
197
|
-
## Files Created
|
|
198
|
-
|
|
199
|
-
1. `lib/zai_payment/resources/token_auth.rb` - Core resource implementation
|
|
200
|
-
2. `spec/zai_payment/resources/token_auth_spec.rb` - Test suite
|
|
201
|
-
3. `examples/token_auths.md` - Comprehensive usage examples
|
|
202
|
-
4. `docs/token_auths.md` - Technical documentation
|
|
203
|
-
|
|
204
|
-
## Files Modified
|
|
205
|
-
|
|
206
|
-
1. `lib/zai_payment.rb` - Added token_auths accessor
|
|
207
|
-
2. `lib/zai_payment/version.rb` - Version bump to 2.1.0
|
|
208
|
-
3. `changelog.md` - Added 2.1.0 release notes
|
|
209
|
-
4. `readme.md` - Added Token Auth documentation
|
|
210
|
-
5. `docs/readme.md` - Updated documentation index
|
|
211
|
-
|
|
212
|
-
## Security Considerations
|
|
213
|
-
|
|
214
|
-
- **PCI Compliance:** Tokens enable PCI-compliant card data collection without sensitive data touching your server
|
|
215
|
-
- **Token Expiration:** Tokens have limited lifespan (typically 1 hour)
|
|
216
|
-
- **Single-use:** Tokens should be generated fresh for each session
|
|
217
|
-
- **User-specific:** Each token is tied to a specific user ID
|
|
218
|
-
- **Type-specific:** Bank tokens only for bank accounts, card tokens only for cards
|
|
219
|
-
- **HTTPS Required:** All communication over secure HTTPS
|
|
220
|
-
|
|
221
|
-
## Next Steps
|
|
222
|
-
|
|
223
|
-
The Token Auth implementation is complete and ready for use. Developers can now:
|
|
224
|
-
|
|
225
|
-
1. Generate tokens for buyers to collect credit card information
|
|
226
|
-
2. Generate tokens for sellers to collect bank account details
|
|
227
|
-
3. Integrate with PromisePay.js for secure frontend data collection
|
|
228
|
-
4. Process payments without handling sensitive payment data directly
|
|
229
|
-
|
|
230
|
-
## Related APIs
|
|
231
|
-
|
|
232
|
-
This implementation complements existing resources:
|
|
233
|
-
- **Users API** - Create users before generating tokens
|
|
234
|
-
- **Items API** - Use payment accounts to create transactions
|
|
235
|
-
- **Webhooks API** - Receive notifications about payment events
|
|
236
|
-
|
|
237
|
-
## Documentation Links
|
|
238
|
-
|
|
239
|
-
- **API Reference:** https://developer.hellozai.com/reference/generatetoken
|
|
240
|
-
- **Examples:** [examples/token_auths.md](examples/token_auths.md)
|
|
241
|
-
- **Guide:** [docs/token_auths.md](docs/token_auths.md)
|
|
242
|
-
- **PromisePay.js:** https://developer.hellozai.com/docs/promisepay-js
|
|
243
|
-
|
|
244
|
-
---
|
|
245
|
-
|
|
246
|
-
**Implementation Date:** October 24, 2025
|
|
247
|
-
**Version:** 2.1.0
|
|
248
|
-
**Status:** ✅ Complete and tested
|
|
249
|
-
|