paystack_sdk 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/CHANGELOG.md +67 -0
- data/README.md +624 -86
- data/lib/paystack_sdk/client.rb +64 -21
- data/lib/paystack_sdk/middleware/transport_errors.rb +23 -0
- data/lib/paystack_sdk/request_helpers.rb +117 -0
- data/lib/paystack_sdk/resources/banks.rb +163 -13
- data/lib/paystack_sdk/resources/base.rb +4 -2
- data/lib/paystack_sdk/resources/charges.rb +190 -76
- data/lib/paystack_sdk/resources/customers.rb +260 -139
- data/lib/paystack_sdk/resources/extensions/charges.rb +65 -0
- data/lib/paystack_sdk/resources/miscellaneous.rb +58 -0
- data/lib/paystack_sdk/resources/refunds.rb +116 -0
- data/lib/paystack_sdk/resources/transactions.rb +365 -238
- data/lib/paystack_sdk/resources/transfer_recipients.rb +135 -27
- data/lib/paystack_sdk/resources/transfers.rb +260 -25
- data/lib/paystack_sdk/response.rb +88 -9
- data/lib/paystack_sdk/utils/connection_utils.rb +100 -5
- data/lib/paystack_sdk/version.rb +1 -1
- data/lib/paystack_sdk/webhook.rb +152 -0
- data/lib/paystack_sdk.rb +27 -2
- metadata +57 -4
- data/lib/paystack_sdk/resources/verification.rb +0 -36
data/lib/paystack_sdk/client.rb
CHANGED
|
@@ -5,8 +5,9 @@ require_relative "resources/customers"
|
|
|
5
5
|
require_relative "resources/transfer_recipients"
|
|
6
6
|
require_relative "resources/transfers"
|
|
7
7
|
require_relative "resources/banks"
|
|
8
|
-
require_relative "resources/verification"
|
|
9
8
|
require_relative "resources/charges"
|
|
9
|
+
require_relative "resources/miscellaneous"
|
|
10
|
+
require_relative "resources/refunds"
|
|
10
11
|
require_relative "utils/connection_utils"
|
|
11
12
|
|
|
12
13
|
module PaystackSdk
|
|
@@ -16,6 +17,10 @@ module PaystackSdk
|
|
|
16
17
|
# Include connection utilities
|
|
17
18
|
include Utils::ConnectionUtils
|
|
18
19
|
|
|
20
|
+
# Prefix of Paystack's test and live secret keys.
|
|
21
|
+
TEST_KEY_PREFIX = "sk_test_"
|
|
22
|
+
LIVE_KEY_PREFIX = "sk_live_"
|
|
23
|
+
|
|
19
24
|
# @return [Faraday::Connection] The Faraday connection object used for API requests
|
|
20
25
|
attr_reader :connection
|
|
21
26
|
|
|
@@ -25,6 +30,9 @@ module PaystackSdk
|
|
|
25
30
|
# If nil, a new connection will be created using the default API key.
|
|
26
31
|
# @param secret_key [String, nil] Optional API key to use for creating a new connection.
|
|
27
32
|
# Only used if connection is nil.
|
|
33
|
+
# @param sandbox_only [Boolean] Refuse to build a client unless the key is a test key
|
|
34
|
+
# (`sk_test_...`). Set this in staging and CI so they can never charge real money.
|
|
35
|
+
# @raise [ArgumentError] If `sandbox_only` is true and the key is not a test key.
|
|
28
36
|
#
|
|
29
37
|
# @example With an existing connection
|
|
30
38
|
# connection = Faraday.new(...)
|
|
@@ -35,8 +43,25 @@ module PaystackSdk
|
|
|
35
43
|
#
|
|
36
44
|
# @example With default connection (requires PAYSTACK_SECRET_KEY environment variable)
|
|
37
45
|
# client = PaystackSdk::Client.new
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
# @example Refuse live keys (staging, CI)
|
|
47
|
+
# client = PaystackSdk::Client.new(secret_key: ENV["PAYSTACK_SECRET_KEY"], sandbox_only: true)
|
|
48
|
+
def initialize(connection = nil, secret_key: nil, sandbox_only: false, **options)
|
|
49
|
+
if sandbox_only
|
|
50
|
+
key = connection ? key_from(connection) : (secret_key || ENV["PAYSTACK_SECRET_KEY"])
|
|
51
|
+
unless key.to_s.start_with?(TEST_KEY_PREFIX)
|
|
52
|
+
raise ArgumentError, "sandbox_only is set, but the secret key is not a test key (#{TEST_KEY_PREFIX}...)"
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
@connection = initialize_connection(connection, secret_key: secret_key, **options)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Whether this client is using a live key (`sk_live_...`), so requests move real money.
|
|
60
|
+
# A test key, or a key in any other form, is not live.
|
|
61
|
+
#
|
|
62
|
+
# @return [Boolean]
|
|
63
|
+
def live?
|
|
64
|
+
key_from(@connection).to_s.start_with?(LIVE_KEY_PREFIX)
|
|
40
65
|
end
|
|
41
66
|
|
|
42
67
|
# Provides access to the `Transactions` resource.
|
|
@@ -47,7 +72,7 @@ module PaystackSdk
|
|
|
47
72
|
# @example
|
|
48
73
|
# ```ruby
|
|
49
74
|
# transactions = client.transactions
|
|
50
|
-
# response = transactions.initiate(
|
|
75
|
+
# response = transactions.initiate(email: "ama@example.com", amount: 10000)
|
|
51
76
|
# ```
|
|
52
77
|
def transactions
|
|
53
78
|
@transactions ||= Resources::Transactions.new(@connection)
|
|
@@ -75,7 +100,7 @@ module PaystackSdk
|
|
|
75
100
|
# @example
|
|
76
101
|
# ```ruby
|
|
77
102
|
# recipients = client.transfer_recipients
|
|
78
|
-
# response = recipients.create(
|
|
103
|
+
# response = recipients.create(type: "nuban", name: "Ama Mensah", account_number: "0123456789", bank_code: "058")
|
|
79
104
|
# ```
|
|
80
105
|
def transfer_recipients
|
|
81
106
|
@transfer_recipients ||= Resources::TransferRecipients.new(@connection)
|
|
@@ -89,7 +114,7 @@ module PaystackSdk
|
|
|
89
114
|
# @example
|
|
90
115
|
# ```ruby
|
|
91
116
|
# transfers = client.transfers
|
|
92
|
-
# response = transfers.create(
|
|
117
|
+
# response = transfers.create(source: "balance", amount: 100_000, recipient: "RCP_xxx", reference: "payout-2025-0001-ama")
|
|
93
118
|
# ```
|
|
94
119
|
def transfers
|
|
95
120
|
@transfers ||= Resources::Transfers.new(@connection)
|
|
@@ -103,38 +128,56 @@ module PaystackSdk
|
|
|
103
128
|
# @example
|
|
104
129
|
# ```ruby
|
|
105
130
|
# banks = client.banks
|
|
106
|
-
# response = banks.list
|
|
131
|
+
# response = banks.list(country: "nigeria")
|
|
107
132
|
# ```
|
|
108
133
|
def banks
|
|
109
134
|
@banks ||= Resources::Banks.new(@connection)
|
|
110
135
|
end
|
|
111
136
|
|
|
112
|
-
# Provides access to the `
|
|
137
|
+
# Provides access to the `Charges` resource.
|
|
113
138
|
#
|
|
114
|
-
# @return [PaystackSdk::Resources::
|
|
115
|
-
# `
|
|
139
|
+
# @return [PaystackSdk::Resources::Charges] An instance of the
|
|
140
|
+
# `Charges` resource.
|
|
116
141
|
#
|
|
117
142
|
# @example
|
|
118
143
|
# ```ruby
|
|
119
|
-
#
|
|
120
|
-
# response =
|
|
144
|
+
# charges = client.charges
|
|
145
|
+
# response = charges.mobile_money(
|
|
146
|
+
# email: "ama@example.com",
|
|
147
|
+
# amount: 10000,
|
|
148
|
+
# mobile_money: {phone: "0551234987", provider: "mtn"}
|
|
149
|
+
# )
|
|
121
150
|
# ```
|
|
122
|
-
def
|
|
123
|
-
@
|
|
151
|
+
def charges
|
|
152
|
+
@charges ||= Resources::Charges.new(@connection)
|
|
124
153
|
end
|
|
125
154
|
|
|
126
|
-
# Provides access to the `
|
|
155
|
+
# Provides access to the `Miscellaneous` resource.
|
|
127
156
|
#
|
|
128
|
-
# @return [PaystackSdk::Resources::
|
|
129
|
-
# `
|
|
157
|
+
# @return [PaystackSdk::Resources::Miscellaneous] An instance of the
|
|
158
|
+
# `Miscellaneous` resource.
|
|
130
159
|
#
|
|
131
160
|
# @example
|
|
132
161
|
# ```ruby
|
|
133
|
-
#
|
|
134
|
-
# response = charges.mobile_money(payload)
|
|
162
|
+
# response = client.miscellaneous.resolve_card_bin(bin: "539983")
|
|
135
163
|
# ```
|
|
136
|
-
def
|
|
137
|
-
@
|
|
164
|
+
def miscellaneous
|
|
165
|
+
@miscellaneous ||= Resources::Miscellaneous.new(@connection)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Provides access to the `Refunds` resource.
|
|
169
|
+
#
|
|
170
|
+
# @return [PaystackSdk::Resources::Refunds] An instance of the
|
|
171
|
+
# `Refunds` resource.
|
|
172
|
+
def refunds
|
|
173
|
+
@refunds ||= Resources::Refunds.new(@connection)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
private
|
|
177
|
+
|
|
178
|
+
# The secret key a connection sends, read from its Authorization header.
|
|
179
|
+
def key_from(connection)
|
|
180
|
+
connection.headers["Authorization"].to_s.delete_prefix("Bearer ")
|
|
138
181
|
end
|
|
139
182
|
end
|
|
140
183
|
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PaystackSdk
|
|
4
|
+
module Middleware
|
|
5
|
+
# Translates low-level Faraday transport failures into SDK errors so that
|
|
6
|
+
# `rescue PaystackSdk::Error` catches them. It sits outside the retry
|
|
7
|
+
# middleware, so it only sees failures that survived all retries.
|
|
8
|
+
class TransportErrors < Faraday::Middleware
|
|
9
|
+
def call(env)
|
|
10
|
+
@app.call(env)
|
|
11
|
+
rescue Faraday::TimeoutError => e
|
|
12
|
+
raise PaystackSdk::TimeoutError, "Request to Paystack timed out: #{e.message}"
|
|
13
|
+
rescue Faraday::ConnectionFailed, Faraday::SSLError => e
|
|
14
|
+
# Connect-phase timeouts (Net::OpenTimeout) surface as ConnectionFailed.
|
|
15
|
+
if e.cause.is_a?(::Timeout::Error)
|
|
16
|
+
raise PaystackSdk::TimeoutError, "Connecting to Paystack timed out: #{e.message}"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
raise PaystackSdk::ConnectionError, "Could not connect to Paystack: #{e.message}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "date"
|
|
4
|
+
require "erb"
|
|
5
|
+
require "json"
|
|
6
|
+
|
|
7
|
+
module PaystackSdk
|
|
8
|
+
# Small helpers resource classes use to turn idiomatic Ruby arguments into exactly what Paystack
|
|
9
|
+
# documents on the wire. They are private to the classes that include them.
|
|
10
|
+
#
|
|
11
|
+
# Ruby code uses snake_case keywords (`per_page:`, `terminal_id:`); the request carries Paystack's
|
|
12
|
+
# names (`perPage`, `terminalid`). Each method names its mapping in one place, with {#to_wire}.
|
|
13
|
+
module RequestHelpers
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
# Escapes a value for use as one segment of a URL path, so a reference or code containing `/`,
|
|
17
|
+
# `?`, `#` or a space cannot change which endpoint is called.
|
|
18
|
+
#
|
|
19
|
+
# `.` and `..` are refused: the URL builder resolves them as relative path steps, so
|
|
20
|
+
# `/customer/..` would call `/`. No Paystack identifier is ever one of them. An empty value is
|
|
21
|
+
# refused too, since it would collapse the segment out of the path.
|
|
22
|
+
#
|
|
23
|
+
# @param segment [#to_s]
|
|
24
|
+
# @param name [String] parameter name, for the error message
|
|
25
|
+
# @return [String]
|
|
26
|
+
# @raise [PaystackSdk::InvalidValueError] If the segment is empty, `.` or `..`
|
|
27
|
+
def escape_path(segment, name: "path segment")
|
|
28
|
+
value = segment.to_s
|
|
29
|
+
raise InvalidValueError.new(name, "must not be empty") if value.empty?
|
|
30
|
+
raise InvalidValueError.new(name, %(must not be "#{value}")) if %w[. ..].include?(value)
|
|
31
|
+
|
|
32
|
+
ERB::Util.url_encode(value)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Drops nil values, keeping `false`, `0` and empty strings, which are real values.
|
|
36
|
+
#
|
|
37
|
+
# @param params [Hash]
|
|
38
|
+
# @return [Hash]
|
|
39
|
+
def compact_params(params)
|
|
40
|
+
params.compact
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Renames Ruby-style keys to the parameter names Paystack documents, drops nils and returns
|
|
44
|
+
# string keys. Keys without a mapping are sent as given.
|
|
45
|
+
#
|
|
46
|
+
# @param params [Hash] e.g. `{per_page: 20, status: "success"}`
|
|
47
|
+
# @param mapping [Hash{Symbol => String}] e.g. `{per_page: "perPage"}`
|
|
48
|
+
# @return [Hash{String => Object}]
|
|
49
|
+
def to_wire(params, mapping)
|
|
50
|
+
compact_params(params).each_with_object({}) do |(key, value), wire|
|
|
51
|
+
wire[(mapping[key] || key).to_s] = value
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Formats a Date, Time or ISO 8601 String for a Paystack date-time parameter.
|
|
56
|
+
#
|
|
57
|
+
# @param value [Date, Time, String, nil]
|
|
58
|
+
# @param name [String] parameter name, for the error message
|
|
59
|
+
# @return [String, nil]
|
|
60
|
+
# @raise [PaystackSdk::InvalidFormatError] If a String is not ISO 8601
|
|
61
|
+
def format_datetime(value, name: "date")
|
|
62
|
+
case value
|
|
63
|
+
when nil then nil
|
|
64
|
+
when Time, DateTime then value.getutc.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
65
|
+
when Date then value.iso8601
|
|
66
|
+
when String
|
|
67
|
+
iso8601?(value) ? value : raise(InvalidFormatError.new(name, "ISO 8601 date or date-time (e.g. 2026-01-31 or 2026-01-31T09:00:00Z)"))
|
|
68
|
+
else raise InvalidFormatError.new(name, "Date, Time or ISO 8601 String")
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Formats a Date, Time or YYYY-MM-DD String for a Paystack date parameter.
|
|
73
|
+
#
|
|
74
|
+
# @param value [Date, Time, String, nil]
|
|
75
|
+
# @param name [String] parameter name, for the error message
|
|
76
|
+
# @return [String, nil]
|
|
77
|
+
# @raise [PaystackSdk::InvalidFormatError] If a String is not a real YYYY-MM-DD date
|
|
78
|
+
def format_date(value, name: "date")
|
|
79
|
+
case value
|
|
80
|
+
when nil then nil
|
|
81
|
+
when Time, Date then value.strftime("%Y-%m-%d")
|
|
82
|
+
when String
|
|
83
|
+
valid = value.match?(/\A\d{4}-\d{2}-\d{2}\z/) && begin
|
|
84
|
+
Date.strptime(value, "%Y-%m-%d")
|
|
85
|
+
rescue
|
|
86
|
+
nil
|
|
87
|
+
end
|
|
88
|
+
valid ? value : raise(InvalidFormatError.new(name, "YYYY-MM-DD"))
|
|
89
|
+
else raise InvalidFormatError.new(name, "Date, Time or YYYY-MM-DD String")
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# For the few fields Paystack documents as "stringified JSON" (for example customer metadata):
|
|
94
|
+
# accepts a Hash or Array and sends the JSON string. Strings pass through unchanged.
|
|
95
|
+
#
|
|
96
|
+
# @param value [Hash, Array, String, nil]
|
|
97
|
+
# @return [String, nil]
|
|
98
|
+
def stringify_json(value)
|
|
99
|
+
case value
|
|
100
|
+
when nil, String then value
|
|
101
|
+
else JSON.generate(value)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def iso8601?(value)
|
|
106
|
+
Time.iso8601(value)
|
|
107
|
+
true
|
|
108
|
+
rescue ArgumentError
|
|
109
|
+
begin
|
|
110
|
+
Date.iso8601(value)
|
|
111
|
+
true
|
|
112
|
+
rescue ArgumentError
|
|
113
|
+
false
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -1,20 +1,170 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Generated by bin/paystack-scaffold from Paystack's OpenAPI spec (PaystackOSS/openapi@d9d444d).
|
|
4
|
+
# Do not edit by hand: regenerate it with `bin/paystack-scaffold Bank`. Hand-written extras go in lib/paystack_sdk/resources/extensions/banks.rb.
|
|
5
|
+
# scaffold-digest: 530fc74fc57bba755180a37c395576bd9fc13c76500eae0fce6da7b1a6740ff9
|
|
6
|
+
|
|
7
|
+
require_relative "base"
|
|
2
8
|
|
|
3
9
|
module PaystackSdk
|
|
4
10
|
module Resources
|
|
5
|
-
|
|
6
|
-
|
|
11
|
+
# Bank operations.
|
|
12
|
+
class Banks < PaystackSdk::Resources::Base
|
|
13
|
+
# Ruby keyword => the parameter name Paystack documents.
|
|
14
|
+
WIRE_NAMES = {per_page: "perPage", next_cursor: "next"}.freeze
|
|
15
|
+
|
|
16
|
+
# List Banks.
|
|
17
|
+
#
|
|
18
|
+
# List banks supported on Paystack
|
|
19
|
+
#
|
|
20
|
+
# @param country [String] The country from which to obtain the list of supported banks One of: ghana, kenya, nigeria, south africa.
|
|
21
|
+
# @param currency [String] The currency of the banks to list. One of: GHS, KES, NGN, ZAR, USD.
|
|
22
|
+
# @param use_cursor [Boolean] A flag to indicate if cursor based pagination should be used
|
|
23
|
+
# @param per_page [Integer] The number of records to fetch per request
|
|
24
|
+
# @param page [Integer] The offset to retrieve data from
|
|
25
|
+
# @param next_cursor [String] An alphanumeric value returned for every cursor based retrieval, used to retrieve the next set of data
|
|
26
|
+
# @param previous [String] An alphanumeric value returned for every cursor based retrieval, used to retrieve the previous set of data
|
|
27
|
+
# @param pay_with_bank_transfer [Boolean] A flag to filter for available banks a customer can make a transfer to complete a payment
|
|
28
|
+
# @param pay_with_bank [Boolean] A flag to filter for banks a customer can pay directly from
|
|
29
|
+
# @param enabled_for_verification [Boolean] A flag to filter the banks that are supported for account verification in South Africa.
|
|
30
|
+
# @param gateway [String] The type of gateway for a Nigerian bank One of: emandate, digitalbankmandate.
|
|
31
|
+
# @param type [String] Type of financial channel One of: ghipss, mobile_money, nuban, kepss, basa.
|
|
32
|
+
# @param include_nip_sort_code [Boolean] A flag that returns Nigerian banks with their NIP institution code.
|
|
33
|
+
# @return [PaystackSdk::Response] The response from the Paystack API.
|
|
34
|
+
# @raise [PaystackSdk::Error] If a parameter is invalid or the API request fails.
|
|
7
35
|
# @see https://paystack.com/docs/api/miscellaneous/#bank
|
|
8
|
-
def list(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
36
|
+
def list(
|
|
37
|
+
country: nil,
|
|
38
|
+
currency: nil,
|
|
39
|
+
use_cursor: nil,
|
|
40
|
+
per_page: nil,
|
|
41
|
+
page: nil,
|
|
42
|
+
next_cursor: nil,
|
|
43
|
+
previous: nil,
|
|
44
|
+
pay_with_bank_transfer: nil,
|
|
45
|
+
pay_with_bank: nil,
|
|
46
|
+
enabled_for_verification: nil,
|
|
47
|
+
gateway: nil,
|
|
48
|
+
type: nil,
|
|
49
|
+
include_nip_sort_code: nil
|
|
50
|
+
)
|
|
51
|
+
validate_allowed_values!(
|
|
52
|
+
value: country,
|
|
53
|
+
allowed_values: ["ghana", "kenya", "nigeria", "south africa"],
|
|
54
|
+
name: "country"
|
|
55
|
+
)
|
|
56
|
+
validate_allowed_values!(
|
|
57
|
+
value: currency,
|
|
58
|
+
allowed_values: %w[GHS KES NGN ZAR USD],
|
|
59
|
+
name: "currency"
|
|
60
|
+
)
|
|
61
|
+
validate_positive_integer!(value: per_page, name: "perPage")
|
|
62
|
+
validate_positive_integer!(value: page, name: "page")
|
|
63
|
+
validate_allowed_values!(
|
|
64
|
+
value: gateway,
|
|
65
|
+
allowed_values: %w[emandate digitalbankmandate],
|
|
66
|
+
name: "gateway"
|
|
67
|
+
)
|
|
68
|
+
validate_allowed_values!(
|
|
69
|
+
value: type,
|
|
70
|
+
allowed_values: %w[ghipss mobile_money nuban kepss basa],
|
|
71
|
+
name: "type"
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
wire_query = to_wire(
|
|
75
|
+
{
|
|
76
|
+
country:,
|
|
77
|
+
currency:,
|
|
78
|
+
use_cursor:,
|
|
79
|
+
per_page:,
|
|
80
|
+
page:,
|
|
81
|
+
next_cursor:,
|
|
82
|
+
previous:,
|
|
83
|
+
pay_with_bank_transfer:,
|
|
84
|
+
pay_with_bank:,
|
|
85
|
+
enabled_for_verification:,
|
|
86
|
+
gateway:,
|
|
87
|
+
type:,
|
|
88
|
+
include_nip_sort_code:
|
|
89
|
+
},
|
|
90
|
+
WIRE_NAMES
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
handle_response(@connection.get("/bank", wire_query))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Resolve Account Number.
|
|
97
|
+
#
|
|
98
|
+
# Resolve an account number to confirm the name associated with it
|
|
99
|
+
#
|
|
100
|
+
# @param account_number [String] The account number of interest
|
|
101
|
+
# @param bank_code [String] The bank code associated with the account number
|
|
102
|
+
# @return [PaystackSdk::Response] The response from the Paystack API.
|
|
103
|
+
# @raise [PaystackSdk::Error] If a parameter is invalid or the API request fails.
|
|
104
|
+
# @see https://paystack.com/docs/api/verification/#resolve-account
|
|
105
|
+
def resolve_account_number(account_number:, bank_code:)
|
|
106
|
+
validate_presence!(value: account_number, name: "account_number")
|
|
107
|
+
validate_presence!(value: bank_code, name: "bank_code")
|
|
108
|
+
|
|
109
|
+
wire_query = to_wire({account_number:, bank_code:}, WIRE_NAMES)
|
|
110
|
+
|
|
111
|
+
handle_response(@connection.get("/bank/resolve", wire_query))
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Validate Bank Account.
|
|
115
|
+
#
|
|
116
|
+
# Confirm the authenticity of a customer's account number before sending money
|
|
117
|
+
#
|
|
118
|
+
# @param account_name [String] Customer's first and last name registered with their bank
|
|
119
|
+
# @param account_number [String] Customer's account number
|
|
120
|
+
# @param account_type [String] The type of the customer's account number One of: personal, business.
|
|
121
|
+
# @param bank_code [String] The bank code of the customer’s bank.
|
|
122
|
+
# @param country_code [String] The two digit ISO code of the customer’s bank
|
|
123
|
+
# @param document_type [String] Customer’s mode of identity One of: identityNumber, passportNumber, businessRegistrationNumber.
|
|
124
|
+
# @param document_number [String] Customer’s mode of identity number
|
|
125
|
+
# @return [PaystackSdk::Response] The response from the Paystack API.
|
|
126
|
+
# @raise [PaystackSdk::Error] If a parameter is invalid or the API request fails.
|
|
127
|
+
# @see https://paystack.com/docs/api/verification/#validate-account
|
|
128
|
+
def validate_account(
|
|
129
|
+
account_name:,
|
|
130
|
+
account_number:,
|
|
131
|
+
account_type:,
|
|
132
|
+
bank_code:,
|
|
133
|
+
country_code:,
|
|
134
|
+
document_type:,
|
|
135
|
+
document_number: nil
|
|
136
|
+
)
|
|
137
|
+
validate_presence!(value: account_name, name: "account_name")
|
|
138
|
+
validate_presence!(value: account_number, name: "account_number")
|
|
139
|
+
validate_presence!(value: account_type, name: "account_type")
|
|
140
|
+
validate_allowed_values!(
|
|
141
|
+
value: account_type,
|
|
142
|
+
allowed_values: %w[personal business],
|
|
143
|
+
name: "account_type"
|
|
144
|
+
)
|
|
145
|
+
validate_presence!(value: bank_code, name: "bank_code")
|
|
146
|
+
validate_presence!(value: country_code, name: "country_code")
|
|
147
|
+
validate_presence!(value: document_type, name: "document_type")
|
|
148
|
+
validate_allowed_values!(
|
|
149
|
+
value: document_type,
|
|
150
|
+
allowed_values: %w[identityNumber passportNumber businessRegistrationNumber],
|
|
151
|
+
name: "document_type"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
wire_body = to_wire(
|
|
155
|
+
{
|
|
156
|
+
account_name:,
|
|
157
|
+
account_number:,
|
|
158
|
+
account_type:,
|
|
159
|
+
bank_code:,
|
|
160
|
+
country_code:,
|
|
161
|
+
document_type:,
|
|
162
|
+
document_number:
|
|
163
|
+
},
|
|
164
|
+
WIRE_NAMES
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
handle_response(@connection.post("/bank/validate", wire_body))
|
|
18
168
|
end
|
|
19
169
|
end
|
|
20
170
|
end
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require_relative "../response"
|
|
4
4
|
require_relative "../client"
|
|
5
5
|
require_relative "../validations"
|
|
6
|
+
require_relative "../request_helpers"
|
|
6
7
|
require_relative "../utils/connection_utils"
|
|
7
8
|
|
|
8
9
|
module PaystackSdk
|
|
@@ -11,6 +12,7 @@ module PaystackSdk
|
|
|
11
12
|
# It provides shared functionality, such as handling API responses.
|
|
12
13
|
class Base
|
|
13
14
|
include PaystackSdk::Validations
|
|
15
|
+
include PaystackSdk::RequestHelpers
|
|
14
16
|
include PaystackSdk::Utils::ConnectionUtils
|
|
15
17
|
|
|
16
18
|
# Initializes a new `Base` instance.
|
|
@@ -29,8 +31,8 @@ module PaystackSdk
|
|
|
29
31
|
#
|
|
30
32
|
# @example With default connection (requires PAYSTACK_SECRET_KEY environment variable)
|
|
31
33
|
# resource = PaystackSdk::Resources::SomeResource.new
|
|
32
|
-
def initialize(connection = nil, secret_key: nil)
|
|
33
|
-
@connection = initialize_connection(connection, secret_key: secret_key)
|
|
34
|
+
def initialize(connection = nil, secret_key: nil, **options)
|
|
35
|
+
@connection = initialize_connection(connection, secret_key: secret_key, **options)
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
private
|