paystack-gateway 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaystackGateway
4
+ # Automate sending money https://paystack.com/docs/api/#transfer
5
+ module Transfers
6
+ include PaystackGateway::RequestModule
7
+
8
+ # Response from POST /transfer endpoint.
9
+ class InitiateTransferResponse < PaystackGateway::Response
10
+ include TransactionResponse
11
+
12
+ delegate :transfer_code, :id, :transferred_at, to: :data
13
+
14
+ def transaction_completed_at
15
+ transferred_at || super
16
+ end
17
+ end
18
+
19
+ # Raised when an error occurs while calling POST /transfer
20
+ class InitiateTransferError < ApiError
21
+ def transaction_failed?
22
+ response_body[:status] == false && http_code == 400
23
+ end
24
+
25
+ def failure_reason
26
+ response_body[:message]
27
+ end
28
+ end
29
+
30
+ api_method def self.initiate_transfer(amount:, recipient_code:, reference:, reason: nil)
31
+ response = use_connection do |connection|
32
+ connection.post(
33
+ '/transfer',
34
+ {
35
+ source: :balance, amount: (amount * 100).to_i, recipient: recipient_code,
36
+ reference: reference, reason: reason,
37
+ }.compact,
38
+ )
39
+ end
40
+ response.tap { |r| r.completed_at = Time.current }
41
+ end
42
+
43
+ # Response from GET /transfer/verify/:reference endpoint.
44
+ class VerifyTransferResponse < InitiateTransferResponse; end
45
+
46
+ # Raised when an error occurs while calling GET /transfer/verify/:reference
47
+ class VerifyTransferError < ApiError
48
+ def transaction_not_found?
49
+ response_body[:status] == false && response_body[:message].match?(/transfer not found/i)
50
+ end
51
+ end
52
+
53
+ api_method def self.verify_transfer(reference:)
54
+ use_connection do |connection|
55
+ connection.get("/transfer/verify/#{reference}")
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaystackGateway
4
+ # Perform KYC processes https://paystack.com/docs/api/#verification
5
+ module Verification
6
+ include PaystackGateway::RequestModule
7
+
8
+ # Response from GET /bank/resolve endpoint.
9
+ class ResolveAccountNumberResponse < PaystackGateway::Response
10
+ delegate :account_name, :bank_id, to: :data
11
+
12
+ def account_valid?
13
+ status && account_name.present?
14
+ end
15
+ end
16
+
17
+ # Raised when an error occurs while calling /bank/resolve
18
+ class ResolveAccountNumberError < ApiError
19
+ def invalid_account?
20
+ http_code == 422 && response_body[:status] == false
21
+ end
22
+ end
23
+
24
+ api_method def self.resolve_account_number(account_number:, bank_code:)
25
+ use_connection(cache_options: {}) do |connection|
26
+ connection.get(
27
+ '/bank/resolve',
28
+ { account_number: account_number, bank_code: bank_code },
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PaystackGateway
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/security_utils'
4
+
5
+ module PaystackGateway
6
+ # Webhooks
7
+ module Webhooks
8
+ # https://paystack.com/docs/payments/webhooks/#ip-whitelisting
9
+ WEBHOOK_IPS = %w[52.31.139.75 52.49.173.169 52.214.14.220].freeze
10
+ WEBHOOK_IP_ADDRESSES = WEBHOOK_IPS.map { |addr| IPAddr.new(addr) }
11
+
12
+ # Wrapper for webhook responses from Paystack.
13
+ class WebhookResponse < PaystackGateway::Response
14
+ property :event
15
+ end
16
+
17
+ def self.parse_webhook(parsed_body)
18
+ WebhookResponse.new(parsed_body.deep_symbolize_keys)
19
+ end
20
+
21
+ # https://paystack.com/docs/payments/webhooks/#signature-validation
22
+ def self.valid_webhook?(request_headers, request_body)
23
+ request_signature = request_headers['X-Paystack-Signature']
24
+ return false if request_signature.blank?
25
+
26
+ calculated_signature = OpenSSL::HMAC.hexdigest('SHA512', PaystackGateway.secret_key, request_body)
27
+ ActiveSupport::SecurityUtils.secure_compare(request_signature, calculated_signature)
28
+ end
29
+
30
+ def self.valid_ip?(request_ip) = WEBHOOK_IP_ADDRESSES.any? { _1.include?(request_ip) }
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'paystack_gateway/version'
4
+ require 'paystack_gateway/configuration'
5
+ require 'paystack_gateway/api_error'
6
+ require 'paystack_gateway/current'
7
+ require 'paystack_gateway/request_module'
8
+ require 'paystack_gateway/response'
9
+ require 'paystack_gateway/transaction_response'
10
+
11
+ require 'paystack_gateway/customers'
12
+ require 'paystack_gateway/dedicated_virtual_accounts'
13
+ require 'paystack_gateway/miscellaneous'
14
+ require 'paystack_gateway/plans'
15
+ require 'paystack_gateway/refunds'
16
+ require 'paystack_gateway/subaccounts'
17
+ require 'paystack_gateway/transactions'
18
+ require 'paystack_gateway/transfer_recipients'
19
+ require 'paystack_gateway/transfers'
20
+ require 'paystack_gateway/verification'
21
+ require 'paystack_gateway/webhooks'
22
+
23
+ # = PaystackGateway
24
+ module PaystackGateway
25
+ end
@@ -0,0 +1,4 @@
1
+ module PaystackGateway
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paystack-gateway
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - darthrighteous
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-11-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: hashie
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description: |-
56
+ Library providing a collection of easy-to-use modules, methods, and helpers
57
+ for interacting with Paystack’s API endpoints. Includes built-in error
58
+ handling, response parsing and logging. See official paystack docs
59
+ https://paystack.com/docs/api/
60
+ email:
61
+ - ja.ogunniyi@gmail.com
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - ".rubocop.yml"
67
+ - CHANGELOG.md
68
+ - CODE_OF_CONDUCT.md
69
+ - LICENSE.txt
70
+ - README.md
71
+ - Rakefile
72
+ - lib/faraday/response/caching.rb
73
+ - lib/faraday/response/mashify.rb
74
+ - lib/paystack-gateway.rb
75
+ - lib/paystack_gateway.rb
76
+ - lib/paystack_gateway/api_error.rb
77
+ - lib/paystack_gateway/configuration.rb
78
+ - lib/paystack_gateway/current.rb
79
+ - lib/paystack_gateway/customers.rb
80
+ - lib/paystack_gateway/dedicated_virtual_accounts.rb
81
+ - lib/paystack_gateway/miscellaneous.rb
82
+ - lib/paystack_gateway/plans.rb
83
+ - lib/paystack_gateway/refunds.rb
84
+ - lib/paystack_gateway/request_module.rb
85
+ - lib/paystack_gateway/response.rb
86
+ - lib/paystack_gateway/subaccounts.rb
87
+ - lib/paystack_gateway/transaction_response.rb
88
+ - lib/paystack_gateway/transactions.rb
89
+ - lib/paystack_gateway/transfer_recipients.rb
90
+ - lib/paystack_gateway/transfers.rb
91
+ - lib/paystack_gateway/verification.rb
92
+ - lib/paystack_gateway/version.rb
93
+ - lib/paystack_gateway/webhooks.rb
94
+ - sig/paystack_gateway.rbs
95
+ homepage: https://github.com/darthrighteous/paystackgateway
96
+ licenses:
97
+ - MIT
98
+ metadata:
99
+ rubygems_mfa_required: 'true'
100
+ homepage_uri: https://github.com/darthrighteous/paystackgateway
101
+ source_code_uri: https://github.com/darthrighteous/paystackgateway
102
+ changelog_uri: https://github.com/darthrighteous/paystackgateway/blob/master/CHANGELOG.md
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: 3.3.0
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubygems_version: 3.5.3
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Ruby bindings for Paystack’s API https://paystack.com/docs/api
122
+ test_files: []