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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +12 -2
  3. data/CHANGELOG.md +57 -0
  4. data/README.md +81 -102
  5. data/lib/paystack_gateway/api_error.rb +3 -1
  6. data/lib/paystack_gateway/apple_pay.rb +92 -0
  7. data/lib/paystack_gateway/balance.rb +62 -0
  8. data/lib/paystack_gateway/bank.rb +181 -0
  9. data/lib/paystack_gateway/bulk_charge.rb +197 -0
  10. data/lib/paystack_gateway/charge.rb +346 -0
  11. data/lib/paystack_gateway/configuration.rb +13 -2
  12. data/lib/paystack_gateway/customer.rb +498 -0
  13. data/lib/paystack_gateway/customers.rb +1 -42
  14. data/lib/paystack_gateway/dedicated_virtual_account.rb +353 -0
  15. data/lib/paystack_gateway/dedicated_virtual_accounts.rb +1 -64
  16. data/lib/paystack_gateway/direct_debit.rb +64 -0
  17. data/lib/paystack_gateway/dispute.rb +380 -0
  18. data/lib/paystack_gateway/extensions/customer_extensions.rb +14 -0
  19. data/lib/paystack_gateway/extensions/plan_extensions.rb +36 -0
  20. data/lib/paystack_gateway/extensions/refund_extensions.rb +43 -0
  21. data/lib/paystack_gateway/extensions/transaction_extensions.rb +40 -0
  22. data/lib/paystack_gateway/extensions/transaction_response_extension.rb +31 -0
  23. data/lib/paystack_gateway/extensions/transfer_extensions.rb +34 -0
  24. data/lib/paystack_gateway/integration.rb +60 -0
  25. data/lib/paystack_gateway/legacy/customers.rb +48 -0
  26. data/lib/paystack_gateway/legacy/dedicated_virtual_accounts.rb +70 -0
  27. data/lib/paystack_gateway/legacy/miscellaneous.rb +30 -0
  28. data/lib/paystack_gateway/legacy/plans.rb +86 -0
  29. data/lib/paystack_gateway/legacy/refunds.rb +65 -0
  30. data/lib/paystack_gateway/legacy/subaccounts.rb +41 -0
  31. data/lib/paystack_gateway/legacy/transaction_response.rb +37 -0
  32. data/lib/paystack_gateway/legacy/transactions.rb +91 -0
  33. data/lib/paystack_gateway/legacy/transfer_recipients.rb +27 -0
  34. data/lib/paystack_gateway/legacy/transfers.rb +63 -0
  35. data/lib/paystack_gateway/legacy/verification.rb +37 -0
  36. data/lib/paystack_gateway/miscellaneous.rb +75 -13
  37. data/lib/paystack_gateway/order.rb +259 -0
  38. data/lib/paystack_gateway/page.rb +317 -0
  39. data/lib/paystack_gateway/payment_request.rb +454 -0
  40. data/lib/paystack_gateway/plan.rb +247 -0
  41. data/lib/paystack_gateway/plans.rb +1 -80
  42. data/lib/paystack_gateway/product.rb +303 -0
  43. data/lib/paystack_gateway/refund.rb +197 -0
  44. data/lib/paystack_gateway/refunds.rb +1 -59
  45. data/lib/paystack_gateway/request_module.rb +12 -11
  46. data/lib/paystack_gateway/settlement.rb +60 -0
  47. data/lib/paystack_gateway/split.rb +286 -0
  48. data/lib/paystack_gateway/storefront.rb +329 -0
  49. data/lib/paystack_gateway/subaccount.rb +263 -0
  50. data/lib/paystack_gateway/subaccounts.rb +1 -35
  51. data/lib/paystack_gateway/subscription.rb +256 -0
  52. data/lib/paystack_gateway/terminal.rb +236 -0
  53. data/lib/paystack_gateway/transaction.rb +592 -0
  54. data/lib/paystack_gateway/transaction_response.rb +1 -33
  55. data/lib/paystack_gateway/transactions.rb +1 -86
  56. data/lib/paystack_gateway/transfer.rb +410 -0
  57. data/lib/paystack_gateway/transfer_recipient.rb +237 -0
  58. data/lib/paystack_gateway/transfer_recipients.rb +1 -21
  59. data/lib/paystack_gateway/transfers.rb +1 -57
  60. data/lib/paystack_gateway/verification.rb +1 -31
  61. data/lib/paystack_gateway/version.rb +1 -1
  62. data/lib/paystack_gateway/virtual_terminal.rb +297 -0
  63. data/lib/paystack_gateway.rb +50 -18
  64. metadata +50 -7
