zai_payment 2.6.1 → 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.
- checksums.yaml +4 -4
- data/IMPLEMENTATION_SUMMARY.md +183 -0
- data/RESPONSE_FORMAT_CORRECTION.md +75 -0
- data/badges/coverage.json +1 -1
- data/changelog.md +158 -0
- data/docs/batch_transactions.md +340 -0
- data/docs/direct_api_usage.md +489 -0
- data/docs/pay_ids.md +777 -0
- data/docs/virtual_accounts.md +916 -0
- data/docs/wallet_accounts.md +493 -0
- data/examples/batch_transactions.md +450 -0
- data/examples/pay_ids.md +871 -0
- data/examples/virtual_accounts.md +1530 -0
- data/examples/wallet_accounts.md +733 -0
- data/lib/zai_payment/resources/batch_transaction.rb +302 -0
- data/lib/zai_payment/resources/pay_id.rb +197 -0
- data/lib/zai_payment/resources/virtual_account.rb +212 -0
- data/lib/zai_payment/resources/wallet_account.rb +176 -0
- data/lib/zai_payment/response.rb +2 -2
- data/lib/zai_payment/version.rb +1 -1
- data/lib/zai_payment.rb +24 -0
- data/readme.md +109 -3
- metadata +16 -1
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ZaiPayment
|
|
4
|
+
module Resources
|
|
5
|
+
# BatchTransaction resource for managing Zai batch transactions (Prelive only)
|
|
6
|
+
#
|
|
7
|
+
# @note These endpoints are only available in the prelive environment
|
|
8
|
+
class BatchTransaction
|
|
9
|
+
attr_reader :client, :config
|
|
10
|
+
|
|
11
|
+
# Valid transaction types
|
|
12
|
+
TRANSACTION_TYPES = %w[payment refund disbursement fee deposit withdrawal].freeze
|
|
13
|
+
|
|
14
|
+
# Valid transaction type methods
|
|
15
|
+
TRANSACTION_TYPE_METHODS = %w[credit_card npp bpay wallet_account_transfer wire_transfer misc].freeze
|
|
16
|
+
|
|
17
|
+
# Valid directions
|
|
18
|
+
DIRECTIONS = %w[debit credit].freeze
|
|
19
|
+
|
|
20
|
+
def initialize(client: nil, config: nil)
|
|
21
|
+
@client = client || Client.new(base_endpoint: :core_base)
|
|
22
|
+
@config = config || ZaiPayment.config
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# List batch transactions
|
|
26
|
+
#
|
|
27
|
+
# Retrieve an ordered and paginated list of existing batch transactions.
|
|
28
|
+
# The list can be filtered by account, batch ID, item, and transaction type.
|
|
29
|
+
#
|
|
30
|
+
# @param options [Hash] optional filters
|
|
31
|
+
# @option options [Integer] :limit number of records to return (default: 10, max: 200)
|
|
32
|
+
# @option options [Integer] :offset number of records to skip (default: 0)
|
|
33
|
+
# @option options [String] :account_id Bank, Card or Wallet Account ID
|
|
34
|
+
# @option options [String] :batch_id Batch ID
|
|
35
|
+
# @option options [String] :item_id Item ID
|
|
36
|
+
# @option options [String] :transaction_type transaction type
|
|
37
|
+
# (payment, refund, disbursement, fee, deposit, withdrawal)
|
|
38
|
+
# @option options [String] :transaction_type_method transaction method (credit_card, npp, bpay, etc.)
|
|
39
|
+
# @option options [String] :direction direction (debit, credit)
|
|
40
|
+
# @option options [String] :created_before ISO 8601 date/time to filter transactions created before
|
|
41
|
+
# @option options [String] :created_after ISO 8601 date/time to filter transactions created after
|
|
42
|
+
# @option options [String] :disbursement_bank the bank used for disbursing the payment
|
|
43
|
+
# @option options [String] :processing_bank the bank used for processing the payment
|
|
44
|
+
# @return [Response] the API response containing batch_transactions array
|
|
45
|
+
#
|
|
46
|
+
# @example List all batch transactions
|
|
47
|
+
# batch_transactions = ZaiPayment.batch_transactions
|
|
48
|
+
# response = batch_transactions.list
|
|
49
|
+
# response.data # => [{"id" => 12484, "status" => 12200, ...}]
|
|
50
|
+
#
|
|
51
|
+
# @example List with filters
|
|
52
|
+
# response = batch_transactions.list(
|
|
53
|
+
# transaction_type: 'disbursement',
|
|
54
|
+
# direction: 'credit',
|
|
55
|
+
# limit: 50
|
|
56
|
+
# )
|
|
57
|
+
#
|
|
58
|
+
# @see https://developer.hellozai.com/reference/listbatchtransactions
|
|
59
|
+
def list(**options)
|
|
60
|
+
validate_list_options(options)
|
|
61
|
+
|
|
62
|
+
params = build_list_params(options)
|
|
63
|
+
|
|
64
|
+
client.get('/batch_transactions', params: params)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Show a batch transaction
|
|
68
|
+
#
|
|
69
|
+
# Get a batch transaction using its ID (UUID or numeric ID).
|
|
70
|
+
#
|
|
71
|
+
# @param id [String] the batch transaction ID
|
|
72
|
+
# @return [Response] the API response containing batch_transactions object
|
|
73
|
+
#
|
|
74
|
+
# @example Get a batch transaction by UUID
|
|
75
|
+
# batch_transactions = ZaiPayment.batch_transactions
|
|
76
|
+
# response = batch_transactions.show('90c1418b-f4f4-413e-a4ba-f29c334e7f55')
|
|
77
|
+
# response.data # => {"id" => 13143, "uuid" => "90c1418b-f4f4-413e-a4ba-f29c334e7f55", ...}
|
|
78
|
+
#
|
|
79
|
+
# @example Get a batch transaction by numeric ID
|
|
80
|
+
# response = batch_transactions.show('13143')
|
|
81
|
+
# response.data['state'] # => "successful"
|
|
82
|
+
#
|
|
83
|
+
# @raise [Errors::ValidationError] if id is blank
|
|
84
|
+
#
|
|
85
|
+
# @see https://developer.hellozai.com/reference/showbatchtransaction
|
|
86
|
+
def show(id)
|
|
87
|
+
validate_id!(id, 'id')
|
|
88
|
+
|
|
89
|
+
client.get("/batch_transactions/#{id}")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Export batch transactions (Prelive only)
|
|
93
|
+
#
|
|
94
|
+
# Calls the GET /batch_transactions/export_transactions API which moves all pending
|
|
95
|
+
# batch_transactions into batched state. As a result, this API will return all the
|
|
96
|
+
# batch_transactions that have moved from pending to batched. Please store the id
|
|
97
|
+
# in order to progress it in Pre-live.
|
|
98
|
+
#
|
|
99
|
+
# @return [Response] the API response containing transactions array with batch_id
|
|
100
|
+
#
|
|
101
|
+
# @example Export transactions
|
|
102
|
+
# batch_transactions = ZaiPayment.batch_transactions
|
|
103
|
+
# response = batch_transactions.export_transactions
|
|
104
|
+
# response.data # => {"transactions" => [{"id" => "...", "batch_id" => "...", "status" => "batched", ...}]}
|
|
105
|
+
#
|
|
106
|
+
# @raise [Errors::ConfigurationError] if not in prelive environment
|
|
107
|
+
#
|
|
108
|
+
# @see https://developer.hellozai.com/reference (Prelive endpoints)
|
|
109
|
+
def export_transactions
|
|
110
|
+
ensure_prelive_environment!
|
|
111
|
+
|
|
112
|
+
client.get('/batch_transactions/export_transactions')
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Update batch transaction states (Prelive only)
|
|
116
|
+
#
|
|
117
|
+
# Calls the PATCH /batches/:id/transaction_states API which moves one or more
|
|
118
|
+
# batch_transactions into a specific state. You will need to pass in the batch_id
|
|
119
|
+
# from the export_transactions response.
|
|
120
|
+
#
|
|
121
|
+
# State codes:
|
|
122
|
+
# - 12700: bank_processing state
|
|
123
|
+
# - 12000: successful state (final state, triggers webhook)
|
|
124
|
+
#
|
|
125
|
+
# @param batch_id [String] the batch ID from export_transactions response
|
|
126
|
+
# @param exported_ids [Array<String>] array of transaction IDs to update
|
|
127
|
+
# @param state [Integer] the target state code (12700 or 12000)
|
|
128
|
+
# @return [Response] the API response containing job information
|
|
129
|
+
#
|
|
130
|
+
# @example Move transactions to bank_processing state
|
|
131
|
+
# batch_transactions = ZaiPayment.batch_transactions
|
|
132
|
+
# response = batch_transactions.update_transaction_states(
|
|
133
|
+
# "batch_id",
|
|
134
|
+
# exported_ids: ["439970a2-e0a1-418e-aecf-6b519c115c55"],
|
|
135
|
+
# state: 12700
|
|
136
|
+
# )
|
|
137
|
+
# response.body # => {
|
|
138
|
+
# "aggregated_jobs_uuid" => "c1cbc502-9754-42fd-9731-2330ddd7a41f",
|
|
139
|
+
# "msg" => "1 jobs have been sent to the queue.",
|
|
140
|
+
# "errors" => []
|
|
141
|
+
# }
|
|
142
|
+
#
|
|
143
|
+
# @example Move transactions to successful state
|
|
144
|
+
# response = batch_transactions.update_transaction_states(
|
|
145
|
+
# "batch_id",
|
|
146
|
+
# exported_ids: ["439970a2-e0a1-418e-aecf-6b519c115c55"],
|
|
147
|
+
# state: 12000
|
|
148
|
+
# )
|
|
149
|
+
# response.body # => {
|
|
150
|
+
# "aggregated_jobs_uuid" => "...",
|
|
151
|
+
# "msg" => "1 jobs have been sent to the queue.",
|
|
152
|
+
# "errors" => []
|
|
153
|
+
# }
|
|
154
|
+
#
|
|
155
|
+
# @raise [Errors::ConfigurationError] if not in prelive environment
|
|
156
|
+
# @raise [Errors::ValidationError] if parameters are invalid
|
|
157
|
+
#
|
|
158
|
+
# @see https://developer.hellozai.com/reference (Prelive endpoints)
|
|
159
|
+
def update_transaction_states(batch_id, exported_ids:, state:)
|
|
160
|
+
ensure_prelive_environment!
|
|
161
|
+
validate_id!(batch_id, 'batch_id')
|
|
162
|
+
validate_exported_ids!(exported_ids)
|
|
163
|
+
validate_state!(state)
|
|
164
|
+
|
|
165
|
+
body = {
|
|
166
|
+
exported_ids: exported_ids,
|
|
167
|
+
state: state
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
client.patch("/batches/#{batch_id}/transaction_states", body: body)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Move transactions to bank_processing state (Prelive only)
|
|
174
|
+
#
|
|
175
|
+
# Convenience method that calls update_transaction_states with state 12700.
|
|
176
|
+
# This simulates the step where transactions are moved to bank_processing state.
|
|
177
|
+
#
|
|
178
|
+
# @param batch_id [String] the batch ID from export_transactions response
|
|
179
|
+
# @param exported_ids [Array<String>] array of transaction IDs to update
|
|
180
|
+
# @return [Response] the API response with aggregated_jobs_uuid, msg, and errors
|
|
181
|
+
#
|
|
182
|
+
# @example
|
|
183
|
+
# batch_transactions = ZaiPayment.batch_transactions
|
|
184
|
+
# response = batch_transactions.process_to_bank_processing(
|
|
185
|
+
# "batch_id",
|
|
186
|
+
# exported_ids: ["439970a2-e0a1-418e-aecf-6b519c115c55"]
|
|
187
|
+
# )
|
|
188
|
+
# response.body["msg"] # => "1 jobs have been sent to the queue."
|
|
189
|
+
#
|
|
190
|
+
# @raise [Errors::ConfigurationError] if not in prelive environment
|
|
191
|
+
# @raise [Errors::ValidationError] if parameters are invalid
|
|
192
|
+
def process_to_bank_processing(batch_id, exported_ids:)
|
|
193
|
+
update_transaction_states(batch_id, exported_ids: exported_ids, state: 12_700)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Move transactions to successful state (Prelive only)
|
|
197
|
+
#
|
|
198
|
+
# Convenience method that calls update_transaction_states with state 12000.
|
|
199
|
+
# This simulates the final step where transactions are marked as successful
|
|
200
|
+
# and triggers the batch_transactions webhook.
|
|
201
|
+
#
|
|
202
|
+
# @param batch_id [String] the batch ID from export_transactions response
|
|
203
|
+
# @param exported_ids [Array<String>] array of transaction IDs to update
|
|
204
|
+
# @return [Response] the API response with aggregated_jobs_uuid, msg, and errors
|
|
205
|
+
#
|
|
206
|
+
# @example
|
|
207
|
+
# batch_transactions = ZaiPayment.batch_transactions
|
|
208
|
+
# response = batch_transactions.process_to_successful(
|
|
209
|
+
# "batch_id",
|
|
210
|
+
# exported_ids: ["439970a2-e0a1-418e-aecf-6b519c115c55"]
|
|
211
|
+
# )
|
|
212
|
+
# response.body["msg"] # => "1 jobs have been sent to the queue."
|
|
213
|
+
#
|
|
214
|
+
# @raise [Errors::ConfigurationError] if not in prelive environment
|
|
215
|
+
# @raise [Errors::ValidationError] if parameters are invalid
|
|
216
|
+
def process_to_successful(batch_id, exported_ids:)
|
|
217
|
+
update_transaction_states(batch_id, exported_ids: exported_ids, state: 12_000)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
private
|
|
221
|
+
|
|
222
|
+
def ensure_prelive_environment!
|
|
223
|
+
return if config.environment.to_sym == :prelive
|
|
224
|
+
|
|
225
|
+
raise Errors::ConfigurationError,
|
|
226
|
+
'Batch transaction endpoints are only available in prelive environment. ' \
|
|
227
|
+
"Current environment: #{config.environment}"
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def validate_id!(value, field_name)
|
|
231
|
+
return unless value.nil? || value.to_s.strip.empty?
|
|
232
|
+
|
|
233
|
+
raise Errors::ValidationError, "#{field_name} is required and cannot be blank"
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def validate_exported_ids!(exported_ids)
|
|
237
|
+
if exported_ids.nil? || !exported_ids.is_a?(Array) || exported_ids.empty?
|
|
238
|
+
raise Errors::ValidationError,
|
|
239
|
+
'exported_ids is required and must be a non-empty array'
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
return unless exported_ids.any? { |id| id.nil? || id.to_s.strip.empty? }
|
|
243
|
+
|
|
244
|
+
raise Errors::ValidationError,
|
|
245
|
+
'exported_ids cannot contain nil or empty values'
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def validate_state!(state)
|
|
249
|
+
valid_states = [12_700, 12_000]
|
|
250
|
+
|
|
251
|
+
return if valid_states.include?(state)
|
|
252
|
+
|
|
253
|
+
raise Errors::ValidationError,
|
|
254
|
+
"state must be 12700 (bank_processing) or 12000 (successful), got: #{state}"
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def validate_transaction_type!(transaction_type)
|
|
258
|
+
return if TRANSACTION_TYPES.include?(transaction_type.to_s)
|
|
259
|
+
|
|
260
|
+
raise Errors::ValidationError,
|
|
261
|
+
"transaction_type must be one of: #{TRANSACTION_TYPES.join(', ')}"
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def validate_transaction_type_method!(transaction_type_method)
|
|
265
|
+
return if TRANSACTION_TYPE_METHODS.include?(transaction_type_method.to_s)
|
|
266
|
+
|
|
267
|
+
raise Errors::ValidationError,
|
|
268
|
+
"transaction_type_method must be one of: #{TRANSACTION_TYPE_METHODS.join(', ')}"
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def validate_direction!(direction)
|
|
272
|
+
return if DIRECTIONS.include?(direction.to_s)
|
|
273
|
+
|
|
274
|
+
raise Errors::ValidationError,
|
|
275
|
+
"direction must be one of: #{DIRECTIONS.join(', ')}"
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def validate_list_options(options)
|
|
279
|
+
validate_transaction_type!(options[:transaction_type]) if options[:transaction_type]
|
|
280
|
+
validate_transaction_type_method!(options[:transaction_type_method]) if options[:transaction_type_method]
|
|
281
|
+
validate_direction!(options[:direction]) if options[:direction]
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def build_list_params(options)
|
|
285
|
+
{
|
|
286
|
+
limit: options.fetch(:limit, 10),
|
|
287
|
+
offset: options.fetch(:offset, 0),
|
|
288
|
+
account_id: options[:account_id],
|
|
289
|
+
batch_id: options[:batch_id],
|
|
290
|
+
item_id: options[:item_id],
|
|
291
|
+
transaction_type: options[:transaction_type],
|
|
292
|
+
transaction_type_method: options[:transaction_type_method],
|
|
293
|
+
direction: options[:direction],
|
|
294
|
+
created_before: options[:created_before],
|
|
295
|
+
created_after: options[:created_after],
|
|
296
|
+
disbursement_bank: options[:disbursement_bank],
|
|
297
|
+
processing_bank: options[:processing_bank]
|
|
298
|
+
}.compact
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ZaiPayment
|
|
4
|
+
module Resources
|
|
5
|
+
# PayID resource for managing Zai PayID registrations
|
|
6
|
+
#
|
|
7
|
+
# @see https://developer.hellozai.com/reference/registerpayid
|
|
8
|
+
class PayId
|
|
9
|
+
attr_reader :client
|
|
10
|
+
|
|
11
|
+
# Map of attribute keys to API field names for create
|
|
12
|
+
CREATE_FIELD_MAPPING = {
|
|
13
|
+
pay_id: :pay_id,
|
|
14
|
+
type: :type,
|
|
15
|
+
details: :details
|
|
16
|
+
}.freeze
|
|
17
|
+
|
|
18
|
+
# Valid PayID types
|
|
19
|
+
VALID_TYPES = %w[EMAIL].freeze
|
|
20
|
+
|
|
21
|
+
# Valid PayID statuses for update
|
|
22
|
+
VALID_STATUSES = %w[deregistered].freeze
|
|
23
|
+
|
|
24
|
+
def initialize(client: nil)
|
|
25
|
+
@client = client || Client.new(base_endpoint: :va_base)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Register a PayID for a given Virtual Account
|
|
29
|
+
#
|
|
30
|
+
# @param virtual_account_id [String] the virtual account ID
|
|
31
|
+
# @param attributes [Hash] PayID attributes
|
|
32
|
+
# @option attributes [String] :pay_id (Required) The PayID being registered (max 256 chars)
|
|
33
|
+
# @option attributes [String] :type (Required) The type of PayID ('EMAIL')
|
|
34
|
+
# @option attributes [Hash] :details (Required) Additional details
|
|
35
|
+
# @option details [String] :pay_id_name Name to identify the entity (1-140 chars)
|
|
36
|
+
# @option details [String] :owner_legal_name Full legal account name (1-140 chars)
|
|
37
|
+
# @return [Response] the API response containing PayID details
|
|
38
|
+
#
|
|
39
|
+
# @example Register an EMAIL PayID
|
|
40
|
+
# pay_ids = ZaiPayment::Resources::PayId.new
|
|
41
|
+
# response = pay_ids.create(
|
|
42
|
+
# '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
43
|
+
# pay_id: 'jsmith@mydomain.com',
|
|
44
|
+
# type: 'EMAIL',
|
|
45
|
+
# details: {
|
|
46
|
+
# pay_id_name: 'J Smith',
|
|
47
|
+
# owner_legal_name: 'Mr John Smith'
|
|
48
|
+
# }
|
|
49
|
+
# )
|
|
50
|
+
# response.data # => {"id" => "46deb476-c1a6-41eb-8eb7-26a695bbe5bc", ...}
|
|
51
|
+
#
|
|
52
|
+
# @see https://developer.hellozai.com/reference/registerpayid
|
|
53
|
+
def create(virtual_account_id, **attributes)
|
|
54
|
+
validate_id!(virtual_account_id, 'virtual_account_id')
|
|
55
|
+
validate_create_attributes!(attributes)
|
|
56
|
+
|
|
57
|
+
body = build_create_body(attributes)
|
|
58
|
+
client.post("/virtual_accounts/#{virtual_account_id}/pay_ids", body: body)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Show a specific PayID
|
|
62
|
+
#
|
|
63
|
+
# @param pay_id_id [String] the PayID ID
|
|
64
|
+
# @return [Response] the API response containing PayID details
|
|
65
|
+
#
|
|
66
|
+
# @example Get PayID details
|
|
67
|
+
# pay_ids = ZaiPayment::Resources::PayId.new
|
|
68
|
+
# response = pay_ids.show('46deb476-c1a6-41eb-8eb7-26a695bbe5bc')
|
|
69
|
+
# response.data # => {"id" => "46deb476-c1a6-41eb-8eb7-26a695bbe5bc", ...}
|
|
70
|
+
#
|
|
71
|
+
# @see https://developer.hellozai.com/reference/retrieveapayid
|
|
72
|
+
def show(pay_id_id)
|
|
73
|
+
validate_id!(pay_id_id, 'pay_id_id')
|
|
74
|
+
client.get("/pay_ids/#{pay_id_id}")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Update Status for a PayID
|
|
78
|
+
#
|
|
79
|
+
# Update the status of a PayID. Currently, this endpoint only supports deregistering
|
|
80
|
+
# PayIDs by setting the status to 'deregistered'. This is an asynchronous operation
|
|
81
|
+
# that returns a 202 Accepted response.
|
|
82
|
+
#
|
|
83
|
+
# @param pay_id_id [String] the PayID ID
|
|
84
|
+
# @param status [String] the new status (must be 'deregistered')
|
|
85
|
+
# @return [Response] the API response containing the operation status
|
|
86
|
+
#
|
|
87
|
+
# @example Deregister a PayID
|
|
88
|
+
# pay_ids = ZaiPayment::Resources::PayId.new
|
|
89
|
+
# response = pay_ids.update_status(
|
|
90
|
+
# '46deb476-c1a6-41eb-8eb7-26a695bbe5bc',
|
|
91
|
+
# 'deregistered'
|
|
92
|
+
# )
|
|
93
|
+
# response.data # => {"id" => "46deb476-c1a6-41eb-8eb7-26a695bbe5bc", "message" => "...", ...}
|
|
94
|
+
#
|
|
95
|
+
# @see https://developer.hellozai.com/reference/updatepayidstatus
|
|
96
|
+
def update_status(pay_id_id, status)
|
|
97
|
+
validate_id!(pay_id_id, 'pay_id_id')
|
|
98
|
+
validate_status!(status)
|
|
99
|
+
|
|
100
|
+
body = { status: status }
|
|
101
|
+
client.patch("/pay_ids/#{pay_id_id}/status", body: body)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
private
|
|
105
|
+
|
|
106
|
+
def validate_id!(value, field_name)
|
|
107
|
+
return unless value.nil? || value.to_s.strip.empty?
|
|
108
|
+
|
|
109
|
+
raise Errors::ValidationError, "#{field_name} is required and cannot be blank"
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def validate_create_attributes!(attributes)
|
|
113
|
+
validate_pay_id!(attributes[:pay_id])
|
|
114
|
+
validate_type!(attributes[:type])
|
|
115
|
+
validate_details!(attributes[:details])
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def validate_pay_id!(pay_id)
|
|
119
|
+
if pay_id.nil? || pay_id.to_s.strip.empty?
|
|
120
|
+
raise Errors::ValidationError, 'pay_id is required and cannot be blank'
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
return unless pay_id.to_s.length > 256
|
|
124
|
+
|
|
125
|
+
raise Errors::ValidationError, 'pay_id must be 256 characters or less'
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def validate_type!(type)
|
|
129
|
+
raise Errors::ValidationError, 'type is required and cannot be blank' if type.nil? || type.to_s.strip.empty?
|
|
130
|
+
|
|
131
|
+
return if VALID_TYPES.include?(type.to_s.upcase)
|
|
132
|
+
|
|
133
|
+
raise Errors::ValidationError,
|
|
134
|
+
"type must be one of: #{VALID_TYPES.join(', ')}, got '#{type}'"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def validate_details!(details)
|
|
138
|
+
raise Errors::ValidationError, 'details is required and must be a hash' if details.nil? || !details.is_a?(Hash)
|
|
139
|
+
|
|
140
|
+
validate_pay_id_name!(details[:pay_id_name])
|
|
141
|
+
validate_owner_legal_name!(details[:owner_legal_name])
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def validate_pay_id_name!(pay_id_name)
|
|
145
|
+
return unless pay_id_name
|
|
146
|
+
|
|
147
|
+
raise Errors::ValidationError, 'pay_id_name cannot be empty when provided' if pay_id_name.to_s.empty?
|
|
148
|
+
|
|
149
|
+
return unless pay_id_name.to_s.length > 140
|
|
150
|
+
|
|
151
|
+
raise Errors::ValidationError, 'pay_id_name must be between 1 and 140 characters'
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def validate_owner_legal_name!(owner_legal_name)
|
|
155
|
+
return unless owner_legal_name
|
|
156
|
+
|
|
157
|
+
raise Errors::ValidationError, 'owner_legal_name cannot be empty when provided' if owner_legal_name.to_s.empty?
|
|
158
|
+
|
|
159
|
+
return unless owner_legal_name.to_s.length > 140
|
|
160
|
+
|
|
161
|
+
raise Errors::ValidationError, 'owner_legal_name must be between 1 and 140 characters'
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def validate_status!(status)
|
|
165
|
+
raise Errors::ValidationError, 'status cannot be blank' if status.nil? || status.to_s.strip.empty?
|
|
166
|
+
|
|
167
|
+
return if VALID_STATUSES.include?(status.to_s)
|
|
168
|
+
|
|
169
|
+
raise Errors::ValidationError,
|
|
170
|
+
"status must be 'deregistered', got '#{status}'"
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# rubocop:disable Metrics/AbcSize
|
|
174
|
+
def build_create_body(attributes)
|
|
175
|
+
body = {}
|
|
176
|
+
|
|
177
|
+
# Add pay_id
|
|
178
|
+
body[:pay_id] = attributes[:pay_id] if attributes[:pay_id]
|
|
179
|
+
|
|
180
|
+
# Add type (convert to uppercase to match API expectations)
|
|
181
|
+
body[:type] = attributes[:type].to_s.upcase if attributes[:type]
|
|
182
|
+
|
|
183
|
+
# Add details
|
|
184
|
+
if attributes[:details].is_a?(Hash)
|
|
185
|
+
body[:details] = {}
|
|
186
|
+
details = attributes[:details]
|
|
187
|
+
|
|
188
|
+
body[:details][:pay_id_name] = details[:pay_id_name] if details[:pay_id_name]
|
|
189
|
+
body[:details][:owner_legal_name] = details[:owner_legal_name] if details[:owner_legal_name]
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
body
|
|
193
|
+
end
|
|
194
|
+
# rubocop:enable Metrics/AbcSize
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|