flutterwave 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ module Flutterwave
2
+ class IP
3
+ attr_accessor :client
4
+
5
+ def initialize(client)
6
+ @client = client
7
+ end
8
+
9
+ def check(options = {})
10
+ raise Flutterwave::Utils::MissingKeyError.new(
11
+ 'IP key required!'
12
+ ) unless options[:ip]
13
+
14
+ response = post(
15
+ Flutterwave::Utils::Constants::IP[:check_url],
16
+ ip: options[:ip]
17
+ )
18
+
19
+ Flutterwave::Response.new(response)
20
+ end
21
+
22
+ def post(url, data)
23
+ Flutterwave::Utils::NetworkManager.post(url, data)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,121 @@
1
+ require 'flutterwave/response'
2
+ require 'time'
3
+
4
+ module Flutterwave
5
+ class Pay
6
+ include Flutterwave::Helpers
7
+ attr_accessor :client, :options
8
+
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ # https://www.flutterwave.com/documentation/pay/ - Link Account
14
+ def link(options = {})
15
+ @options = options
16
+ options[:country] ||= 'NG'
17
+
18
+ response = post(
19
+ Flutterwave::Utils::Constants::PAY[:link_url],
20
+ merchantid: client.merchant_key,
21
+ accountnumber: encrypt(:accountnumber),
22
+ country: encrypt(:country)
23
+ )
24
+
25
+ Flutterwave::Response.new(response)
26
+ end
27
+
28
+ # https://www.flutterwave.com/documentation/pay/ - Validate Step 1
29
+ def validate(options = {})
30
+ @options = options
31
+ options[:country] ||= 'NG'
32
+
33
+ response = post(
34
+ Flutterwave::Utils::Constants::PAY[:validate_url],
35
+ merchantid: client.merchant_key,
36
+ otp: encrypt(:otp),
37
+ relatedreference: encrypt(:relatedreference),
38
+ otptype: encrypt(:otptype),
39
+ country: encrypt(:country)
40
+ )
41
+
42
+ Flutterwave::Response.new(response)
43
+ end
44
+
45
+ # https://www.flutterwave.com/documentation/pay/ - Send
46
+ def send(options = {})
47
+ @options = options
48
+ options[:country] ||= 'NG'
49
+
50
+ response = post(
51
+ Flutterwave::Utils::Constants::PAY[:send_url],
52
+ merchantid: client.merchant_key,
53
+ accounttoken: encrypt(:accounttoken),
54
+ destbankcode: encrypt(:destbankcode),
55
+ currency: encrypt(:currency),
56
+ country: encrypt(:country),
57
+ transferamount: encrypt(:transferamount),
58
+ uniquereference: encrypt(:uniquereference),
59
+ narration: encrypt(:narration),
60
+ recipientname: encrypt(:recipientname),
61
+ sendername: encrypt(:sendername),
62
+ recipientaccount: encrypt(:recipientaccount)
63
+ )
64
+
65
+ Flutterwave::Response.new(response)
66
+ end
67
+
68
+ # https://www.flutterwave.com/documentation/pay/ - Get Linked Accounts
69
+ def linked_accounts(options = {})
70
+ @options = options
71
+ options[:country] ||= 'NG'
72
+
73
+ response = post(
74
+ Flutterwave::Utils::Constants::PAY[:linked_accounts_url],
75
+ merchantid: client.merchant_key,
76
+ country: encrypt(:country)
77
+ )
78
+
79
+ Flutterwave::Response.new(response)
80
+ end
81
+
82
+ # https://www.flutterwave.com/documentation/pay/ - Unlink Account
83
+ def unlink(options = {})
84
+ @options = options
85
+ options[:country] ||= 'NG'
86
+
87
+ response = post(
88
+ Flutterwave::Utils::Constants::PAY[:unlink_url],
89
+ merchantid: client.merchant_key,
90
+ accountnumber: encrypt(:accountnumber),
91
+ country: encrypt(:country)
92
+ )
93
+
94
+ Flutterwave::Response.new(response)
95
+ end
96
+
97
+ # https://www.flutterwave.com/documentation/pay/ - Get Transaction Status
98
+ def status(options = {})
99
+ @options = options
100
+ options[:country] ||= 'NG'
101
+
102
+ response = post(
103
+ Flutterwave::Utils::Constants::PAY[:status_url],
104
+ merchantid: client.merchant_key,
105
+ uniquereference: encrypt(:uniquereference),
106
+ country: encrypt(:country)
107
+ )
108
+
109
+ Flutterwave::Response.new(response)
110
+ end
111
+
112
+ def encrypt(key)
113
+ plain_text = options[key].to_s
114
+ raise Flutterwave::Utils::MissingKeyError.new(
115
+ "#{key.capitalize} key required!"
116
+ ) if plain_text.empty?
117
+
118
+ encrypt_data(plain_text, client.api_key)
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,28 @@
1
+ module Flutterwave
2
+ class Response
3
+ attr_accessor :response
4
+
5
+ def initialize(response)
6
+ @response = response ? OpenStruct.new(response['data']) : OpenStruct.new({})
7
+ end
8
+
9
+ def successful?
10
+ (try('responseCode') || try('responsecode')) == '00'
11
+ end
12
+
13
+ def failed?
14
+ !successful?
15
+ end
16
+
17
+ def method_missing(method_name, *args)
18
+ return response.send(method_name, *args) if response.respond_to?(method_name)
19
+ super
20
+ end
21
+
22
+ def try(method_name)
23
+ instance_eval method_name
24
+ rescue NameError
25
+ nil
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,64 @@
1
+ module Flutterwave
2
+ module Utils
3
+ module Constants
4
+ BASE_URL = 'http://staging1flutterwave.co:8080'.freeze
5
+ KEY = 'tk_0f86a4ef436f76faab1d3'.freeze
6
+
7
+ BANK = {
8
+ list_url: '/pwc/rest/fw/banks'
9
+ }.freeze
10
+
11
+ ACH = {
12
+ list_url: '/pwc/rest/card/mvva/institutions',
13
+ id_url: '/pwc/rest/card/mvva/institutions/id',
14
+ add_user_url: '/pwc/rest/card/mvva/adduser',
15
+ charge_url: '/pwc/rest/card/mvva/chargeach'
16
+ }.freeze
17
+
18
+ PAY = {
19
+ link_url: '/pwc/rest/pay/linkaccount',
20
+ validate_url: '/pwc/rest/pay/linkaccount/validate',
21
+ linked_accounts_url: '/pwc/rest/pay/getlinkedaccounts',
22
+ send_url: '/pwc/rest/pay/send',
23
+ unlink_url: '/pwc/rest/pay/unlinkaccount',
24
+ status_url: '/pwc/rest/pay/status'
25
+ }.freeze
26
+
27
+ BVN = {
28
+ verify_url: '/pwc/rest/bvn/verify/',
29
+ resend_url: '/pwc/rest/bvn/resendotp/',
30
+ validate_url: '/pwc/rest/bvn/validate/'
31
+ }.freeze
32
+
33
+ BIN = {
34
+ check_url: '/pwc/rest/fw/check/'
35
+ }.freeze
36
+
37
+ IP = {
38
+ check_url: '/pwc/rest/fw/ipcheck'
39
+ }.freeze
40
+
41
+ CARD = {
42
+ tokenize_url: '/pwc/rest/card/mvva/tokenize',
43
+ preauthorize_url: '/pwc/rest/card/mvva/preauthorize',
44
+ capture_url: '/pwc/rest/card/mvva/capture',
45
+ refund_url: '/pwc/rest/card/mvva/refund',
46
+ void_url: '/pwc/rest/card/mvva/void',
47
+ enquiry_url: '/pwc/rest/card/mvva/cardenquiry',
48
+ validate_enquiry_url: '/pwc/rest/card/mvva/cardenquiry/validate',
49
+ charge_url: '/pwc/rest/card/mvva/pay',
50
+ verify_url: '/pwc/rest/card/mvva/status'
51
+ }.freeze
52
+
53
+ ACCOUNT = {
54
+ initiate_recurrent_url: '/pwc/rest/recurrent/account',
55
+ charge_url: '/pwc/rest/account/pay',
56
+ charge_recurrent_url: '/pwc/rest/recurrent/account/charge',
57
+ validate_url: '/pwc/rest/account/pay/validate',
58
+ validate_recurrent_url: '/pwc/rest/recurrent/account/validate',
59
+ alt_validate_url: '/pwc/rest/accessbank/ussd/validate',
60
+ resend_url: '/pwc/rest/account/pay/resendotp'
61
+ }.freeze
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,37 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ module Flutterwave
5
+ module Utils
6
+ module EncryptionManager
7
+ KEY = Flutterwave::Utils::Constants::KEY
8
+
9
+ def self.encrypt(text, key = KEY)
10
+ key = digest(key)
11
+ cipher = OpenSSL::Cipher::Cipher.new('des-ede3')
12
+ cipher.encrypt
13
+ cipher.key = key
14
+ cipher_text = cipher.update(text.to_s)
15
+ cipher_text << cipher.final
16
+
17
+ Base64.encode64(cipher_text).gsub(/\n/, '')
18
+ end
19
+
20
+ def self.decrypt(text, key = KEY)
21
+ key = digest(key)
22
+ cipher = OpenSSL::Cipher::Cipher.new('des-ede3')
23
+ cipher.decrypt
24
+ cipher.key = key
25
+ plain_text = cipher.update(Base64.decode64(text.to_s))
26
+
27
+ plain_text << cipher.final
28
+ end
29
+
30
+ def self.digest(key)
31
+ digest = Digest::MD5.digest(key)
32
+
33
+ digest + digest[0, 8]
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,14 @@
1
+ require 'flutterwave/utils/network_manager'
2
+ require 'flutterwave/utils/encryption_manager'
3
+
4
+ module Flutterwave
5
+ module Helpers
6
+ def post(url, data)
7
+ Flutterwave::Utils::NetworkManager.post(url, data)
8
+ end
9
+
10
+ def encrypt_data(plain_text, api_key)
11
+ Flutterwave::Utils::EncryptionManager.encrypt(plain_text, api_key)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ module Flutterwave
2
+ module Utils
3
+ class MissingKeyError < StandardError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,25 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+ require 'flutterwave/utils/constants'
5
+
6
+ module Flutterwave
7
+ module Utils
8
+ module NetworkManager
9
+ BASE_URL = Flutterwave::Utils::Constants::BASE_URL
10
+
11
+ def self.post(url, body)
12
+ uri = URI.parse("#{BASE_URL}#{url}")
13
+ request = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
14
+ request.body = body.to_json
15
+ response = Net::HTTP.start(uri.hostname, uri.port) do |http|
16
+ http.request(request)
17
+ end
18
+
19
+ JSON.parse(response.body)
20
+ rescue SocketError, TypeError, EOFError, JSON::ParserError
21
+ return nil
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Flutterwave
2
+ VERSION = '0.1.1'.freeze
3
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flutterwave
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Tobi Oduah
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-12-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faker
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: webmock
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - tobi.oduah@andela.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".travis.yml"
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - bin/console
97
+ - bin/setup
98
+ - flutterwave.gemspec
99
+ - lib/flutterwave.rb
100
+ - lib/flutterwave/account.rb
101
+ - lib/flutterwave/ach.rb
102
+ - lib/flutterwave/bank.rb
103
+ - lib/flutterwave/bin.rb
104
+ - lib/flutterwave/bvn.rb
105
+ - lib/flutterwave/card.rb
106
+ - lib/flutterwave/client.rb
107
+ - lib/flutterwave/ip.rb
108
+ - lib/flutterwave/pay.rb
109
+ - lib/flutterwave/response.rb
110
+ - lib/flutterwave/utils/constants.rb
111
+ - lib/flutterwave/utils/encryption_manager.rb
112
+ - lib/flutterwave/utils/helpers.rb
113
+ - lib/flutterwave/utils/missing_key_error.rb
114
+ - lib/flutterwave/utils/network_manager.rb
115
+ - lib/flutterwave/version.rb
116
+ homepage: https://github.com/0duaht/flutterwave-ruby
117
+ licenses:
118
+ - MIT
119
+ metadata:
120
+ allowed_push_host: https://rubygems.org
121
+ post_install_message:
122
+ rdoc_options: []
123
+ require_paths:
124
+ - lib
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ requirements:
132
+ - - ">="
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ requirements: []
136
+ rubyforge_project:
137
+ rubygems_version: 2.4.5.1
138
+ signing_key:
139
+ specification_version: 4
140
+ summary: Ruby client for interacting with Flutterwave APIs
141
+ test_files: []