flutterwave 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 273fe5aaf4f8f929e7f3579a2e3862d016704027
4
+ data.tar.gz: 7658f624f764bd070c708b85e1cabf983298a6bd
5
+ SHA512:
6
+ metadata.gz: 41d08641f6303ed74ec7a8c1908df3b972a01e0105cc5a6afd3fe7c980d83978fbc4dd642627b1afb1216350af8a2494e568b477717faab0e262da3f07f86f6e
7
+ data.tar.gz: 9c544fd6958d10121fcbb90ebea9e1babd2a56099dfba44198cb96890f89a5957a5fda44061f6f4e6e1882c0cdc7a346c3a17bd6a8b9a8b2c527f741b6ea2869
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.2.3
5
+ before_install: gem install bundler -v 1.12.5
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in flutterwave.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Tobi Oduah
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,102 @@
1
+ # Flutterwave
2
+
3
+ Ruby SDK for convenient access to the Flutterwave API from Ruby applications. Full API documentation avaialable at https://www.flutterwave.com/documentation
4
+
5
+ ## Installation
6
+
7
+ gem install flutterwave
8
+
9
+ ## Usage
10
+
11
+ The library needs to be configured with your merchant key and API key. These are accessible from the Settings panel at https://www.flutterwavedev.com/
12
+
13
+ To initialize the Ruby client:
14
+
15
+ ```ruby
16
+ require 'flutterwave'
17
+
18
+ merchant_key = 'tk_aT0BPO14Rs'
19
+ api_key = 'tk_ybh0luGWQbM04Is15lXh'
20
+ client = Flutterwave::Client.new(merchant_key, api_key)
21
+ ```
22
+
23
+ ## API operations
24
+ All API operations are performed through the client instance. API responses are used to initialize a response class that allows direct access to JSON keys as methods. Arguments to operation methods adapt the same signature as sample requests to the API endpoint. For instance, an API call that returns:
25
+
26
+ ```json
27
+ {
28
+ "data": {
29
+ "responsecode": "02",
30
+ "responsemessage": "Successful, pending OTP validation",
31
+ "transactionreference": "ABC1234444"
32
+ },
33
+ "status": "success"
34
+ }
35
+ ```
36
+ Gets initialized as a `Flutterwave::Response` object with method keys - `responsecode`, `responsemessage`, `transactionreference`, `successful?`, `failed?`
37
+
38
+ ## Examples
39
+ An example using the wrapper for accessing https://www.flutterwave.com/documentation/alternative-payments/
40
+ The resend-otp operation could be accessed through this sample:
41
+
42
+ ```ruby
43
+ client = Flutterwave::Client.new('sample_merchant_key', 'sample_api_key')
44
+ response = client.account.resend({
45
+ validateoption: 'SMS',
46
+ transactionreference: 'FLW02391188'
47
+ })
48
+
49
+ print response.responsemessage if response.successful?
50
+ ```
51
+
52
+ The method arguments to the resend method match the same hash-signature as the request sample at https://www.flutterwave.com/documentation/alternative-payments/#resend-otp. Response from the API is used to construct an instance of `Flutterwave::Response` which makes keys in the `data` hash accessible as methods.
53
+
54
+ ## Banks Listing
55
+ The only operation that does not follow the description above is when obtaining listing of banks, alongside their codes and names. To ease operation with the listing, a `Flutterwave::Bank` object is created for each bank object returned by the API. The `Flutterwave::BankAPI` also comes with some helper methods that help find a bank by code, or by a regex matching the bank's name. An example usage is described below:
56
+
57
+ ```ruby
58
+ client = Flutterwave::Client.new('sample_merchant_key', 'sample_api_key')
59
+ all_banks = client.bank.list
60
+ names_of_all_banks = all_banks.inject([]) { |list, bank| list << bank.name }
61
+
62
+ p names_of_all_banks # => ["Fidelity Bank", "Heritage"..."Unity Bank"]
63
+
64
+ # sample for finding a bank by name
65
+ access_bank_code = client.bank.find_by_name('access').code # => '044'
66
+
67
+ # sample for finding a bank by code
68
+ bank_name = client.bank.find_by_code('058').name # => GTBank Plc
69
+ ```
70
+
71
+ ## Mappings (API to Method)
72
+ Each method has the corresponding API link as a comment above the method signature. To access details about the arguments to the method, please see the tests for that class, or visit the API link.
73
+
74
+ ## Development
75
+
76
+ Run all tests:
77
+
78
+ bundle exec rake
79
+
80
+ Run a single test suite:
81
+
82
+ bundle exec rake TEST=test/pay_test.rb
83
+
84
+ ## Contributing
85
+
86
+ 1. Fork it by visiting - https://github.com/0duaht/flutterwave-ruby/fork
87
+
88
+ 2. Create your feature branch
89
+
90
+ $ git checkout -b new_feature
91
+
92
+ 3. Contribute to code
93
+
94
+ 4. Commit changes made
95
+
96
+ $ git commit -a -m 'descriptive_message_about_change'
97
+
98
+ 5. Push to branch created
99
+
100
+ $ git push origin new_feature
101
+
102
+ 6. Then, create a new Pull Request
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "flutterwave"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'flutterwave/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'flutterwave'
8
+ spec.version = Flutterwave::VERSION
9
+ spec.authors = ['Tobi Oduah']
10
+ spec.email = ['tobi.oduah@andela.com']
11
+
12
+ spec.summary = 'Ruby client for interacting with Flutterwave APIs'
13
+ spec.homepage = 'https://github.com/0duaht/flutterwave-ruby'
14
+ spec.license = 'MIT'
15
+
16
+ if spec.respond_to?(:metadata)
17
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
+ else
19
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
20
+ end
21
+
22
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ spec.bindir = 'exe'
24
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
+ spec.require_paths = ['lib']
26
+
27
+ spec.add_development_dependency 'bundler', '~> 1.12'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'minitest', '~> 5.0'
30
+ spec.add_development_dependency 'faker'
31
+ spec.add_development_dependency 'webmock'
32
+ end
@@ -0,0 +1,2 @@
1
+ require 'flutterwave/version'
2
+ require 'flutterwave/client'
@@ -0,0 +1,161 @@
1
+ require 'flutterwave/response'
2
+
3
+ module Flutterwave
4
+ class Account
5
+ include Flutterwave::Helpers
6
+ attr_accessor :client, :options
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ # https://www.flutterwave.com/documentation/alternative-payments-recurrent/#initiate
13
+ def initiate_recurrent(options = {})
14
+ @options = options
15
+
16
+ request_params = {
17
+ accountNumber: encrypt(:accountNumber),
18
+ merchantid: client.merchant_key
19
+ }
20
+
21
+ response = post(
22
+ Flutterwave::Utils::Constants::ACCOUNT[:initiate_recurrent_url],
23
+ request_params
24
+ )
25
+
26
+ Flutterwave::Response.new(response)
27
+ end
28
+
29
+ # https://www.flutterwave.com/documentation/alternative-payments-recurrent/#validate
30
+ def validate_recurrent(options = {})
31
+ @options = options
32
+
33
+ request_params = {
34
+ accountNumber: encrypt(:accountNumber),
35
+ otp: encrypt(:otp),
36
+ reference: encrypt(:reference),
37
+ billingamount: encrypt(:billingamount),
38
+ debitnarration: encrypt(:debitnarration),
39
+ merchantid: client.merchant_key
40
+ }
41
+
42
+ response = post(
43
+ Flutterwave::Utils::Constants::ACCOUNT[:validate_recurrent_url],
44
+ request_params
45
+ )
46
+
47
+ Flutterwave::Response.new(response)
48
+ end
49
+
50
+ # https://www.flutterwave.com/documentation/alternative-payments-recurrent/#initiate
51
+ def charge_recurrent(options = {})
52
+ @options = options
53
+
54
+ request_params = {
55
+ accountToken: encrypt(:accountToken),
56
+ billingamount: encrypt(:billingamount),
57
+ debitnarration: encrypt(:debitnarration),
58
+ merchantid: client.merchant_key
59
+ }
60
+
61
+ response = post(
62
+ Flutterwave::Utils::Constants::ACCOUNT[:charge_recurrent_url],
63
+ request_params
64
+ )
65
+
66
+ Flutterwave::Response.new(response)
67
+ end
68
+
69
+ # https://www.flutterwave.com/documentation/alternative-payments/#charge-ii
70
+ def charge(options = {})
71
+ @options = options
72
+ options[:country] ||= 'NG'
73
+
74
+ request_params = {
75
+ validateoption: encrypt(:validateoption),
76
+ accountnumber: encrypt(:accountnumber),
77
+ bankcode: encrypt(:bankcode),
78
+ amount: encrypt(:amount),
79
+ currency: encrypt(:currency),
80
+ firstname: encrypt(:firstname),
81
+ lastname: encrypt(:lastname),
82
+ email: encrypt(:email),
83
+ narration: encrypt(:narration),
84
+ transactionreference: encrypt(:transactionreference),
85
+ merchantid: client.merchant_key
86
+ }
87
+
88
+ request_params[:passcode] = encrypt(:passcode) if options[:passcode]
89
+
90
+ response = post(
91
+ Flutterwave::Utils::Constants::ACCOUNT[:charge_url],
92
+ request_params
93
+ )
94
+
95
+ Flutterwave::Response.new(response)
96
+ end
97
+
98
+ # https://www.flutterwave.com/documentation/alternative-payments/#resend-otp
99
+ def resend(options = {})
100
+ @options = options
101
+
102
+ request_params = {
103
+ validateoption: encrypt(:validateoption),
104
+ transactionreference: encrypt(:transactionreference),
105
+ merchantid: client.merchant_key
106
+ }
107
+
108
+ response = post(
109
+ Flutterwave::Utils::Constants::ACCOUNT[:resend_url],
110
+ request_params
111
+ )
112
+
113
+ Flutterwave::Response.new(response)
114
+ end
115
+
116
+ # https://www.flutterwave.com/documentation/alternative-payments/#validate-ii
117
+ def validate(options = {})
118
+ @options = options
119
+
120
+ request_params = {
121
+ otp: encrypt(:otp),
122
+ transactionreference: encrypt(:transactionreference),
123
+ merchantid: client.merchant_key
124
+ }
125
+
126
+ response = post(
127
+ Flutterwave::Utils::Constants::ACCOUNT[:validate_url],
128
+ request_params
129
+ )
130
+
131
+ Flutterwave::Response.new(response)
132
+ end
133
+
134
+ # https://www.flutterwave.com/documentation/alternative-payments/#validate-ii-alt
135
+ def alt_validate(options = {})
136
+ @options = options
137
+
138
+ request_params = {
139
+ otp: encrypt(:otp),
140
+ phonenumber: encrypt(:phonenumber),
141
+ merchantid: client.merchant_key
142
+ }
143
+
144
+ response = post(
145
+ Flutterwave::Utils::Constants::ACCOUNT[:alt_validate_url],
146
+ request_params
147
+ )
148
+
149
+ Flutterwave::Response.new(response)
150
+ end
151
+
152
+ def encrypt(key)
153
+ plain_text = options[key].to_s
154
+ raise Flutterwave::Utils::MissingKeyError.new(
155
+ "#{key.capitalize} key required!"
156
+ ) if plain_text.empty?
157
+
158
+ encrypt_data(plain_text, client.api_key)
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,83 @@
1
+ module Flutterwave
2
+ class ACH
3
+ include Flutterwave::Helpers
4
+ attr_accessor :client, :options
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ # https://www.flutterwave.com/documentation/ach-payments/#get-institutions
11
+ def list
12
+ response = post(
13
+ Flutterwave::Utils::Constants::ACH[:list_url],
14
+ merchantid: client.merchant_key
15
+ )
16
+
17
+ Flutterwave::Response.new(response)
18
+ end
19
+
20
+ # https://www.flutterwave.com/documentation/ach-payments/#get-institution-by-id
21
+ def find_by_id(options = {})
22
+ @options = options
23
+
24
+ response = post(
25
+ Flutterwave::Utils::Constants::ACH[:id_url],
26
+ institutionid: encrypt(:id),
27
+ merchantid: client.merchant_key
28
+ )
29
+
30
+ Flutterwave::Response.new(response)
31
+ end
32
+
33
+ # https://www.flutterwave.com/documentation/ach-payments/#add-user
34
+ def add_user(options = {})
35
+ @options = options
36
+
37
+ request_params = {
38
+ username: encrypt(:username),
39
+ password: encrypt(:password),
40
+ email: encrypt(:email),
41
+ institution: encrypt(:institution),
42
+ merchantid: client.merchant_key
43
+ }
44
+
45
+ request_params[:pin] = encrypt(:pin) if options[:pin]
46
+
47
+ response = post(
48
+ Flutterwave::Utils::Constants::ACH[:add_user_url],
49
+ request_params
50
+ )
51
+
52
+ Flutterwave::Response.new(response)
53
+ end
54
+
55
+ # https://www.flutterwave.com/documentation/ach-payments/#charge
56
+ def charge(options = {})
57
+ @options = options
58
+
59
+ response = post(
60
+ Flutterwave::Utils::Constants::ACH[:charge_url],
61
+ publictoken: encrypt(:publictoken),
62
+ accountid: encrypt(:accountid),
63
+ custid: encrypt(:custid),
64
+ narration: encrypt(:narration),
65
+ trxreference: encrypt(:trxreference),
66
+ amount: encrypt(:amount),
67
+ currency: encrypt(:currency),
68
+ merchantid: client.merchant_key
69
+ )
70
+
71
+ Flutterwave::Response.new(response)
72
+ end
73
+
74
+ def encrypt(key)
75
+ plain_text = options[key].to_s
76
+ raise Flutterwave::Utils::MissingKeyError.new(
77
+ "#{key.capitalize} key required!"
78
+ ) if plain_text.empty?
79
+
80
+ encrypt_data(plain_text, client.api_key)
81
+ end
82
+ end
83
+ end