@@ -1,82 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module PaystackGateway
4
- # Create and manage installment payment options
5
- # https://paystack.com/docs/api/plan/#create
6
- module Plans
7
- include PaystackGateway::RequestModule
8
-
9
- # Response from POST /plan endpoint.
10
- class CreatePlanResponse < PaystackGateway::Response
11
- delegate :id, to: :data, prefix: :plan
12
- delegate :id, :plan_code, to: :data
13
- end
14
-
15
- api_method def self.create_plan(name:, amount:, interval:)
16
- use_connection do |connection|
17
- connection.post(
18
- '/plan',
19
- {
20
- name:,
21
- interval:,
22
- amount: amount * 100,
23
- send_invoices: false,
24
- send_sms: false,
25
- },
26
- )
27
- end
28
- end
29
-
30
- # Response from GET /plan endpoint.
31
- class ListPlansResponse < PaystackGateway::Response
32
- def active_plans = data.select { |plan| !plan.is_deleted && !plan.is_archived }
33
-
34
- def find_active_plan_by_name(name)
35
- active_plans.sort_by { -Time.parse(_1.createdAt).to_i }.find { _1.name == name }
36
- end
37
- end
38
-
39
- api_method def self.list_plans
40
- use_connection do |connection|
41
- connection.get('/plan')
42
- end
43
- end
44
-
45
- # Response from GET /plan/:code endpoint.
46
- class FetchPlanResponse < PaystackGateway::Response
47
- delegate :subscriptions, to: :data
48
-
49
- def active_subscriptions = subscriptions.select { _1.status.to_sym == :active }
50
-
51
- def active_subscription_codes(email: nil)
52
- subscriptions =
53
- if email
54
- active_subscriptions.select { _1.customer.email.casecmp?(email) }
55
- else
56
- active_subscriptions
57
- end
58
- subscriptions.map(&:subscription_code)
59
- end
60
- end
61
-
62
- api_method def self.fetch_plan(code:)
63
- use_connection do |connection|
64
- connection.get("/plan/#{code}")
65
- end
66
- end
67
-
68
- class UpdatePlanResponse < PaystackGateway::Response; end
69
-
70
- api_method def self.update_plan(code:, amount:, interval:)
71
- use_connection do |connection|
72
- connection.put(
73
- "/plan/#{code}",
74
- {
75
- amount: amount * 100,
76
- interval:,
77
- },
78
- )
79
- end
80
- end
81
- end
82
- end
3
+ require 'paystack_gateway/legacy/plans'
@@ -0,0 +1,303 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaystackGateway
4
+ # https://paystack.com/docs/api/product
5
+ #
6
+ # Products
7
+ # A collection of endpoints for creating and managing inventories
8
+ module Product
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/product/#list
18
+ # List Products: GET /product
19
+ # List all previously created products
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 active [Boolean]
26
+ # The state of the product
27
+ # @param from [Time]
28
+ # The start date
29
+ # @param to [Time]
30
+ # The end date
31
+ #
32
+ # @return [ListResponse] successful response
33
+ # @raise [ListError] if the request fails
34
+ api_method def self.list(per_page: nil, page: nil, active: nil, from: nil, to: nil)
35
+ use_connection do |connection|
36
+ connection.get(
37
+ '/product',
38
+ { perPage: per_page, page:, active:, from:, to: }.compact,
39
+ )
40
+ end
41
+ end
42
+
43
+ # Successful response from calling #create.
44
+ class CreateResponse < PaystackGateway::Response
45
+ delegate :variants_options,
46
+ :variants,
47
+ :name,
48
+ :description,
49
+ :currency,
50
+ :price,
51
+ :quantity,
52
+ :type,
53
+ :is_shippable,
54
+ :unlimited,
55
+ :files,
56
+ :shipping_fields,
57
+ :integration,
58
+ :domain,
59
+ :metadata,
60
+ :slug,
61
+ :product_code,
62
+ :quantity_sold,
63
+ :active,
64
+ :deleted_at,
65
+ :in_stock,
66
+ :minimum_orderable,
67
+ :maximum_orderable,
68
+ :low_stock_alert,
69
+ :id,
70
+ :createdAt,
71
+ :updatedAt, to: :data
72
+ end
73
+
74
+ # Error response from #create.
75
+ class CreateError < ApiError; end
76
+
77
+ # https://paystack.com/docs/api/product/#create
78
+ # Create Product: POST /product
79
+ # Create a new product on your integration
80
+ #
81
+ # @param name [String] (required)
82
+ # Name of product
83
+ # @param description [String] (required)
84
+ # The description of the product
85
+ # @param price [Integer] (required)
86
+ # Price should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents,
87
+ # if currency is ZAR
88
+ # @param currency [String] (required)
89
+ # Currency in which price is set. Allowed values are: NGN, GHS, ZAR or USD
90
+ # @param unlimited [Boolean]
91
+ # Set to true if the product has unlimited stock. Leave as false if the product has
92
+ # limited stock
93
+ # @param quantity [Integer]
94
+ # Number of products in stock. Use if limited is true
95
+ # @param split_code [String]
96
+ # The split code if sharing the transaction with partners
97
+ # @param metadata [String]
98
+ # Stringified JSON object of custom data
99
+ #
100
+ # @return [CreateResponse] successful response
101
+ # @raise [CreateError] if the request fails
102
+ api_method def self.create(
103
+ name:,
104
+ description:,
105
+ price:,
106
+ currency:,
107
+ unlimited: nil,
108
+ quantity: nil,
109
+ split_code: nil,
110
+ metadata: nil
111
+ )
112
+ use_connection do |connection|
113
+ connection.post(
114
+ '/product',
115
+ {
116
+ name:,
117
+ description:,
118
+ price:,
119
+ currency:,
120
+ unlimited:,
121
+ quantity:,
122
+ split_code:,
123
+ metadata:,
124
+ }.compact,
125
+ )
126
+ end
127
+ end
128
+
129
+ # Successful response from calling #fetch.
130
+ class FetchResponse < PaystackGateway::Response
131
+ delegate :digital_assets,
132
+ :integration,
133
+ :name,
134
+ :description,
135
+ :product_code,
136
+ :price,
137
+ :currency,
138
+ :quantity,
139
+ :quantity_sold,
140
+ :type,
141
+ :files,
142
+ :file_path,
143
+ :is_shippable,
144
+ :shipping_fields,
145
+ :unlimited,
146
+ :domain,
147
+ :active,
148
+ :features,
149
+ :in_stock,
150
+ :metadata,
151
+ :slug,
152
+ :success_message,
153
+ :redirect_url,
154
+ :split_code,
155
+ :notification_emails,
156
+ :minimum_orderable,
157
+ :maximum_orderable,
158
+ :low_stock_alert,
159
+ :stock_threshold,
160
+ :expires_in,
161
+ :id,
162
+ :createdAt,
163
+ :updatedAt, to: :data
164
+ end
165
+
166
+ # Error response from #fetch.
167
+ class FetchError < ApiError; end
168
+
169
+ # https://paystack.com/docs/api/product/#fetch
170
+ # Fetch Product: GET /product/{id}
171
+ # Fetch a previously created product
172
+ #
173
+ # @param id [Integer] (required)
174
+ # The unique identifier of the product
175
+ #
176
+ # @return [FetchResponse] successful response
177
+ # @raise [FetchError] if the request fails
178
+ api_method def self.fetch(id:)
179
+ use_connection do |connection|
180
+ connection.get(
181
+ "/product/#{id}",
182
+ )
183
+ end
184
+ end
185
+
186
+ # Successful response from calling #update.
187
+ class UpdateResponse < PaystackGateway::Response
188
+ delegate :name,
189
+ :description,
190
+ :product_code,
191
+ :price,
192
+ :currency,
193
+ :quantity,
194
+ :quantity_sold,
195
+ :type,
196
+ :files,
197
+ :file_path,
198
+ :is_shippable,
199
+ :shipping_fields,
200
+ :unlimited,
201
+ :domain,
202
+ :active,
203
+ :features,
204
+ :in_stock,
205
+ :metadata,
206
+ :slug,
207
+ :success_message,
208
+ :redirect_url,
209
+ :split_code,
210
+ :notification_emails,
211
+ :minimum_orderable,
212
+ :maximum_orderable,
213
+ :low_stock_alert,
214
+ :stock_threshold,
215
+ :expires_in,
216
+ :id,
217
+ :integration,
218
+ :createdAt,
219
+ :updatedAt, to: :data
220
+ end
221
+
222
+ # Error response from #update.
223
+ class UpdateError < ApiError; end
224
+
225
+ # https://paystack.com/docs/api/product/#update
226
+ # Update product: PUT /product/{id}
227
+ # Update a previously created product
228
+ #
229
+ # @param id [Integer] (required)
230
+ # The unique identifier of the product
231
+ # @param name [String]
232
+ # Name of product
233
+ # @param description [String]
234
+ # The description of the product
235
+ # @param price [Integer]
236
+ # Price should be in kobo if currency is NGN, pesewas, if currency is GHS, and cents,
237
+ # if currency is ZAR
238
+ # @param currency [String]
239
+ # Currency in which price is set. Allowed values are: NGN, GHS, ZAR or USD
240
+ # @param unlimited [Boolean]
241
+ # Set to true if the product has unlimited stock. Leave as false if the product has
242
+ # limited stock
243
+ # @param quantity [Integer]
244
+ # Number of products in stock. Use if limited is true
245
+ # @param split_code [String]
246
+ # The split code if sharing the transaction with partners
247
+ # @param metadata [Hash]
248
+ # JSON object of custom data
249
+ #
250
+ # @return [UpdateResponse] successful response
251
+ # @raise [UpdateError] if the request fails
252
+ api_method def self.update(
253
+ id:,
254
+ name: nil,
255
+ description: nil,
256
+ price: nil,
257
+ currency: nil,
258
+ unlimited: nil,
259
+ quantity: nil,
260
+ split_code: nil,
261
+ metadata: nil
262
+ )
263
+ use_connection do |connection|
264
+ connection.put(
265
+ "/product/#{id}",
266
+ {
267
+ name:,
268
+ description:,
269
+ price:,
270
+ currency:,
271
+ unlimited:,
272
+ quantity:,
273
+ split_code:,
274
+ metadata:,
275
+ }.compact,
276
+ )
277
+ end
278
+ end
279
+
280
+ # Successful response from calling #delete.
281
+ class DeleteResponse < PaystackGateway::Response; end
282
+
283
+ # Error response from #delete.
284
+ class DeleteError < ApiError; end
285
+
286
+ # https://paystack.com/docs/api/product/#delete
287
+ # Delete Product: DELETE /product/{id}
288
+ # Delete a previously created product
289
+ #
290
+ # @param id [Integer] (required)
291
+ # The unique identifier of the product
292
+ #
293
+ # @return [DeleteResponse] successful response
294
+ # @raise [DeleteError] if the request fails
295
+ api_method def self.delete(id:)
296
+ use_connection do |connection|
297
+ connection.delete(
298
+ "/product/#{id}",
299
+ )
300
+ end
301
+ end
302
+ end
303
+ end
@@ -0,0 +1,197 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaystackGateway
4
+ # https://paystack.com/docs/api/refund
5
+ #
6
+ # Refunds
7
+ # A collection of endpoints for creating and managing transaction reimbursement
8
+ module Refund
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/refund/#list
18
+ # List Refunds: GET /refund
19
+ # List previously created refunds
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 from [Time]
26
+ # The start date
27
+ # @param to [Time]
28
+ # The end date
29
+ #
30
+ # @return [ListResponse] successful response
31
+ # @raise [ListError] if the request fails
32
+ api_method def self.list(per_page: nil, page: nil, from: nil, to: nil)
33
+ use_connection do |connection|
34
+ connection.get(
35
+ '/refund',
36
+ { perPage: per_page, page:, from:, to: }.compact,
37
+ )
38
+ end
39
+ end
40
+
41
+ # Successful response from calling #create.
42
+ class CreateResponse < PaystackGateway::Response
43
+ delegate :transaction,
44
+ :integration,
45
+ :deducted_amount,
46
+ :channel,
47
+ :merchant_note,
48
+ :customer_note,
49
+ :refunded_by,
50
+ :expected_at,
51
+ :currency,
52
+ :domain,
53
+ :amount,
54
+ :fully_deducted,
55
+ :id,
56
+ :createdAt,
57
+ :updatedAt, to: :data
58
+ end
59
+
60
+ # Error response from #create.
61
+ class CreateError < ApiError; end
62
+
63
+ # https://paystack.com/docs/api/refund/#create
64
+ # Create Refund: POST /refund
65
+ # Initiate a refund for a previously completed transaction
66
+ #
67
+ # @param transaction [String] (required)
68
+ # The reference of a previosuly completed transaction
69
+ # @param amount [Integer]
70
+ # Amount to be refunded to the customer. It cannot be more than the original transaction
71
+ # amount
72
+ # @param currency ["GHS", "KES", "NGN", "USD", "ZAR"]
73
+ # Three-letter ISO currency
74
+ # @param customer_note [String]
75
+ # Customer reason
76
+ # @param merchant_note [String]
77
+ # Merchant reason
78
+ #
79
+ # @return [CreateResponse] successful response
80
+ # @raise [CreateError] if the request fails
81
+ api_method def self.create(transaction:, amount: nil, currency: nil, customer_note: nil, merchant_note: nil)
82
+ use_connection do |connection|
83
+ connection.post(
84
+ '/refund',
85
+ { transaction:, amount:, currency:, customer_note:, merchant_note: }.compact,
86
+ )
87
+ end
88
+ end
89
+
90
+ # Successful response from calling #retry.
91
+ class RetryResponse < PaystackGateway::Response
92
+ delegate :integration,
93
+ :transaction,
94
+ :dispute,
95
+ :settlement,
96
+ :id,
97
+ :domain,
98
+ :currency,
99
+ :amount,
100
+ :refunded_at,
101
+ :expected_at,
102
+ :channel,
103
+ :refunded_by,
104
+ :customer_note,
105
+ :merchant_note,
106
+ :deducted_amount,
107
+ :fully_deducted,
108
+ :bank_reference,
109
+ :reason,
110
+ :customer,
111
+ :initiated_by,
112
+ :reversed_at,
113
+ :session_id, to: :data
114
+ end
115
+
116
+ # Error response from #retry.
117
+ class RetryError < ApiError; end
118
+
119
+ # https://paystack.com/docs/api/refund/#retry
120
+ # Retry Refund: POST /refund/retry_with_customer_details/{id}
121
+ # Retry a refund with a `needs-attention` status by providing the bank account details
122
+ # of a customer.
123
+ #
124
+ # @param id [Integer] (required)
125
+ # The identifier of the refund
126
+ # @param refund_account_details [Hash] (required)
127
+ # An object that contains the customer’s account details for refund
128
+ # @option refund_account_details [String] :currency
129
+ # The currency of the customer's bank account. It should be the same as the currency
130
+ # the payment was made
131
+ # @option refund_account_details [String] :account_number
132
+ # The customer's account number
133
+ # @option refund_account_details [String] :bank_id
134
+ # The ID representing the customer's bank. You can get the list of bank IDs by calling
135
+ # the List Banks endpoint.
136
+ #
137
+ # @return [RetryResponse] successful response
138
+ # @raise [RetryError] if the request fails
139
+ api_method def self.retry(id:, refund_account_details:)
140
+ use_connection do |connection|
141
+ connection.post(
142
+ "/refund/retry_with_customer_details/#{id}",
143
+ { refund_account_details: }.compact,
144
+ )
145
+ end
146
+ end
147
+
148
+ # Successful response from calling #fetch.
149
+ class FetchResponse < PaystackGateway::Response
150
+ delegate :integration,
151
+ :transaction,
152
+ :dispute,
153
+ :settlement,
154
+ :id,
155
+ :domain,
156
+ :currency,
157
+ :amount,
158
+ :refunded_at,
159
+ :refunded_by,
160
+ :customer_note,
161
+ :merchant_note,
162
+ :deducted_amount,
163
+ :fully_deducted,
164
+ :createdAt,
165
+ :bank_reference,
166
+ :transaction_reference,
167
+ :reason,
168
+ :customer,
169
+ :refund_type,
170
+ :transaction_amount,
171
+ :initiated_by,
172
+ :refund_channel,
173
+ :session_id,
174
+ :collect_account_number, to: :data
175
+ end
176
+
177
+ # Error response from #fetch.
178
+ class FetchError < ApiError; end
179
+
180
+ # https://paystack.com/docs/api/refund/#fetch
181
+ # Fetch Refund: GET /refund/{id}
182
+ # Get a previously created refund
183
+ #
184
+ # @param id [Integer] (required)
185
+ # The identifier of the refund
186
+ #
187
+ # @return [FetchResponse] successful response
188
+ # @raise [FetchError] if the request fails
189
+ api_method def self.fetch(id:)
190
+ use_connection do |connection|
191
+ connection.get(
192
+ "/refund/#{id}",
193
+ )
194
+ end
195
+ end
196
+ end
197
+ end
@@ -1,61 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module PaystackGateway
4
- # Create and manage transaction refunds.
5
- # https://paystack.com/docs/api/refund
6
- module Refunds
7
- include PaystackGateway::RequestModule
8
-
9
- # Common helpers for responses from refunds endpoints
10
- module TransactionRefundResponse
11
- def refund_success? = transaction_status == :processed
12
- def refund_failed? = transaction_status == :failed
13
- def refund_pending? = transaction_status.in?(%i[pending processing])
14
- end
15
-
16
- # Response from POST /refund endpoint.
17
- class CreateResponse < PaystackGateway::Response
18
- include TransactionResponse
19
- include TransactionRefundResponse
20
- end
21
-
22
- api_method def self.create(transaction_reference_or_id:)
23
- use_connection do |connection|
24
- connection.post('/refund', { transaction: transaction_reference_or_id })
25
- end
26
- end
27
-
28
- # Response from GET /refund endpoint.
29
- class ListRefundsResponse < PaystackGateway::Response
30
- def pending_or_successful
31
- filtered = data.select { _1.status&.to_sym.in?(%i[processed pending processing]) }
32
-
33
- ListRefundsResponse.new({ **self, data: filtered })
34
- end
35
-
36
- def with_amount(amount)
37
- filtered = data.select { _1.amount == amount * 100 }
38
-
39
- ListRefundsResponse.new({ **self, data: filtered })
40
- end
41
- end
42
-
43
- api_method def self.list_refunds(transaction_id:)
44
- use_connection do |connection|
45
- connection.get('/refund', { transaction: transaction_id })
46
- end
47
- end
48
-
49
- # Response from GET /refund/:id endpoint.
50
- class FetchRefundResponse < PaystackGateway::Response
51
- include TransactionResponse
52
- include TransactionRefundResponse
53
- end
54
-
55
- api_method def self.fetch_refund(refund_id:)
56
- use_connection do |connection|
57
- connection.get("/refund/#{refund_id}")
58
- end
59
- end
60
- end
61
- end
3
+ require 'paystack_gateway/legacy/refunds'
@@ -58,23 +58,24 @@ module PaystackGateway
58
58
 
