zai_payment 2.8.0 → 2.8.2
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/changelog.md +19 -0
- data/docs/bank_accounts.md +13 -11
- data/examples/bank_accounts.md +3 -3
- data/lib/zai_payment/resources/wallet_account.rb +109 -0
- data/lib/zai_payment/response.rb +1 -1
- data/lib/zai_payment/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b3f20fe256ab69c787f421db039fac49e817c855ca7aa07441380fb1d03ab2ca
|
|
4
|
+
data.tar.gz: 995f5e6a67dbc86b4ebadd2918c96dd63ba0effe5c8991826fd35e89bfdd6c0c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e7152d67c815e5698d8f61aa4f28fa9957190b7ba97a3dac7fee73248698d04cf1d44acfca6988cd301fcf6e3094420f1b90d135e643af4b5150e8cde796c799
|
|
7
|
+
data.tar.gz: 811ec3899505dc68601c9432f7c4356f4e5fc3d44703bd156b5ce55daeb5ec90ceede45d9fc1084fa09ec7f5c281856635d9d3f1b1064338094dddf4e93d2e63
|
data/changelog.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
## [Released]
|
|
2
2
|
|
|
3
|
+
## [2.8.1] - 2025-11-07
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **Response Data Extraction Bug**: Fixed `.data` method returning only `routing_number` value instead of full object 🐛
|
|
7
|
+
- Removed `routing_number` from `RESPONSE_DATA_KEYS` constant - it's a field within responses, not a collection wrapper key
|
|
8
|
+
- The `.data` method was incorrectly treating `routing_number` as a top-level data key
|
|
9
|
+
- This caused `response.data` to return just `"803320"` (the routing number) instead of the complete virtual account object
|
|
10
|
+
- Now properly returns the full response object when no wrapper key is found
|
|
11
|
+
- Affected resources: Virtual Accounts (and potentially other resources with `routing_number` field)
|
|
12
|
+
- Updated test mocks to match actual API response format (flat objects for single resources)
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **Virtual Account Test Fixtures**: Updated response structure to match actual Zai API format
|
|
16
|
+
- Single resource responses (show, create, update) now return flat objects without wrapper keys
|
|
17
|
+
- Collection responses (list) continue to use `virtual_accounts` wrapper key
|
|
18
|
+
- All 87 virtual account tests passing with corrected response structure
|
|
19
|
+
|
|
20
|
+
**Full Changelog**: https://github.com/Sentia/zai-payment/compare/v2.8.0...v2.8.1
|
|
21
|
+
|
|
3
22
|
## [2.8.0] - 2025-11-07
|
|
4
23
|
|
|
5
24
|
### Added
|
data/docs/bank_accounts.md
CHANGED
|
@@ -117,7 +117,7 @@ Validate a US bank routing number before creating an account. This can be used t
|
|
|
117
117
|
response = bank_accounts.validate_routing_number('122235821')
|
|
118
118
|
|
|
119
119
|
if response.success?
|
|
120
|
-
routing_info = response.data
|
|
120
|
+
routing_info = response.data['routing_number']
|
|
121
121
|
puts "Routing Number: #{routing_info['routing_number']}"
|
|
122
122
|
puts "Bank Name: #{routing_info['customer_name']}"
|
|
123
123
|
puts "City: #{routing_info['city']}"
|
|
@@ -133,16 +133,18 @@ end
|
|
|
133
133
|
|
|
134
134
|
```ruby
|
|
135
135
|
{
|
|
136
|
-
"routing_number" =>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
136
|
+
"routing_number" => {
|
|
137
|
+
"routing_number" => "122235821",
|
|
138
|
+
"customer_name" => "US BANK NA",
|
|
139
|
+
"address" => "EP-MN-WN1A",
|
|
140
|
+
"city" => "ST. PAUL",
|
|
141
|
+
"state_code" => "MN",
|
|
142
|
+
"zip" => "55107",
|
|
143
|
+
"zip_extension" => "1419",
|
|
144
|
+
"phone_area_code" => "800",
|
|
145
|
+
"phone_prefix" => "937",
|
|
146
|
+
"phone_suffix" => "631"
|
|
147
|
+
}
|
|
146
148
|
}
|
|
147
149
|
```
|
|
148
150
|
|
data/examples/bank_accounts.md
CHANGED
|
@@ -164,7 +164,7 @@ bank_accounts = ZaiPayment::Resources::BankAccount.new
|
|
|
164
164
|
response = bank_accounts.validate_routing_number('122235821')
|
|
165
165
|
|
|
166
166
|
if response.success?
|
|
167
|
-
routing_info = response.data
|
|
167
|
+
routing_info = response.data['routing_number']
|
|
168
168
|
|
|
169
169
|
puts "Routing Number Validation Results:"
|
|
170
170
|
puts " Routing Number: #{routing_info['routing_number']}"
|
|
@@ -197,7 +197,7 @@ begin
|
|
|
197
197
|
validation_response = bank_accounts.validate_routing_number(routing_number)
|
|
198
198
|
|
|
199
199
|
if validation_response.success?
|
|
200
|
-
bank_info = validation_response.data
|
|
200
|
+
bank_info = validation_response.data['routing_number']
|
|
201
201
|
|
|
202
202
|
# Show user the bank information for confirmation
|
|
203
203
|
puts "You are creating an account with:"
|
|
@@ -246,7 +246,7 @@ class BankAccountsController < ApplicationController
|
|
|
246
246
|
response = bank_accounts.validate_routing_number(routing_number)
|
|
247
247
|
|
|
248
248
|
if response.success?
|
|
249
|
-
bank_info = response.data
|
|
249
|
+
bank_info = response.data['routing_number']
|
|
250
250
|
|
|
251
251
|
# Return bank info to display in the form
|
|
252
252
|
render json: {
|
|
@@ -15,6 +15,16 @@ module ZaiPayment
|
|
|
15
15
|
reference_id: :reference_id
|
|
16
16
|
}.freeze
|
|
17
17
|
|
|
18
|
+
# Map of attribute keys to API field names for withdraw
|
|
19
|
+
WITHDRAW_FIELD_MAPPING = {
|
|
20
|
+
account_id: :account_id,
|
|
21
|
+
amount: :amount,
|
|
22
|
+
custom_descriptor: :custom_descriptor,
|
|
23
|
+
reference_id: :reference_id,
|
|
24
|
+
end_to_end_id: :end_to_end_id,
|
|
25
|
+
ifti_information: :ifti_information
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
18
28
|
def initialize(client: nil)
|
|
19
29
|
@client = client || Client.new
|
|
20
30
|
end
|
|
@@ -118,6 +128,58 @@ module ZaiPayment
|
|
|
118
128
|
client.post("/wallet_accounts/#{wallet_account_id}/bill_payment", body: body)
|
|
119
129
|
end
|
|
120
130
|
|
|
131
|
+
# Withdraw funds from a Wallet Account to a specified disbursement account
|
|
132
|
+
#
|
|
133
|
+
# @param wallet_account_id [String] the wallet account ID
|
|
134
|
+
# @param attributes [Hash] withdrawal attributes
|
|
135
|
+
# @option attributes [String] :account_id (Required) Account ID to withdraw to
|
|
136
|
+
# @option attributes [Integer] :amount (Required) Amount in cents to withdraw
|
|
137
|
+
# @option attributes [String] :custom_descriptor Custom descriptor for the withdrawal
|
|
138
|
+
# (max 200 chars for NPP, 18 for DE batch)
|
|
139
|
+
# @option attributes [String] :reference_id Unique reference information (cannot contain '.' character)
|
|
140
|
+
# @option attributes [String] :end_to_end_id Unique identifier for NPP IFTI payout tracking (mandatory for IFTI)
|
|
141
|
+
# @option attributess [Hash] :ifti_information IFTI payer information hash (required for IFTI payouts)
|
|
142
|
+
# @return [Response] the API response containing disbursement details
|
|
143
|
+
#
|
|
144
|
+
# @example Basic withdrawal
|
|
145
|
+
# wallet_accounts = ZaiPayment::Resources::WalletAccount.new
|
|
146
|
+
# response = wallet_accounts.withdraw(
|
|
147
|
+
# 'wallet_account_id',
|
|
148
|
+
# account_id: 'bank_account_id',
|
|
149
|
+
# amount: 10000
|
|
150
|
+
# )
|
|
151
|
+
#
|
|
152
|
+
# @example Withdrawal with custom descriptor and reference
|
|
153
|
+
# response = wallet_accounts.withdraw(
|
|
154
|
+
# 'wallet_account_id',
|
|
155
|
+
# account_id: 'bank_account_id',
|
|
156
|
+
# amount: 10000,
|
|
157
|
+
# custom_descriptor: 'Invoice #12345 Payment',
|
|
158
|
+
# reference_id: 'ref-12345'
|
|
159
|
+
# )
|
|
160
|
+
#
|
|
161
|
+
# @example NPP IFTI withdrawal
|
|
162
|
+
# response = wallet_accounts.withdraw(
|
|
163
|
+
# 'wallet_account_id',
|
|
164
|
+
# account_id: 'bank_account_id',
|
|
165
|
+
# amount: 10000,
|
|
166
|
+
# end_to_end_id: 'E2E-UNIQUE-ID-123',
|
|
167
|
+
# ifti_information: {
|
|
168
|
+
# payer_name: 'John Doe',
|
|
169
|
+
# payer_address: '123 Main St, Sydney NSW 2000',
|
|
170
|
+
# payer_country: 'AUS'
|
|
171
|
+
# }
|
|
172
|
+
# )
|
|
173
|
+
#
|
|
174
|
+
# @see https://developer.hellozai.com/reference
|
|
175
|
+
def withdraw(wallet_account_id, **attributes)
|
|
176
|
+
validate_id!(wallet_account_id, 'wallet_account_id')
|
|
177
|
+
validate_withdraw_attributes!(attributes)
|
|
178
|
+
|
|
179
|
+
body = build_withdraw_body(attributes)
|
|
180
|
+
client.post("/wallet_accounts/#{wallet_account_id}/withdraw", body: body)
|
|
181
|
+
end
|
|
182
|
+
|
|
121
183
|
private
|
|
122
184
|
|
|
123
185
|
def validate_id!(value, field_name)
|
|
@@ -159,6 +221,40 @@ module ZaiPayment
|
|
|
159
221
|
raise Errors::ValidationError, "reference_id cannot contain single quote (') character"
|
|
160
222
|
end
|
|
161
223
|
|
|
224
|
+
def validate_withdraw_attributes!(attributes)
|
|
225
|
+
validate_required_withdraw_attributes!(attributes)
|
|
226
|
+
validate_amount!(attributes[:amount]) if attributes[:amount]
|
|
227
|
+
validate_withdraw_reference_id!(attributes[:reference_id]) if attributes[:reference_id]
|
|
228
|
+
validate_custom_descriptor!(attributes[:custom_descriptor]) if attributes[:custom_descriptor]
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def validate_required_withdraw_attributes!(attributes)
|
|
232
|
+
required_fields = %i[account_id amount]
|
|
233
|
+
|
|
234
|
+
missing_fields = required_fields.select do |field|
|
|
235
|
+
attributes[field].nil? || (attributes[field].respond_to?(:to_s) && attributes[field].to_s.strip.empty?)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
return if missing_fields.empty?
|
|
239
|
+
|
|
240
|
+
raise Errors::ValidationError,
|
|
241
|
+
"Missing required fields: #{missing_fields.join(', ')}"
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def validate_withdraw_reference_id!(reference_id)
|
|
245
|
+
# Reference ID cannot contain '.' character
|
|
246
|
+
return unless reference_id.to_s.include?('.')
|
|
247
|
+
|
|
248
|
+
raise Errors::ValidationError, "reference_id cannot contain '.' character"
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def validate_custom_descriptor!(custom_descriptor)
|
|
252
|
+
# Basic validation - max 200 characters for NPP (API will enforce specific limits)
|
|
253
|
+
return if custom_descriptor.to_s.length <= 200
|
|
254
|
+
|
|
255
|
+
raise Errors::ValidationError, 'custom_descriptor must be 200 characters or less'
|
|
256
|
+
end
|
|
257
|
+
|
|
162
258
|
def build_pay_bill_body(attributes)
|
|
163
259
|
body = {}
|
|
164
260
|
|
|
@@ -171,6 +267,19 @@ module ZaiPayment
|
|
|
171
267
|
|
|
172
268
|
body
|
|
173
269
|
end
|
|
270
|
+
|
|
271
|
+
def build_withdraw_body(attributes)
|
|
272
|
+
body = {}
|
|
273
|
+
|
|
274
|
+
attributes.each do |key, value|
|
|
275
|
+
next if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
|
276
|
+
|
|
277
|
+
api_field = WITHDRAW_FIELD_MAPPING[key]
|
|
278
|
+
body[api_field] = value if api_field
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
body
|
|
282
|
+
end
|
|
174
283
|
end
|
|
175
284
|
end
|
|
176
285
|
end
|
data/lib/zai_payment/response.rb
CHANGED
|
@@ -8,7 +8,7 @@ module ZaiPayment
|
|
|
8
8
|
RESPONSE_DATA_KEYS = %w[
|
|
9
9
|
webhooks users items fees transactions
|
|
10
10
|
batch_transactions batches bpay_accounts bank_accounts card_accounts
|
|
11
|
-
wallet_accounts virtual_accounts
|
|
11
|
+
wallet_accounts virtual_accounts disbursements pay_ids
|
|
12
12
|
].freeze
|
|
13
13
|
|
|
14
14
|
def initialize(faraday_response)
|
data/lib/zai_payment/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zai_payment
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.8.
|
|
4
|
+
version: 2.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eddy Jaga
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: exe
|
|
9
10
|
cert_chain: []
|
|
10
|
-
date:
|
|
11
|
+
date: 2025-11-21 00:00:00.000000000 Z
|
|
11
12
|
dependencies:
|
|
12
13
|
- !ruby/object:Gem::Dependency
|
|
13
14
|
name: base64
|
|
@@ -129,6 +130,7 @@ metadata:
|
|
|
129
130
|
code_of_conduct_uri: https://github.com/Sentia/zai-payment/blob/main/code_of_conduct.md
|
|
130
131
|
rubygems_mfa_required: 'true'
|
|
131
132
|
documentation_uri: https://github.com/Sentia/zai-payment#readme
|
|
133
|
+
post_install_message:
|
|
132
134
|
rdoc_options: []
|
|
133
135
|
require_paths:
|
|
134
136
|
- lib
|
|
@@ -143,7 +145,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
143
145
|
- !ruby/object:Gem::Version
|
|
144
146
|
version: '0'
|
|
145
147
|
requirements: []
|
|
146
|
-
rubygems_version: 3.
|
|
148
|
+
rubygems_version: 3.5.11
|
|
149
|
+
signing_key:
|
|
147
150
|
specification_version: 4
|
|
148
151
|
summary: Ruby gem for Zai payment integration
|
|
149
152
|
test_files: []
|