paystack_sdk 0.0.1 → 0.0.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/README.md +22 -4
- data/lib/paystack_sdk/resources/base.rb +6 -16
- data/lib/paystack_sdk/resources/transactions.rb +42 -9
- data/lib/paystack_sdk/response.rb +238 -0
- data/lib/paystack_sdk/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c03bb9f7dac356482968d6f001891089c925b179faed1b22f95f9b07c517aa74
|
4
|
+
data.tar.gz: 37ea92fc17e2d1a3e6fb5397df6e96dbe6d8e013816e312cb38ed4ccb6722671
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61b2525bd9207c4e3173deef634d1fa1298fe79a97c76eacff072fc606843a60b45bd5c657d17014fe507bf2aa297d71d3beb9bbcafc7d8fdcc01a4ec4bcf397
|
7
|
+
data.tar.gz: 81145b4c48f151413970819905a1952502eb7e57873a5c7b82e618a9f006e2185847f7526a6cc348b332d727151524a4cdf529b8f39e8e63b7c70d680469b830
|
data/README.md
CHANGED
@@ -36,19 +36,37 @@ paystack = PaystackSdk::Client.new(api_key: "sk_test_xxx")
|
|
36
36
|
params = {email: "customer@email.com", amount: "2300", currency: "USD"}
|
37
37
|
response = paystack.transactions.initialize_transaction(params)
|
38
38
|
|
39
|
+
if response.success?
|
40
|
+
puts response.authorization_url
|
41
|
+
else
|
42
|
+
puts resposne.error_message
|
43
|
+
end
|
44
|
+
|
39
45
|
# Example: Verify a payment
|
40
46
|
response = paystack.transactions.verify(reference: "transaction_reference")
|
41
|
-
if
|
47
|
+
if response.success?
|
42
48
|
puts "Payment verified successfully!"
|
43
49
|
else
|
44
50
|
puts "Payment verification failed: #{response.error_message}"
|
45
51
|
end
|
52
|
+
```
|
53
|
+
|
54
|
+
### The Orginal Response
|
46
55
|
|
47
|
-
|
48
|
-
|
49
|
-
|
56
|
+
There will times you may need access to the original API response. For such cases, you
|
57
|
+
can use the `#original_response` method on the response object.
|
58
|
+
|
59
|
+
The return value is a hash with all the values from the HTTP request. This could be useful
|
60
|
+
when you need to debug or gain access to the response its raw state.
|
61
|
+
|
62
|
+
For example
|
63
|
+
```ruby
|
64
|
+
response = transaction.list
|
65
|
+
|
66
|
+
puts response.original_message # => This will return the exact response received from Paystack
|
50
67
|
```
|
51
68
|
|
69
|
+
|
52
70
|
Refer to the [documentation](https://github.com/nanafox/paystack_sdk) for more detailed usage examples and supported endpoints.
|
53
71
|
|
54
72
|
## Development
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../response"
|
4
|
+
|
1
5
|
module PaystackSdk
|
2
6
|
module Resources
|
3
7
|
# The `Base` class serves as a parent class for all resource classes in the SDK.
|
@@ -10,29 +14,15 @@ module PaystackSdk
|
|
10
14
|
@connection = connection
|
11
15
|
end
|
12
16
|
|
13
|
-
# Checks if the last API response was successful.
|
14
|
-
#
|
15
|
-
# @return [Boolean] `true` if the last API response was successful, otherwise `false`.
|
16
|
-
def success?
|
17
|
-
@api_response&.success? || false
|
18
|
-
end
|
19
|
-
|
20
17
|
private
|
21
18
|
|
22
19
|
# Handles the API response, raising an error if the response is unsuccessful.
|
23
20
|
#
|
24
21
|
# @param response [Faraday::Response] The response object returned by the Faraday connection.
|
25
|
-
# @return [
|
22
|
+
# @return [PaystackSdk::Response] The parsed response body wrapped in a `PaystackSdk::Response` object if the request was successful.
|
26
23
|
# @raise [PaystackSdk::Error] If the response indicates an error.
|
27
24
|
def handle_response(response)
|
28
|
-
|
29
|
-
|
30
|
-
if response.success?
|
31
|
-
response.body
|
32
|
-
else
|
33
|
-
error_message = response.body.is_a?(Hash) ? response.body["message"] : "Paystack API Error"
|
34
|
-
raise PaystackSdk::Error, error_message
|
35
|
-
end
|
25
|
+
PaystackSdk::Response.new(response)
|
36
26
|
end
|
37
27
|
end
|
38
28
|
end
|
@@ -4,8 +4,38 @@ require_relative "base"
|
|
4
4
|
|
5
5
|
module PaystackSdk
|
6
6
|
module Resources
|
7
|
-
# The `Transactions` class provides methods for interacting with the Paystack
|
7
|
+
# The `Transactions` class provides methods for interacting with the Paystack
|
8
|
+
# Transactions API.
|
8
9
|
# It allows you to initialize transactions, verify payments, list transactions, and fetch transaction details.
|
10
|
+
# The Transactions class provides methods to interact with the Paystack API for managing transactions.
|
11
|
+
# It includes functionalities for initializing, verifying, listing, fetching, and retrieving transaction totals.
|
12
|
+
#
|
13
|
+
# Example usage:
|
14
|
+
# ```ruby
|
15
|
+
# transactions = PaystackSdk::Resources::Transactions.new(connection)
|
16
|
+
#
|
17
|
+
# # Initialize a transaction
|
18
|
+
# payload = { email: "customer@email.com", amount: 10000, currency: "GHS" }
|
19
|
+
# response = transactions.initialize_transaction(payload)
|
20
|
+
# if response.success?
|
21
|
+
# puts "Transaction initialized successfully."
|
22
|
+
# puts "Authorization URL: #{response.data.authorization_url}"
|
23
|
+
# else
|
24
|
+
# puts "Error initializing transaction: #{response.error_message}"
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# # Verify a transaction
|
28
|
+
# response = transactions.verify(reference: "transaction_reference")
|
29
|
+
#
|
30
|
+
# # List transactions
|
31
|
+
# response = transactions.list(per_page: 50, page: 1)
|
32
|
+
#
|
33
|
+
# # Fetch a single transaction
|
34
|
+
# response = transactions.fetch(transaction_id: 12345)
|
35
|
+
#
|
36
|
+
# # Get transaction totals
|
37
|
+
# response = transactions.totals
|
38
|
+
# ```
|
9
39
|
class Transactions < PaystackSdk::Resources::Base
|
10
40
|
# Initializes a new transaction.
|
11
41
|
#
|
@@ -17,7 +47,7 @@ module PaystackSdk
|
|
17
47
|
# payload = { email: "customer@email.com", amount: 10000, currency: "GHS" }
|
18
48
|
# response = transactions.initialize_transaction(payload)
|
19
49
|
def initialize_transaction(payload)
|
20
|
-
raise PaystackSdk::Error, "
|
50
|
+
raise PaystackSdk::Error, "Payload must be a hash" unless payload.is_a?(Hash)
|
21
51
|
response = @connection.post("/transaction/initialize", payload)
|
22
52
|
handle_response(response)
|
23
53
|
end
|
@@ -37,26 +67,29 @@ module PaystackSdk
|
|
37
67
|
|
38
68
|
# Lists all transactions.
|
39
69
|
#
|
40
|
-
# @
|
70
|
+
# @param per_page [Integer] Number of records per page (default: 50)
|
71
|
+
# @param page [Integer] Page number to retrieve (default: 1)
|
72
|
+
# @return [PaystackSdk::Response] The response from the Paystack API containing a
|
73
|
+
# list of transactions.
|
41
74
|
# @raise [PaystackSdk::Error] If the API request fails.
|
42
75
|
#
|
43
76
|
# @example
|
44
|
-
# response = transactions.list
|
45
|
-
def list
|
46
|
-
response = @connection.get("/transaction")
|
77
|
+
# response = transactions.list(per_page: 20, page: 2)
|
78
|
+
def list(per_page: 50, page: 1)
|
79
|
+
response = @connection.get("/transaction", {perPage: per_page, page: page})
|
47
80
|
handle_response(response)
|
48
81
|
end
|
49
82
|
|
50
83
|
# Fetches details of a single transaction by its ID.
|
51
84
|
#
|
52
|
-
# @param
|
85
|
+
# @param transaction_id [Integer] The ID of the transaction to fetch.
|
53
86
|
# @return [Hash] The response from the Paystack API containing transaction details.
|
54
87
|
# @raise [PaystackSdk::Error] If the API request fails.
|
55
88
|
#
|
56
89
|
# @example
|
57
90
|
# response = transactions.fetch("transaction_id")
|
58
|
-
def fetch(
|
59
|
-
response = @connection.get("/transaction/#{
|
91
|
+
def fetch(transaction_id)
|
92
|
+
response = @connection.get("/transaction/#{transaction_id}")
|
60
93
|
handle_response(response)
|
61
94
|
end
|
62
95
|
|
@@ -0,0 +1,238 @@
|
|
1
|
+
module PaystackSdk
|
2
|
+
# The Response class provides a wrapper around Paystack API responses.
|
3
|
+
# It offers convenient access to response data through dot notation and
|
4
|
+
# supports both direct attribute access and hash/array-like operations.
|
5
|
+
#
|
6
|
+
# Features:
|
7
|
+
# - Dynamic attribute access via dot notation (response.data.attribute)
|
8
|
+
# - Hash-like access (response[:key])
|
9
|
+
# - Array-like access for list responses (response[0])
|
10
|
+
# - Iteration support (response.each)
|
11
|
+
# - Automatic handling of nested data structures
|
12
|
+
#
|
13
|
+
# @example Basic usage
|
14
|
+
# ```ruby
|
15
|
+
# response = PaystackSdk::Response.new(api_response)
|
16
|
+
#
|
17
|
+
# # Check if request was successful
|
18
|
+
# if response.success?
|
19
|
+
# # Access data using dot notation
|
20
|
+
# puts response.data.authorization_url
|
21
|
+
# puts response.data.reference
|
22
|
+
#
|
23
|
+
# # Or directly from response
|
24
|
+
# puts response.authorization_url
|
25
|
+
# else
|
26
|
+
# puts "Error: #{response.error_message}"
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# @example Working with list responses
|
30
|
+
# response = transactions.list
|
31
|
+
#
|
32
|
+
# # Iterate through items
|
33
|
+
# response.data.each do |transaction|
|
34
|
+
# puts transaction.amount
|
35
|
+
# puts transaction.reference
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # Access by index
|
39
|
+
# first_transaction = response.data[0] # => same as `response.first`
|
40
|
+
# puts first_transaction.customer.email
|
41
|
+
# ```
|
42
|
+
class Response
|
43
|
+
# @return [String, nil] Error message if the request failed
|
44
|
+
attr_reader :error_message
|
45
|
+
|
46
|
+
# @return [String, nil] API message from the response
|
47
|
+
attr_reader :api_message
|
48
|
+
|
49
|
+
# @return [Hash, Array, Object] The underlying data
|
50
|
+
attr_reader :raw_data
|
51
|
+
|
52
|
+
# Initializes a new Response object
|
53
|
+
#
|
54
|
+
# @param response [Faraday::Response, Hash, Array] The raw API response or data
|
55
|
+
def initialize(response)
|
56
|
+
if response.is_a?(Faraday::Response)
|
57
|
+
# Handle direct Faraday response
|
58
|
+
@success = response.success?
|
59
|
+
@body = response.body
|
60
|
+
@api_message = extract_api_message(@body)
|
61
|
+
@raw_data = extract_data_from_body(@body)
|
62
|
+
|
63
|
+
unless @success
|
64
|
+
@error_message = @api_message || "Paystack API Error"
|
65
|
+
end
|
66
|
+
elsif response.is_a?(Response)
|
67
|
+
# If we're wrapping a Response object, just copy its data
|
68
|
+
@success = response.success
|
69
|
+
@error_message = response.error_message
|
70
|
+
@api_message = response.api_message
|
71
|
+
@raw_data = response.raw_data
|
72
|
+
else
|
73
|
+
# For direct data (Hash, Array, etc.)
|
74
|
+
@success = true
|
75
|
+
@raw_data = response
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns a Response object for the data
|
80
|
+
# This enables chained access like response.data.key
|
81
|
+
#
|
82
|
+
# @return [Response] self, to enable chaining
|
83
|
+
def data
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
# Check if the response was successful
|
88
|
+
#
|
89
|
+
# @return [Boolean] true if the API request was successful
|
90
|
+
def success?
|
91
|
+
@success
|
92
|
+
end
|
93
|
+
|
94
|
+
# Returns the original response body
|
95
|
+
# This is useful for debugging or accessing raw data
|
96
|
+
#
|
97
|
+
# @return [Hash, Array] The original response body
|
98
|
+
def original_response
|
99
|
+
@body
|
100
|
+
end
|
101
|
+
|
102
|
+
# Access hash values via methods (dot notation)
|
103
|
+
# Allows accessing data attributes directly: response.attribute_name
|
104
|
+
#
|
105
|
+
# @param method_name [Symbol] The attribute name to access
|
106
|
+
# @param args [Array] Method arguments (unused)
|
107
|
+
# @param block [Proc] Method block (unused)
|
108
|
+
# @return [Object, Response] The attribute value, wrapped in Response if it's a complex type
|
109
|
+
def method_missing(method_name, *args, &block)
|
110
|
+
if @raw_data.is_a?(Hash) && (@raw_data.key?(method_name) || @raw_data.key?(method_name.to_s))
|
111
|
+
value = @raw_data[method_name] || @raw_data[method_name.to_s]
|
112
|
+
wrap_value(value)
|
113
|
+
elsif @raw_data.is_a?(Array) && @raw_data.respond_to?(method_name)
|
114
|
+
result = @raw_data.send(method_name, *args, &block)
|
115
|
+
wrap_value(result)
|
116
|
+
else
|
117
|
+
super
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Check if the object responds to a method
|
122
|
+
#
|
123
|
+
# @param method_name [Symbol] The method name
|
124
|
+
# @param include_private [Boolean] Whether to include private methods
|
125
|
+
# @return [Boolean] Whether the method is supported
|
126
|
+
def respond_to_missing?(method_name, include_private = false)
|
127
|
+
(@raw_data.is_a?(Hash) && (@raw_data.key?(method_name) || @raw_data.key?(method_name.to_s))) ||
|
128
|
+
(@raw_data.is_a?(Array) && @raw_data.respond_to?(method_name)) ||
|
129
|
+
super
|
130
|
+
end
|
131
|
+
|
132
|
+
# Access data via hash/array notation
|
133
|
+
#
|
134
|
+
# @param key [Object] The key or index to access
|
135
|
+
# @return [Object, Response] The value for the given key or index
|
136
|
+
def [](key)
|
137
|
+
return nil unless @raw_data
|
138
|
+
|
139
|
+
if @raw_data.is_a?(Hash)
|
140
|
+
value = @raw_data[key.is_a?(String) ? key.to_sym : key]
|
141
|
+
wrap_value(value)
|
142
|
+
elsif @raw_data.is_a?(Array) && key.is_a?(Integer)
|
143
|
+
wrap_value(@raw_data[key])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Check if key exists in hash
|
148
|
+
#
|
149
|
+
# @param key [Symbol, String] The key to check
|
150
|
+
# @return [Boolean] Whether the key exists
|
151
|
+
def key?(key)
|
152
|
+
@raw_data.is_a?(Hash) && @raw_data.key?(key.is_a?(String) ? key.to_sym : key)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Iterate through hash entries or array items
|
156
|
+
#
|
157
|
+
# @yield [key, value] For hashes, passes each key-value pair
|
158
|
+
# @yield [value] For arrays, passes each item
|
159
|
+
# @return [Response, Enumerator] Self for chaining or Enumerator if no block given
|
160
|
+
def each(&block)
|
161
|
+
return enum_for(:each) unless block_given?
|
162
|
+
|
163
|
+
if @raw_data.is_a?(Hash)
|
164
|
+
@raw_data.each { |k, v| yield k, wrap_value(v) }
|
165
|
+
elsif @raw_data.is_a?(Array)
|
166
|
+
@raw_data.each { |item| yield wrap_value(item) }
|
167
|
+
end
|
168
|
+
self
|
169
|
+
end
|
170
|
+
|
171
|
+
# Standard array methods, delegated to the raw data
|
172
|
+
# @!method size
|
173
|
+
# @return [Integer] The number of items
|
174
|
+
# @!method length
|
175
|
+
# @return [Integer] The number of items
|
176
|
+
# @!method count
|
177
|
+
# @return [Integer] The number of items
|
178
|
+
# @!method empty?
|
179
|
+
# @return [Boolean] Whether the collection is empty
|
180
|
+
[:size, :length, :count, :empty?].each do |method_name|
|
181
|
+
define_method(method_name) do
|
182
|
+
@raw_data.send(method_name) if @raw_data.respond_to?(method_name)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Special array methods that return wrapped values
|
187
|
+
# @!method first
|
188
|
+
# @return [Object, Response] The first item, wrapped if necessary
|
189
|
+
# @!method last
|
190
|
+
# @return [Object, Response] The last item, wrapped if necessary
|
191
|
+
[:first, :last].each do |method_name|
|
192
|
+
define_method(method_name) do
|
193
|
+
return nil unless @raw_data.is_a?(Array)
|
194
|
+
wrap_value(@raw_data.send(method_name))
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
# Extract API message from response body
|
201
|
+
#
|
202
|
+
# @param body [Hash] The response body
|
203
|
+
# @return [String, nil] The API message
|
204
|
+
def extract_api_message(body)
|
205
|
+
body["message"] || body[:message] if body.is_a?(Hash)
|
206
|
+
end
|
207
|
+
|
208
|
+
# Extract data from response body
|
209
|
+
#
|
210
|
+
# @param body [Hash, Array] The response body
|
211
|
+
# @return [Hash, Array, Object] The data portion of the response
|
212
|
+
def extract_data_from_body(body)
|
213
|
+
if body.is_a?(Hash)
|
214
|
+
body["data"] || body[:data] || body
|
215
|
+
else
|
216
|
+
body
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# Wrap value in Response if needed
|
221
|
+
#
|
222
|
+
# @param value [Object] The value to wrap
|
223
|
+
# @return [Object, Response] The wrapped value
|
224
|
+
def wrap_value(value)
|
225
|
+
case value
|
226
|
+
when Response
|
227
|
+
# Already wrapped
|
228
|
+
value
|
229
|
+
when Hash, Array
|
230
|
+
# Create a new Response with the value
|
231
|
+
Response.new(value)
|
232
|
+
else
|
233
|
+
# Return primitives as-is
|
234
|
+
value
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
data/lib/paystack_sdk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paystack_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maxwell Nana Forson (theLazyProgrammer)
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-05-
|
11
|
+
date: 2025-05-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 13.2.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: debug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.9.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.9.0
|
83
97
|
description: |
|
84
98
|
The `paystack_sdk` gem provides a simple and intuitive interface for
|
85
99
|
interacting with Paystack's payment gateway API. It allows developers to
|
@@ -104,6 +118,7 @@ files:
|
|
104
118
|
- lib/paystack_sdk/client.rb
|
105
119
|
- lib/paystack_sdk/resources/base.rb
|
106
120
|
- lib/paystack_sdk/resources/transactions.rb
|
121
|
+
- lib/paystack_sdk/response.rb
|
107
122
|
- lib/paystack_sdk/version.rb
|
108
123
|
- mise.toml
|
109
124
|
- sig/paystack_sdk.rbs
|