bitpesa 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8b61dc56d2e2bf5d8dde923b877478868e4bc71c
4
+ data.tar.gz: 165c230d90658805e2c997d30cb43dad7352bd2e
5
+ SHA512:
6
+ metadata.gz: 809a31b9b1c4021cafab72c7010f5a48463f7bba82016d9a12624a5c34a93678635c3df874bb86f406c5f9303518c49c815911ae06a69d4f43f8583792d13fab
7
+ data.tar.gz: aa753b95469e580fe6dc77ccd61a1f6a70a1b5f12e31d3391b0e81277f0537731ab1b137761d274ecf0d63490936a0942b251754969ae993968e0f494c2f47f0
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # BitPesa API wrapper in Ruby
2
+
3
+ See the [API docs](https://api.bitpesa.co/documentation).
4
+
5
+ ## Installation
6
+
7
+ You don't need this source code unless you want to modify the gem. If you just
8
+ want to use the gem, you should run:
9
+
10
+ gem install bitpesa
11
+
12
+ ### Requirements
13
+
14
+ * Ruby 2.3.0 or above
data/bitpesa.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ $:.unshift(File.join(File.dirname(__FILE__), 'lib'))
2
+
3
+ require "bitpesa/version"
4
+
5
+ spec = Gem::Specification.new do |s|
6
+ s.name = "bitpesa"
7
+ s.version = BitPesa::VERSION
8
+ s.required_ruby_version = ">= 2.3.0"
9
+ s.summary = "BitPesa API wrapper in Ruby"
10
+ s.description = "BitPesa is a payment provider. See https://bitpesa.com for details."
11
+ s.author = "Bitbond"
12
+ s.email = "developers@bitbond.com"
13
+ s.homepage = "https://api.bitpesa.co/documentation"
14
+ s.license = "MIT"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- test/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
@@ -0,0 +1,99 @@
1
+ require "base64"
2
+
3
+ module BitPesa
4
+
5
+ class Api
6
+
7
+ class << self
8
+
9
+ # Documents
10
+
11
+ def get_document id
12
+ BitPesa::Client.get("/documents/#{id}")
13
+ end
14
+
15
+ def upload_document file_content, **options
16
+ BitPesa::Client.post("/documents", {document: encode_document(file_content, options)})
17
+ end
18
+
19
+ def list_documents page=1
20
+ BitPesa::Client.get("/documents", page: page)
21
+ end
22
+
23
+ # Senders
24
+
25
+ def get_sender id
26
+ BitPesa::Client.get("/senders/#{id}")
27
+ end
28
+
29
+ def create_sender data
30
+ BitPesa::Client.post("/senders", {sender: data})
31
+ end
32
+
33
+ def update_sender id, data
34
+ BitPesa::Client.patch("/senders", data)
35
+ end
36
+
37
+ def list_senders page=1
38
+ BitPesa::Client.get("/senders", page: page)
39
+ end
40
+
41
+ def delete_sender id
42
+ BitPesa::Client.delete("/senders/#{id}")
43
+ end
44
+
45
+ # Transactions
46
+
47
+ def get_transaction id
48
+ BitPesa::Client.get("/transactions/#{id}")
49
+ end
50
+
51
+ def create_transaction data
52
+ BitPesa::Client.post("/transactions", transaction: data)
53
+ end
54
+
55
+ def list_transactions **filters
56
+ BitPesa::Client.get("/transactions", filters)
57
+ end
58
+
59
+ def calculate_transaction data
60
+ BitPesa::Client.post("/transactions/calculate", transaction: data)
61
+ end
62
+
63
+ def validate_transaction data
64
+ BitPesa::Client.post("/transactions/validate", transaction: data)
65
+ end
66
+
67
+ # Webhooks
68
+
69
+ def get_webhook id
70
+ BitPesa::Client.get("/webhooks/#{id}")
71
+ end
72
+
73
+ def create_webhook url:, events:, **meta_data
74
+ BitPesa::Client.post("/webhooks", {webhook: {url: url, events: events, metadata: meta_data}})
75
+ end
76
+
77
+ def list_webhooks
78
+ BitPesa::Client.get("/webhooks")
79
+ end
80
+
81
+ def delete_webhook id
82
+ BitPesa::Client.delete("/webhooks/#{id}")
83
+ end
84
+
85
+ # Helpers
86
+
87
+ def encode_document file_content, file_name:, mime_type:, **meta_data
88
+ encoded_file_content = "data:" + mime_type + ";base64," + Base64.encode64(file_content)
89
+ {
90
+ upload: encoded_file_content,
91
+ upload_file_name: file_name,
92
+ metadata: meta_data
93
+ }
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,104 @@
1
+ require "securerandom"
2
+ require "net/http"
3
+ require "json"
4
+ require "uri"
5
+
6
+ module BitPesa
7
+
8
+ class Client
9
+
10
+ @host = "api.bitpesa.co"
11
+ @key = "API key"
12
+ @secret = "API secret"
13
+ @base_url = "/v1"
14
+ @timeout = 5
15
+
16
+ class << self
17
+
18
+ attr_accessor :host, :key, :secret, :timeout
19
+ attr_reader :base_url
20
+
21
+ def get(endpoint, payload=nil)
22
+ url = request_url(endpoint)
23
+ url += "?" + URI.encode_www_form(payload) if payload
24
+ request "GET", url
25
+ end
26
+
27
+ def post(endpoint, payload={})
28
+ body = JSON.generate(payload)
29
+ request "POST", request_url(endpoint), body
30
+ end
31
+
32
+ def put(endpoint, payload={})
33
+ body = JSON.generate(payload)
34
+ request "PUT", request_url(endpoint), body
35
+ end
36
+
37
+ def patch(endpoint, payload={})
38
+ body = JSON.generate(payload)
39
+ request "PATCH", request_url(endpoint), body
40
+ end
41
+
42
+ def delete(endpoint)
43
+ request "DELETE", request_url(endpoint)
44
+ end
45
+
46
+ private
47
+
48
+ def request_url endpoint
49
+ base_url + endpoint
50
+ end
51
+
52
+ def generate_nonce
53
+ SecureRandom.uuid
54
+ end
55
+
56
+ def sign *args
57
+ message = args.compact.join("&")
58
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA512.new, secret, message)
59
+ end
60
+
61
+ def request http_method, url, payload=nil
62
+ req = Net::HTTP.const_get(http_method.capitalize).new(url, headers(http_method, url, payload))
63
+ req.body = payload
64
+ handle connection.start{|h| h.request(req)}
65
+ end
66
+
67
+ def headers http_method, url, body
68
+ nonce = generate_nonce
69
+ full_url = "https://" + host + url
70
+ body_hexdigest = OpenSSL::Digest::SHA512.hexdigest(body || "")
71
+ {
72
+ "Content-Type" => "application/json",
73
+ "Accept" => "text/html",
74
+ "User-Agent" => "BitPesa Ruby API Client",
75
+ "Authorization-Nonce" => nonce,
76
+ "Authorization-Key" => key,
77
+ "Authorization-Signature" => sign(nonce, http_method, full_url, body_hexdigest)
78
+ }
79
+ end
80
+
81
+ def connection
82
+ connection = Net::HTTP.new(host, 443)
83
+ connection.open_timeout = timeout
84
+ connection.read_timeout = timeout
85
+ connection.use_ssl = true
86
+ connection.set_debug_output $stderr
87
+ connection
88
+ end
89
+
90
+ def handle response
91
+ case response
92
+ when Net::HTTPSuccess
93
+ (response.body != "" && JSON.parse(response.body)) || true
94
+ when Net::HTTPUnauthorized
95
+ raise BitPesa::Unauthorized.new ""
96
+ else
97
+ raise BitPesa::Error.new response.body
98
+ end
99
+ end
100
+
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,9 @@
1
+ module BitPesa
2
+
3
+ class Unauthorized < StandardError
4
+ end
5
+
6
+ class Error < StandardError
7
+ end
8
+
9
+ end
@@ -0,0 +1,3 @@
1
+ module BitPesa
2
+ VERSION = "0.0.1"
3
+ end
data/lib/bitpesa.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "bitpesa/error"
2
+ require "bitpesa/client"
3
+ require "bitpesa/api"
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bitpesa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Bitbond
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-02 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: BitPesa is a payment provider. See https://bitpesa.com for details.
14
+ email: developers@bitbond.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - Gemfile
20
+ - README.md
21
+ - bitpesa.gemspec
22
+ - lib/bitpesa.rb
23
+ - lib/bitpesa/api.rb
24
+ - lib/bitpesa/client.rb
25
+ - lib/bitpesa/error.rb
26
+ - lib/bitpesa/version.rb
27
+ homepage: https://api.bitpesa.co/documentation
28
+ licenses:
29
+ - MIT
30
+ metadata: {}
31
+ post_install_message:
32
+ rdoc_options: []
33
+ require_paths:
34
+ - lib
35
+ required_ruby_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 2.3.0
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ requirements: []
46
+ rubyforge_project:
47
+ rubygems_version: 2.5.1
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: BitPesa API wrapper in Ruby
51
+ test_files: []