paystack-gateway 0.1.1 → 0.2.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/.rubocop.yml +12 -2
- data/CHANGELOG.md +57 -0
- data/README.md +81 -102
- data/lib/paystack_gateway/api_error.rb +3 -1
- data/lib/paystack_gateway/apple_pay.rb +92 -0
- data/lib/paystack_gateway/balance.rb +62 -0
- data/lib/paystack_gateway/bank.rb +181 -0
- data/lib/paystack_gateway/bulk_charge.rb +197 -0
- data/lib/paystack_gateway/charge.rb +346 -0
- data/lib/paystack_gateway/configuration.rb +13 -2
- data/lib/paystack_gateway/customer.rb +498 -0
- data/lib/paystack_gateway/customers.rb +1 -42
- data/lib/paystack_gateway/dedicated_virtual_account.rb +353 -0
- data/lib/paystack_gateway/dedicated_virtual_accounts.rb +1 -64
- data/lib/paystack_gateway/direct_debit.rb +64 -0
- data/lib/paystack_gateway/dispute.rb +380 -0
- data/lib/paystack_gateway/extensions/customer_extensions.rb +14 -0
- data/lib/paystack_gateway/extensions/plan_extensions.rb +36 -0
- data/lib/paystack_gateway/extensions/refund_extensions.rb +43 -0
- data/lib/paystack_gateway/extensions/transaction_extensions.rb +40 -0
- data/lib/paystack_gateway/extensions/transaction_response_extension.rb +31 -0
- data/lib/paystack_gateway/extensions/transfer_extensions.rb +34 -0
- data/lib/paystack_gateway/integration.rb +60 -0
- data/lib/paystack_gateway/legacy/customers.rb +48 -0
- data/lib/paystack_gateway/legacy/dedicated_virtual_accounts.rb +70 -0
- data/lib/paystack_gateway/legacy/miscellaneous.rb +30 -0
- data/lib/paystack_gateway/legacy/plans.rb +86 -0
- data/lib/paystack_gateway/legacy/refunds.rb +65 -0
- data/lib/paystack_gateway/legacy/subaccounts.rb +41 -0
- data/lib/paystack_gateway/legacy/transaction_response.rb +37 -0
- data/lib/paystack_gateway/legacy/transactions.rb +91 -0
- data/lib/paystack_gateway/legacy/transfer_recipients.rb +27 -0
- data/lib/paystack_gateway/legacy/transfers.rb +63 -0
- data/lib/paystack_gateway/legacy/verification.rb +37 -0
- data/lib/paystack_gateway/miscellaneous.rb +75 -13
- data/lib/paystack_gateway/order.rb +259 -0
- data/lib/paystack_gateway/page.rb +317 -0
- data/lib/paystack_gateway/payment_request.rb +454 -0
- data/lib/paystack_gateway/plan.rb +247 -0
- data/lib/paystack_gateway/plans.rb +1 -80
- data/lib/paystack_gateway/product.rb +303 -0
- data/lib/paystack_gateway/refund.rb +197 -0
- data/lib/paystack_gateway/refunds.rb +1 -59
- data/lib/paystack_gateway/request_module.rb +12 -11
- data/lib/paystack_gateway/settlement.rb +60 -0
- data/lib/paystack_gateway/split.rb +286 -0
- data/lib/paystack_gateway/storefront.rb +329 -0
- data/lib/paystack_gateway/subaccount.rb +263 -0
- data/lib/paystack_gateway/subaccounts.rb +1 -35
- data/lib/paystack_gateway/subscription.rb +256 -0
- data/lib/paystack_gateway/terminal.rb +236 -0
- data/lib/paystack_gateway/transaction.rb +592 -0
- data/lib/paystack_gateway/transaction_response.rb +1 -33
- data/lib/paystack_gateway/transactions.rb +1 -86
- data/lib/paystack_gateway/transfer.rb +410 -0
- data/lib/paystack_gateway/transfer_recipient.rb +237 -0
- data/lib/paystack_gateway/transfer_recipients.rb +1 -21
- data/lib/paystack_gateway/transfers.rb +1 -57
- data/lib/paystack_gateway/verification.rb +1 -31
- data/lib/paystack_gateway/version.rb +1 -1
- data/lib/paystack_gateway/virtual_terminal.rb +297 -0
- data/lib/paystack_gateway.rb +50 -18
- metadata +50 -7
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PaystackGateway
|
|
4
|
+
# https://paystack.com/docs/api/dispute
|
|
5
|
+
#
|
|
6
|
+
# Disputes
|
|
7
|
+
# A collection of endpoints for managing transactions complaint made by customers
|
|
8
|
+
module Dispute
|
|
9
|
+
include PaystackGateway::RequestModule
|
|
10
|
+
|
|
11
|
+
# Successful response from calling #list.
|
|
12
|
+
class ListResponse < PaystackGateway::Response; end
|
|
13
|
+
|
|
14
|
+
# Error response from #list.
|
|
15
|
+
class ListError < ApiError; end
|
|
16
|
+
|
|
17
|
+
# https://paystack.com/docs/api/dispute/#list
|
|
18
|
+
# List Disputes: GET /dispute
|
|
19
|
+
# List transaction disputes filed by customers
|
|
20
|
+
#
|
|
21
|
+
# @param per_page [Integer]
|
|
22
|
+
# Number of records to fetch per page
|
|
23
|
+
# @param page [Integer]
|
|
24
|
+
# The section to retrieve
|
|
25
|
+
# @param status ["awaiting-merchant-feedback", "awaiting-bank-feedback", "pending", "resolved"]
|
|
26
|
+
# Dispute status
|
|
27
|
+
# @param transaction [String]
|
|
28
|
+
# Transaction ID
|
|
29
|
+
# @param from [Time]
|
|
30
|
+
# The start date
|
|
31
|
+
# @param to [Time]
|
|
32
|
+
# The end date
|
|
33
|
+
#
|
|
34
|
+
# @return [ListResponse] successful response
|
|
35
|
+
# @raise [ListError] if the request fails
|
|
36
|
+
api_method def self.list(
|
|
37
|
+
per_page: nil,
|
|
38
|
+
page: nil,
|
|
39
|
+
status: nil,
|
|
40
|
+
transaction: nil,
|
|
41
|
+
from: nil,
|
|
42
|
+
to: nil
|
|
43
|
+
)
|
|
44
|
+
use_connection do |connection|
|
|
45
|
+
connection.get(
|
|
46
|
+
'/dispute',
|
|
47
|
+
{
|
|
48
|
+
perPage: per_page,
|
|
49
|
+
page:,
|
|
50
|
+
status:,
|
|
51
|
+
transaction:,
|
|
52
|
+
from:,
|
|
53
|
+
to:,
|
|
54
|
+
}.compact,
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Successful response from calling #fetch.
|
|
60
|
+
class FetchResponse < PaystackGateway::Response
|
|
61
|
+
delegate :id,
|
|
62
|
+
:refund_amount,
|
|
63
|
+
:currency,
|
|
64
|
+
:resolution,
|
|
65
|
+
:domain,
|
|
66
|
+
:transaction,
|
|
67
|
+
:transaction_reference,
|
|
68
|
+
:category,
|
|
69
|
+
:customer,
|
|
70
|
+
:bin,
|
|
71
|
+
:last4,
|
|
72
|
+
:dueAt,
|
|
73
|
+
:resolvedAt,
|
|
74
|
+
:evidence,
|
|
75
|
+
:attachments,
|
|
76
|
+
:note,
|
|
77
|
+
:history,
|
|
78
|
+
:messages,
|
|
79
|
+
:createdAt,
|
|
80
|
+
:updatedAt, to: :data
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Error response from #fetch.
|
|
84
|
+
class FetchError < ApiError; end
|
|
85
|
+
|
|
86
|
+
# https://paystack.com/docs/api/dispute/#fetch
|
|
87
|
+
# Fetch Dispute: GET /dispute/{id}
|
|
88
|
+
# Fetch a transaction dispute
|
|
89
|
+
#
|
|
90
|
+
# @param id [Integer] (required)
|
|
91
|
+
# The unique identifier of the dispute
|
|
92
|
+
#
|
|
93
|
+
# @return [FetchResponse] successful response
|
|
94
|
+
# @raise [FetchError] if the request fails
|
|
95
|
+
api_method def self.fetch(id:)
|
|
96
|
+
use_connection do |connection|
|
|
97
|
+
connection.get(
|
|
98
|
+
"/dispute/#{id}",
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Successful response from calling #update.
|
|
104
|
+
class UpdateResponse < PaystackGateway::Response
|
|
105
|
+
delegate :id,
|
|
106
|
+
:refund_amount,
|
|
107
|
+
:currency,
|
|
108
|
+
:resolution,
|
|
109
|
+
:domain,
|
|
110
|
+
:transaction,
|
|
111
|
+
:transaction_reference,
|
|
112
|
+
:category,
|
|
113
|
+
:customer,
|
|
114
|
+
:bin,
|
|
115
|
+
:last4,
|
|
116
|
+
:dueAt,
|
|
117
|
+
:resolvedAt,
|
|
118
|
+
:evidence,
|
|
119
|
+
:attachments,
|
|
120
|
+
:note,
|
|
121
|
+
:history,
|
|
122
|
+
:messages,
|
|
123
|
+
:createdAt,
|
|
124
|
+
:updatedAt, to: :data
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Error response from #update.
|
|
128
|
+
class UpdateError < ApiError; end
|
|
129
|
+
|
|
130
|
+
# https://paystack.com/docs/api/dispute/#update
|
|
131
|
+
# Update Dispute: PUT /dispute/{id}
|
|
132
|
+
# Update a transaction dispute
|
|
133
|
+
#
|
|
134
|
+
# @param id [Integer] (required)
|
|
135
|
+
# The unique identifier of the dispute
|
|
136
|
+
# @param refund_amount [Integer] (required)
|
|
137
|
+
# The amount to refund, in the subunit of your currency
|
|
138
|
+
# @param uploaded_filename [String]
|
|
139
|
+
# Filename of attachment returned via response from the Dispute upload URL
|
|
140
|
+
#
|
|
141
|
+
# @return [UpdateResponse] successful response
|
|
142
|
+
# @raise [UpdateError] if the request fails
|
|
143
|
+
api_method def self.update(id:, refund_amount:, uploaded_filename: nil)
|
|
144
|
+
use_connection do |connection|
|
|
145
|
+
connection.put(
|
|
146
|
+
"/dispute/#{id}",
|
|
147
|
+
{ refund_amount:, uploaded_filename: }.compact,
|
|
148
|
+
)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Successful response from calling #upload_url.
|
|
153
|
+
class UploadUrlResponse < PaystackGateway::Response
|
|
154
|
+
delegate :signedUrl, :fileName, to: :data
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Error response from #upload_url.
|
|
158
|
+
class UploadUrlError < ApiError; end
|
|
159
|
+
|
|
160
|
+
# https://paystack.com/docs/api/dispute/#upload_url
|
|
161
|
+
# Fetch Upload URL: GET /dispute/{id}/upload_url
|
|
162
|
+
# Get the URL to upload a dispute evidence
|
|
163
|
+
#
|
|
164
|
+
# @param id [Integer] (required)
|
|
165
|
+
# The unique identifier of the dispute
|
|
166
|
+
#
|
|
167
|
+
# @return [UploadUrlResponse] successful response
|
|
168
|
+
# @raise [UploadUrlError] if the request fails
|
|
169
|
+
api_method def self.upload_url(id:)
|
|
170
|
+
use_connection do |connection|
|
|
171
|
+
connection.get(
|
|
172
|
+
"/dispute/#{id}/upload_url",
|
|
173
|
+
)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Successful response from calling #download.
|
|
178
|
+
class DownloadResponse < PaystackGateway::Response
|
|
179
|
+
delegate :path, :expiresAt, to: :data
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Error response from #download.
|
|
183
|
+
class DownloadError < ApiError; end
|
|
184
|
+
|
|
185
|
+
# https://paystack.com/docs/api/dispute/#download
|
|
186
|
+
# Export Disputes: GET /dispute/export
|
|
187
|
+
# Export the disputes available on your integration
|
|
188
|
+
#
|
|
189
|
+
# @param per_page [Integer]
|
|
190
|
+
# Number of records to fetch per page
|
|
191
|
+
# @param page [Integer]
|
|
192
|
+
# The section to retrieve
|
|
193
|
+
# @param status ["awaiting-merchant-feedback", "awaiting-bank-feedback", "pending", "resolved"]
|
|
194
|
+
# @param from [Time]
|
|
195
|
+
# The start date
|
|
196
|
+
# @param to [Time]
|
|
197
|
+
# The end date
|
|
198
|
+
#
|
|
199
|
+
# @return [DownloadResponse] successful response
|
|
200
|
+
# @raise [DownloadError] if the request fails
|
|
201
|
+
api_method def self.download(per_page: nil, page: nil, status: nil, from: nil, to: nil)
|
|
202
|
+
use_connection do |connection|
|
|
203
|
+
connection.get(
|
|
204
|
+
'/dispute/export',
|
|
205
|
+
{ perPage: per_page, page:, status:, from:, to: }.compact,
|
|
206
|
+
)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Successful response from calling #transaction.
|
|
211
|
+
class TransactionResponse < PaystackGateway::Response
|
|
212
|
+
delegate :history,
|
|
213
|
+
:messages,
|
|
214
|
+
:currency,
|
|
215
|
+
:last4,
|
|
216
|
+
:bin,
|
|
217
|
+
:transaction_reference,
|
|
218
|
+
:merchant_transaction_reference,
|
|
219
|
+
:refund_amount,
|
|
220
|
+
:domain,
|
|
221
|
+
:resolution,
|
|
222
|
+
:category,
|
|
223
|
+
:note,
|
|
224
|
+
:attachments,
|
|
225
|
+
:id,
|
|
226
|
+
:integration,
|
|
227
|
+
:transaction,
|
|
228
|
+
:created_by,
|
|
229
|
+
:evidence,
|
|
230
|
+
:resolvedAt,
|
|
231
|
+
:createdAt,
|
|
232
|
+
:updatedAt,
|
|
233
|
+
:dueAt, to: :data
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Error response from #transaction.
|
|
237
|
+
class TransactionError < ApiError; end
|
|
238
|
+
|
|
239
|
+
# https://paystack.com/docs/api/dispute/#transaction
|
|
240
|
+
# List Transaction Disputes: GET /dispute/transaction/{id}
|
|
241
|
+
# List all disputes filed for a transaction
|
|
242
|
+
#
|
|
243
|
+
# @param id [Integer] (required)
|
|
244
|
+
# The unique identifier of the transaction
|
|
245
|
+
#
|
|
246
|
+
# @return [TransactionResponse] successful response
|
|
247
|
+
# @raise [TransactionError] if the request fails
|
|
248
|
+
api_method def self.transaction(id:)
|
|
249
|
+
use_connection do |connection|
|
|
250
|
+
connection.get(
|
|
251
|
+
"/dispute/transaction/#{id}",
|
|
252
|
+
)
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Successful response from calling #resolve.
|
|
257
|
+
class ResolveResponse < PaystackGateway::Response
|
|
258
|
+
delegate :currency,
|
|
259
|
+
:last4,
|
|
260
|
+
:bin,
|
|
261
|
+
:transaction_reference,
|
|
262
|
+
:merchant_transaction_reference,
|
|
263
|
+
:refund_amount,
|
|
264
|
+
:domain,
|
|
265
|
+
:resolution,
|
|
266
|
+
:category,
|
|
267
|
+
:note,
|
|
268
|
+
:attachments,
|
|
269
|
+
:id,
|
|
270
|
+
:integration,
|
|
271
|
+
:transaction,
|
|
272
|
+
:created_by,
|
|
273
|
+
:evidence,
|
|
274
|
+
:resolvedAt,
|
|
275
|
+
:createdAt,
|
|
276
|
+
:updatedAt,
|
|
277
|
+
:dueAt, to: :data
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
# Error response from #resolve.
|
|
281
|
+
class ResolveError < ApiError; end
|
|
282
|
+
|
|
283
|
+
# https://paystack.com/docs/api/dispute/#resolve
|
|
284
|
+
# Resolve Dispute: PUT /dispute/{id}/resolve
|
|
285
|
+
# Resolve a transaction dispute
|
|
286
|
+
#
|
|
287
|
+
# @param id [Integer] (required)
|
|
288
|
+
# The unique identifier of the dispute
|
|
289
|
+
# @param resolution [String] (required)
|
|
290
|
+
# Dispute resolution. Accepted values, merchant-accepted, declined
|
|
291
|
+
# @param message [String] (required)
|
|
292
|
+
# Reason for resolving
|
|
293
|
+
# @param refund_amount [Integer] (required)
|
|
294
|
+
# The amount to refund, in the subunit of your integration currency
|
|
295
|
+
# @param uploaded_filename [String] (required)
|
|
296
|
+
# Filename of attachment returned via response from the Dispute upload URL
|
|
297
|
+
# @param evidence [Integer]
|
|
298
|
+
# Evidence Id for fraud claims
|
|
299
|
+
#
|
|
300
|
+
# @return [ResolveResponse] successful response
|
|
301
|
+
# @raise [ResolveError] if the request fails
|
|
302
|
+
api_method def self.resolve(
|
|
303
|
+
id:,
|
|
304
|
+
resolution:,
|
|
305
|
+
message:,
|
|
306
|
+
refund_amount:,
|
|
307
|
+
uploaded_filename:,
|
|
308
|
+
evidence: nil
|
|
309
|
+
)
|
|
310
|
+
use_connection do |connection|
|
|
311
|
+
connection.put(
|
|
312
|
+
"/dispute/#{id}/resolve",
|
|
313
|
+
{ resolution:, message:, refund_amount:, uploaded_filename:, evidence: }.compact,
|
|
314
|
+
)
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Successful response from calling #evidence.
|
|
319
|
+
class EvidenceResponse < PaystackGateway::Response
|
|
320
|
+
delegate :customer_email,
|
|
321
|
+
:customer_name,
|
|
322
|
+
:customer_phone,
|
|
323
|
+
:service_details,
|
|
324
|
+
:delivery_address,
|
|
325
|
+
:delivery_date,
|
|
326
|
+
:dispute,
|
|
327
|
+
:id,
|
|
328
|
+
:createdAt,
|
|
329
|
+
:updatedAt, to: :data
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# Error response from #evidence.
|
|
333
|
+
class EvidenceError < ApiError; end
|
|
334
|
+
|
|
335
|
+
# https://paystack.com/docs/api/dispute/#evidence
|
|
336
|
+
# Add Evidence: POST /dispute/{id}/evidence
|
|
337
|
+
# Provide evidence for a dispute
|
|
338
|
+
#
|
|
339
|
+
# @param id [Integer] (required)
|
|
340
|
+
# The unique identifier of the dispute
|
|
341
|
+
# @param customer_email [String] (required)
|
|
342
|
+
# Customer email
|
|
343
|
+
# @param customer_name [String] (required)
|
|
344
|
+
# Customer name
|
|
345
|
+
# @param customer_phone [String] (required)
|
|
346
|
+
# Customer mobile number
|
|
347
|
+
# @param service_details [String] (required)
|
|
348
|
+
# Details of service offered
|
|
349
|
+
# @param delivery_address [String]
|
|
350
|
+
# Delivery address
|
|
351
|
+
# @param delivery_date [Time]
|
|
352
|
+
# ISO 8601 representation of delivery date (YYYY-MM-DD)
|
|
353
|
+
#
|
|
354
|
+
# @return [EvidenceResponse] successful response
|
|
355
|
+
# @raise [EvidenceError] if the request fails
|
|
356
|
+
api_method def self.evidence(
|
|
357
|
+
id:,
|
|
358
|
+
customer_email:,
|
|
359
|
+
customer_name:,
|
|
360
|
+
customer_phone:,
|
|
361
|
+
service_details:,
|
|
362
|
+
delivery_address: nil,
|
|
363
|
+
delivery_date: nil
|
|
364
|
+
)
|
|
365
|
+
use_connection do |connection|
|
|
366
|
+
connection.post(
|
|
367
|
+
"/dispute/#{id}/evidence",
|
|
368
|
+
{
|
|
369
|
+
customer_email:,
|
|
370
|
+
customer_name:,
|
|
371
|
+
customer_phone:,
|
|
372
|
+
service_details:,
|
|
373
|
+
delivery_address:,
|
|
374
|
+
delivery_date:,
|
|
375
|
+
}.compact,
|
|
376
|
+
)
|
|
377
|
+
end
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return if !PaystackGateway.use_extensions
|
|
4
|
+
|
|
5
|
+
module PaystackGateway
|
|
6
|
+
module Customer
|
|
7
|
+
# Helpers for PaystackGateway::Customer::FetchResponse
|
|
8
|
+
class FetchResponse
|
|
9
|
+
def active_subscriptions = subscriptions.select { _1.status == 'active' }
|
|
10
|
+
def active_subscription_codes = active_subscriptions.map(&:subscription_code)
|
|
11
|
+
def reusable_authorizations = authorizations.select(&:reusable)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return if !PaystackGateway.use_extensions
|
|
4
|
+
|
|
5
|
+
module PaystackGateway
|
|
6
|
+
module Plan
|
|
7
|
+
# Helpers for PaystackGateway::Plan::CreateResponse
|
|
8
|
+
class CreateResponse
|
|
9
|
+
def plan_id = data.id
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Helpers for PaystackGateway::Plan::ListResponse
|
|
13
|
+
class ListResponse
|
|
14
|
+
def active_plans = data.select { |plan| !plan.is_deleted && !plan.is_archived }
|
|
15
|
+
|
|
16
|
+
def find_active_plan_by_name(name)
|
|
17
|
+
active_plans.sort_by { -Time.parse(_1.createdAt).to_i }.find { _1.name == name }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Helpers for PaystackGateway::Plan::FetchResponse
|
|
22
|
+
class FetchResponse
|
|
23
|
+
def active_subscriptions = subscriptions.select { _1.status.to_sym == :active }
|
|
24
|
+
|
|
25
|
+
def active_subscription_codes(email: nil)
|
|
26
|
+
subscriptions =
|
|
27
|
+
if email
|
|
28
|
+
active_subscriptions.select { _1.customer.email.casecmp?(email) }
|
|
29
|
+
else
|
|
30
|
+
active_subscriptions
|
|
31
|
+
end
|
|
32
|
+
subscriptions.map(&:subscription_code)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return if !PaystackGateway.use_extensions
|
|
4
|
+
|
|
5
|
+
require_relative 'transaction_response_extension'
|
|
6
|
+
|
|
7
|
+
module PaystackGateway
|
|
8
|
+
module Refund
|
|
9
|
+
# Helpers for PaystackGateway::Refund::ListResponse
|
|
10
|
+
class ListResponse
|
|
11
|
+
def pending_or_successful
|
|
12
|
+
filtered = data.select { _1.status&.to_sym.in?(%i[processed pending processing]) }
|
|
13
|
+
|
|
14
|
+
ListResponse.new({ **self, data: filtered })
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def with_amount(amount)
|
|
18
|
+
filtered = data.select { _1.amount == amount * 100 }
|
|
19
|
+
|
|
20
|
+
ListResponse.new({ **self, data: filtered })
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Helpers for responses from refunds endpoints
|
|
25
|
+
module TransactionRefundResponse
|
|
26
|
+
include PaystackGateway::Extensions::TransactionResponseExtension
|
|
27
|
+
|
|
28
|
+
def refund_success? = transaction_status == :processed
|
|
29
|
+
def refund_failed? = transaction_status == :failed
|
|
30
|
+
def refund_pending? = transaction_status.in?(%i[pending processing])
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Helpers for PaystackGateway::Refund::CreateResponse
|
|
34
|
+
class CreateResponse
|
|
35
|
+
include TransactionRefundResponse
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Helpers for PaystackGateway::Refund::FetchResponse
|
|
39
|
+
class FetchResponse
|
|
40
|
+
include TransactionRefundResponse
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return if !PaystackGateway.use_extensions
|
|
4
|
+
|
|
5
|
+
require_relative 'transaction_response_extension'
|
|
6
|
+
|
|
7
|
+
module PaystackGateway
|
|
8
|
+
module Transaction
|
|
9
|
+
# Helpers for PaystackGateway::Transaction::InitializeTransactionResponse
|
|
10
|
+
class InitializeTransactionResponse
|
|
11
|
+
def payment_url
|
|
12
|
+
authorization_url
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Helpers for PaystackGateway::Transaction::InitializeTransactionError
|
|
17
|
+
class InitializeTransactionError
|
|
18
|
+
def cancellable? = network_error?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Helpers for PaystackGateway::Transaction::VerifyResponse
|
|
22
|
+
class VerifyResponse
|
|
23
|
+
include PaystackGateway::Extensions::TransactionResponseExtension
|
|
24
|
+
|
|
25
|
+
def transaction_completed_at = paid_at || super
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Helpers for PaystackGateway::Transaction::VerifyError
|
|
29
|
+
class VerifyError
|
|
30
|
+
def transaction_not_found?
|
|
31
|
+
parsed_response_body[:status] == false &&
|
|
32
|
+
parsed_response_body[:message]&.match?(/transaction reference not found/i)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
class ChargeAuthorizationResponse
|
|
37
|
+
include PaystackGateway::Extensions::TransactionResponseExtension
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bigdecimal'
|
|
4
|
+
|
|
5
|
+
module PaystackGateway
|
|
6
|
+
module Extensions
|
|
7
|
+
# Helpers for various responses around transactions.
|
|
8
|
+
module TransactionResponseExtension
|
|
9
|
+
def transaction_success? = %i[success reversed reversal_pending].include?(transaction_status)
|
|
10
|
+
def transaction_abandoned? = transaction_status == :abandoned
|
|
11
|
+
def transaction_failed? = transaction_status == :failed
|
|
12
|
+
def transaction_pending? = %i[pending ongoing].include?(transaction_status)
|
|
13
|
+
|
|
14
|
+
def transaction_status = data.status.to_sym
|
|
15
|
+
def transaction_amount_in_major_units = amount / BigDecimal(100)
|
|
16
|
+
def transaction_completed_at = data[:updatedAt]
|
|
17
|
+
|
|
18
|
+
def subaccount_amount_in_major_units
|
|
19
|
+
return if !subaccount || !fees_split
|
|
20
|
+
|
|
21
|
+
fees_split.subaccount / BigDecimal(100)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def failure_reason
|
|
25
|
+
return if !transaction_failed? && !transaction_abandoned?
|
|
26
|
+
|
|
27
|
+
data.gateway_response || transaction_status || message
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
return if !PaystackGateway.use_extensions
|
|
4
|
+
|
|
5
|
+
require_relative 'transaction_response_extension'
|
|
6
|
+
|
|
7
|
+
module PaystackGateway
|
|
8
|
+
module Transfer
|
|
9
|
+
# Helpers for PaystackGateway::Transfer::InitiateResponse
|
|
10
|
+
class InitiateResponse
|
|
11
|
+
include PaystackGateway::Extensions::TransactionResponseExtension
|
|
12
|
+
|
|
13
|
+
def transaction_completed_at = transferred_at || super
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Helpers for PaystackGateway::Transfer::InitiateError
|
|
17
|
+
class InitiateError
|
|
18
|
+
def transaction_failed? = parsed_response_body[:status] == false && http_code == 400
|
|
19
|
+
def failure_reason = parsed_response_body[:message]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Helpers for PaystackGateway::Transfer::VerifyResponse
|
|
23
|
+
class VerifyResponse
|
|
24
|
+
def transaction_completed_at = transferred_at || super
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Helpers for PaystackGateway::Transfer::VerifyError
|
|
28
|
+
class VerifyError
|
|
29
|
+
def transaction_not_found?
|
|
30
|
+
parsed_response_body[:status] == false && parsed_response_body[:message]&.match?(/transfer not found/i)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PaystackGateway
|
|
4
|
+
# https://paystack.com/docs/api/integration
|
|
5
|
+
#
|
|
6
|
+
# Integration
|
|
7
|
+
# A collection of endpoints for managing some settings on an integration
|
|
8
|
+
module Integration
|
|
9
|
+
include PaystackGateway::RequestModule
|
|
10
|
+
|
|
11
|
+
# Successful response from calling #fetch_payment_session_timeout.
|
|
12
|
+
class FetchPaymentSessionTimeoutResponse < PaystackGateway::Response
|
|
13
|
+
delegate :payment_session_timeout, to: :data
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Error response from #fetch_payment_session_timeout.
|
|
17
|
+
class FetchPaymentSessionTimeoutError < ApiError; end
|
|
18
|
+
|
|
19
|
+
# https://paystack.com/docs/api/integration/#fetch_payment_session_timeout
|
|
20
|
+
# Fetch Payment Session Timeout: GET /integration/payment_session_timeout
|
|
21
|
+
# Fetch the session timeout of a transaction
|
|
22
|
+
#
|
|
23
|
+
#
|
|
24
|
+
# @return [FetchPaymentSessionTimeoutResponse] successful response
|
|
25
|
+
# @raise [FetchPaymentSessionTimeoutError] if the request fails
|
|
26
|
+
api_method def self.fetch_payment_session_timeout
|
|
27
|
+
use_connection do |connection|
|
|
28
|
+
connection.get(
|
|
29
|
+
'/integration/payment_session_timeout',
|
|
30
|
+
)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Successful response from calling #update_payment_session_timeout.
|
|
35
|
+
class UpdatePaymentSessionTimeoutResponse < PaystackGateway::Response
|
|
36
|
+
delegate :payment_session_timeout, to: :data
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Error response from #update_payment_session_timeout.
|
|
40
|
+
class UpdatePaymentSessionTimeoutError < ApiError; end
|
|
41
|
+
|
|
42
|
+
# https://paystack.com/docs/api/integration/#update_payment_session_timeout
|
|
43
|
+
# Update Payment Session Timeout: PUT /integration/payment_session_timeout
|
|
44
|
+
# Update the session timeout of a transaction
|
|
45
|
+
#
|
|
46
|
+
# @param timeout [Integer] (required)
|
|
47
|
+
# Time in seconds before a transaction becomes invalid
|
|
48
|
+
#
|
|
49
|
+
# @return [UpdatePaymentSessionTimeoutResponse] successful response
|
|
50
|
+
# @raise [UpdatePaymentSessionTimeoutError] if the request fails
|
|
51
|
+
api_method def self.update_payment_session_timeout(timeout:)
|
|
52
|
+
use_connection do |connection|
|
|
53
|
+
connection.put(
|
|
54
|
+
'/integration/payment_session_timeout',
|
|
55
|
+
{ timeout: }.compact,
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Legacy implementation retained for backwards compatibility.
|
|
4
|
+
|
|
5
|
+
module PaystackGateway
|
|
6
|
+
# Create and manage customers https://paystack.com/docs/api/customer/
|
|
7
|
+
#
|
|
8
|
+
# @deprecated Use PaystackGateway::Customer instead.
|
|
9
|
+
module Customers
|
|
10
|
+
include PaystackGateway::RequestModule
|
|
11
|
+
|
|
12
|
+
# Common helpers for response from customer endpoints
|
|
13
|
+
module CustomerResponse
|
|
14
|
+
extend ActiveSupport::Concern
|
|
15
|
+
|
|
16
|
+
included do
|
|
17
|
+
delegate :id, :customer_code, to: :data
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class CreateCustomerResponse < PaystackGateway::Response
|
|
22
|
+
include CustomerResponse
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
api_method def self.create_customer(email:, first_name:, last_name:)
|
|
26
|
+
use_connection do |connection|
|
|
27
|
+
connection.post('/customer', { email:, first_name:, last_name: })
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Response from GET /customer/:email_or_id
|
|
32
|
+
class FetchCustomerResponse < PaystackGateway::Response
|
|
33
|
+
include CustomerResponse
|
|
34
|
+
|
|
35
|
+
delegate :subscriptions, :authorizations, to: :data
|
|
36
|
+
|
|
37
|
+
def active_subscriptions = subscriptions.select { _1.status == 'active' }
|
|
38
|
+
def active_subscription_codes = active_subscriptions.map(&:subscription_code)
|
|
39
|
+
def reusable_authorizations = authorizations.select(&:reusable)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
api_method def self.fetch_customer(email:)
|
|
43
|
+
use_connection do |connection|
|
|
44
|
+
connection.get("/customer/#{email}")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|