59
59
  def decorate_api_methods(method_names = api_methods)
60
60
  singleton_class.class_exec do
61
- prepend(Module.new do
62
- method_names.flatten.each do |method_name|
63
- define_method(method_name) do |*args, **kwargs, &block|
64
- Current.with(api_module: self, api_method_name: method_name) do
65
- super(*args, **kwargs, &block)
66
- rescue Faraday::Error => e
67
- handle_error(e)
68
- end
61
+ method_names.flatten.each do |method_name|
62
+ implementation = instance_method(method_name)
63
+ remove_method(method_name)
64
+
65
+ define_method(method_name) do |*args, **kwargs, &block|
66
+ PaystackGateway::Current.with(api_module: self, api_method_name: method_name) do
67
+ implementation.bind_call(self, *args, **kwargs, &block)
68
+ rescue Faraday::Error => e
69
+ handle_error(e)
69
70
  end
70
71
  end
71
- end)
72
+ end
72
73
  end
73
74
  end
74
75
 
75
76
  def handle_error(error)
76
- PaystackGateway.logger.error "#{Current.qualified_api_method_name}: #{error.message}"
77
- PaystackGateway.logger.error JSON.pretty_generate(filtered_response(error.response) || {}) if error.response
77
+ PaystackGateway.logger.error { "#{Current.qualified_api_method_name}: #{error.message}" }
78
+ PaystackGateway.logger.debug { JSON.pretty_generate(filtered_response(error.response) || {}) } if error.response
78
79
 
79
80
  raise Current.error_class.new(
80
81
  "Paystack error: #{error.message}, status: #{error.response_status}, response: #{error.response_body}",