mpesarb 0.3.0 → 0.3.3
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/.gitpod.yml +8 -0
- data/CHANGELOG.md +3 -1
- data/Gemfile +3 -1
- data/Gemfile.lock +22 -6
- data/README.md +60 -3
- data/Rakefile +8 -6
- data/bin/console +8 -1
- data/lib/mpesa/client.rb +17 -2
- data/lib/mpesa/error.rb +2 -0
- data/lib/mpesa/object.rb +8 -0
- data/lib/mpesa/objects/instace.rb +2 -0
- data/lib/mpesa/resource.rb +11 -0
- data/lib/mpesa/resources/balance.rb +2 -0
- data/lib/mpesa/resources/payout.rb +4 -2
- data/lib/mpesa/resources/register.rb +3 -1
- data/lib/mpesa/resources/reversal.rb +31 -0
- data/lib/mpesa/resources/status.rb +16 -1
- data/lib/mpesa/resources/stk.rb +13 -7
- data/lib/mpesa/resources/token.rb +28 -0
- data/lib/mpesa/version.rb +3 -1
- data/lib/mpesa.rb +1 -0
- data/mpesa.gemspec +1 -0
- metadata +19 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 21c94fd454abe3e4127f6c716ee39c4f574924018af8d6daedafc0c1f1bee5d1
|
|
4
|
+
data.tar.gz: e68131c8d3f8d1531abd3c7419c9dfacc70331a555ecd48b881cf9f290239acf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf9183f955f48501ab1fbb634145bf2f0116b98cad63613b56bdf832ceedef03eabfa8e5e0cccb55161226af04149208c16afe75eaa986c4971c24e07f053d43
|
|
7
|
+
data.tar.gz: 599eaf780d0efc0e141218ef6848e21454e12a379f66ffe64d1b1bffe8ab6aaccb87f177f418c08848321f097efc3513ab9ee3d71e7d1eefb41dfbebf3a081ff
|
data/.gitpod.yml
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# This configuration file was automatically generated by Gitpod.
|
|
2
|
+
# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)
|
|
3
|
+
# and commit this file to your remote git repository to share the goodness with others.
|
|
4
|
+
|
|
5
|
+
tasks:
|
|
6
|
+
- init: bin/setup
|
|
7
|
+
|
|
8
|
+
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
|
|
4
|
+
mpesarb (0.3.1)
|
|
5
|
+
activesupport (>= 5.0.0)
|
|
5
6
|
faraday (>= 1.1)
|
|
6
7
|
faraday_middleware (~> 1.1)
|
|
7
8
|
openssl (>= 2.1)
|
|
@@ -9,12 +10,19 @@ PATH
|
|
|
9
10
|
GEM
|
|
10
11
|
remote: https://rubygems.org/
|
|
11
12
|
specs:
|
|
13
|
+
activesupport (6.1.4.1)
|
|
14
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
15
|
+
i18n (>= 1.6, < 2)
|
|
16
|
+
minitest (>= 5.1)
|
|
17
|
+
tzinfo (~> 2.0)
|
|
18
|
+
zeitwerk (~> 2.3)
|
|
12
19
|
addressable (2.8.0)
|
|
13
20
|
public_suffix (>= 2.0.2, < 5.0)
|
|
14
21
|
ansi (1.5.0)
|
|
15
22
|
builder (3.2.4)
|
|
16
23
|
byebug (11.1.3)
|
|
17
24
|
coderay (1.1.3)
|
|
25
|
+
concurrent-ruby (1.1.9)
|
|
18
26
|
coveralls (0.8.23)
|
|
19
27
|
json (>= 1.8, < 3)
|
|
20
28
|
simplecov (~> 0.16.1)
|
|
@@ -24,7 +32,7 @@ GEM
|
|
|
24
32
|
crack (0.4.5)
|
|
25
33
|
rexml
|
|
26
34
|
docile (1.4.0)
|
|
27
|
-
faraday (1.
|
|
35
|
+
faraday (1.8.0)
|
|
28
36
|
faraday-em_http (~> 1.0)
|
|
29
37
|
faraday-em_synchrony (~> 1.0)
|
|
30
38
|
faraday-excon (~> 1.1)
|
|
@@ -43,9 +51,12 @@ GEM
|
|
|
43
51
|
faraday-net_http_persistent (1.2.0)
|
|
44
52
|
faraday-patron (1.0.0)
|
|
45
53
|
faraday-rack (1.0.0)
|
|
46
|
-
faraday_middleware (1.
|
|
54
|
+
faraday_middleware (1.2.0)
|
|
47
55
|
faraday (~> 1.0)
|
|
48
56
|
hashdiff (1.0.1)
|
|
57
|
+
i18n (1.8.10)
|
|
58
|
+
concurrent-ruby (~> 1.0)
|
|
59
|
+
ipaddr (1.2.3)
|
|
49
60
|
json (2.5.1)
|
|
50
61
|
method_source (1.0.0)
|
|
51
62
|
minitest (5.14.4)
|
|
@@ -55,7 +66,8 @@ GEM
|
|
|
55
66
|
minitest (>= 5.0)
|
|
56
67
|
ruby-progressbar
|
|
57
68
|
multipart-post (2.1.1)
|
|
58
|
-
openssl (2.2.
|
|
69
|
+
openssl (2.2.1)
|
|
70
|
+
ipaddr
|
|
59
71
|
pry (0.13.1)
|
|
60
72
|
coderay (~> 1.1)
|
|
61
73
|
method_source (~> 1.0)
|
|
@@ -78,14 +90,18 @@ GEM
|
|
|
78
90
|
thor (1.1.0)
|
|
79
91
|
tins (1.29.1)
|
|
80
92
|
sync
|
|
93
|
+
tzinfo (2.0.4)
|
|
94
|
+
concurrent-ruby (~> 1.0)
|
|
81
95
|
vcr (6.0.0)
|
|
82
96
|
webmock (3.14.0)
|
|
83
97
|
addressable (>= 2.8.0)
|
|
84
98
|
crack (>= 0.3.2)
|
|
85
99
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
100
|
+
zeitwerk (2.5.1)
|
|
86
101
|
|
|
87
102
|
PLATFORMS
|
|
88
103
|
x86_64-darwin-19
|
|
104
|
+
x86_64-darwin-20
|
|
89
105
|
|
|
90
106
|
DEPENDENCIES
|
|
91
107
|
bundler (>= 2.1.4)
|
|
@@ -93,11 +109,11 @@ DEPENDENCIES
|
|
|
93
109
|
coveralls
|
|
94
110
|
minitest
|
|
95
111
|
minitest-reporters
|
|
96
|
-
|
|
112
|
+
mpesarb!
|
|
97
113
|
pry-byebug
|
|
98
114
|
rake (>= 12.3)
|
|
99
115
|
vcr
|
|
100
116
|
webmock (~> 3.7)
|
|
101
117
|
|
|
102
118
|
BUNDLED WITH
|
|
103
|
-
2.2.
|
|
119
|
+
2.2.27
|
data/README.md
CHANGED
|
@@ -12,7 +12,12 @@ This Gem provides an interface that developers can use to convert JSON to `OpenS
|
|
|
12
12
|
|
|
13
13
|
Install via `Gemfile`
|
|
14
14
|
```
|
|
15
|
-
gem
|
|
15
|
+
gem 'mpesarb', '~> 0.3.2'
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or
|
|
19
|
+
```
|
|
20
|
+
bundle add mpesarb
|
|
16
21
|
```
|
|
17
22
|
|
|
18
23
|
## Usage
|
|
@@ -20,12 +25,25 @@ gem "mpesa", github: "gathuku/mpesa"
|
|
|
20
25
|
### Initialization
|
|
21
26
|
|
|
22
27
|
```ruby
|
|
23
|
-
client = Mpesa::Client.new(key:
|
|
28
|
+
client = Mpesa::Client.new(key: 'ZtkRW6ATbVtFpNml5w5SfG26Adfyagn9', secret: 'dosFI1yQ8bvHEVFw', env: 'sandbox')
|
|
24
29
|
|
|
25
30
|
response = client.auth
|
|
26
31
|
response.access_token # XiKf3D6UrY0J8S2aeOQ7R7w0BuA5
|
|
27
32
|
response.expires_in # 3599
|
|
28
33
|
```
|
|
34
|
+
__Parameters__
|
|
35
|
+
|
|
36
|
+
Required
|
|
37
|
+
- `key` - API consumer key - Required
|
|
38
|
+
- `secret` - API consumer secret - Required
|
|
39
|
+
|
|
40
|
+
Optional
|
|
41
|
+
- `env` - API environment. Default `production`
|
|
42
|
+
- `adapter` - Faraday HTTP adapter. Default `:net_http`
|
|
43
|
+
- `shortcode` - Mpesa shortcode
|
|
44
|
+
- `pass_key` - LPNMO pass Key( used by STK API)
|
|
45
|
+
- `raise_errors` - `Boolean` raise errors if response status code is not 200. Default: `true`
|
|
46
|
+
|
|
29
47
|
|
|
30
48
|
### Register Urls
|
|
31
49
|
|
|
@@ -33,7 +51,8 @@ Register C2B Urls( confirmation and validation url)
|
|
|
33
51
|
```ruby
|
|
34
52
|
response = client.register(
|
|
35
53
|
shortcode: "44445",
|
|
36
|
-
confirmation_url: 'http://
|
|
54
|
+
confirmation_url: 'http://example.com/confirm',
|
|
55
|
+
validation_url: 'http://example.com/validate'
|
|
37
56
|
)
|
|
38
57
|
response.OriginatorCoversationID # "807-15591582-1"
|
|
39
58
|
response.ResponseCode # "0"
|
|
@@ -82,6 +101,44 @@ respose.ResponseDescription # "Accept the service request successfully."
|
|
|
82
101
|
|
|
83
102
|
```
|
|
84
103
|
|
|
104
|
+
### Transaction Status
|
|
105
|
+
Check Transation Status
|
|
106
|
+
|
|
107
|
+
```rb
|
|
108
|
+
response = client.status(
|
|
109
|
+
shortcode: '600426',
|
|
110
|
+
transaction_id: 'OEI2AK4Q16',
|
|
111
|
+
identifier_type: 1,
|
|
112
|
+
initiator_username: 'testapi',
|
|
113
|
+
initiator_password: 'Safaricom426!',
|
|
114
|
+
timeout_url: 'https://example.com/result',
|
|
115
|
+
result_url: 'https://example.com/result'
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
response.ConversationID
|
|
119
|
+
response.ResponseCode
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Reversal
|
|
123
|
+
Initiate a reversal
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
response = client.reversal(
|
|
127
|
+
initiator_password: 'Safaricom426!',
|
|
128
|
+
initiator_username: 'testapi',
|
|
129
|
+
transaction_id: 'OEI2AK4Q16',
|
|
130
|
+
amount: '100',
|
|
131
|
+
receiver: '600610',
|
|
132
|
+
receiver_type: '4',
|
|
133
|
+
timeout_url: 'https://example.com/result',
|
|
134
|
+
result_url: 'https://example.com/result'
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
response.ConversationID
|
|
138
|
+
response.ResponseCode
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
|
|
85
142
|
|
|
86
143
|
## Development
|
|
87
144
|
|
data/Rakefile
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rake/testtask'
|
|
3
5
|
|
|
4
6
|
Rake::TestTask.new(:test) do |t|
|
|
5
|
-
t.libs <<
|
|
6
|
-
t.libs <<
|
|
7
|
-
t.test_files = FileList[
|
|
7
|
+
t.libs << 'test'
|
|
8
|
+
t.libs << 'lib'
|
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
task :
|
|
12
|
+
task default: :test
|
data/bin/console
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
require 'bundler/setup'
|
|
4
5
|
require 'mpesa'
|
|
@@ -10,7 +11,13 @@ require 'mpesa'
|
|
|
10
11
|
# require "pry"
|
|
11
12
|
# Pry.start
|
|
12
13
|
|
|
13
|
-
client = Mpesa::Client.new(
|
|
14
|
+
client = Mpesa::Client.new(
|
|
15
|
+
key: 'ZtkRW6ATbVtFpNml5w5SfG26Adfyagn9',
|
|
16
|
+
secret: 'dosFI1yQ8bvHEVFw',
|
|
17
|
+
env: 'sandbox',
|
|
18
|
+
shortcode: '174379',
|
|
19
|
+
pass_key: 'bfb279f9aa9bdbcf158e97dd71a467cd2e0c893059b10f78e6b72ada1ed2c919'
|
|
20
|
+
)
|
|
14
21
|
|
|
15
22
|
require 'irb'
|
|
16
23
|
IRB.start(__FILE__)
|
data/lib/mpesa/client.rb
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'faraday'
|
|
2
4
|
require 'faraday_middleware'
|
|
3
5
|
|
|
4
6
|
module Mpesa
|
|
5
7
|
class Client
|
|
6
|
-
attr_reader :key, :secret, :env, :adapter, :shortcode, :pass_key
|
|
8
|
+
attr_reader :key, :secret, :env, :adapter, :shortcode, :pass_key, :raise_errors
|
|
7
9
|
|
|
8
|
-
def initialize(key:, secret:, shortcode: nil, pass_key: nil, env: 'production', adapter: Faraday.default_adapter)
|
|
10
|
+
def initialize(key:, secret:, shortcode: nil, pass_key: nil, env: 'production', adapter: Faraday.default_adapter, raise_errors: true)
|
|
9
11
|
@key = key
|
|
10
12
|
@secret = secret
|
|
11
13
|
@env = env
|
|
12
14
|
@adapter = adapter
|
|
13
15
|
@pass_key = pass_key
|
|
14
16
|
@shortcode = shortcode
|
|
17
|
+
@raise_errors = raise_errors
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
def auth
|
|
@@ -30,6 +33,18 @@ module Mpesa
|
|
|
30
33
|
Payout.new(self, args).call
|
|
31
34
|
end
|
|
32
35
|
|
|
36
|
+
def status(**args)
|
|
37
|
+
Status.new(self, args).call
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def balance(**args)
|
|
41
|
+
Balance.new(self, args).call
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def reversal(**args)
|
|
45
|
+
Reversal.new(self, args).call
|
|
46
|
+
end
|
|
47
|
+
|
|
33
48
|
def connection(basic_auth: false)
|
|
34
49
|
@connection ||= Faraday.new do |conn|
|
|
35
50
|
conn.url_prefix = "https://#{subdomain}.safaricom.co.ke"
|
data/lib/mpesa/error.rb
CHANGED
data/lib/mpesa/object.rb
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'ostruct'
|
|
2
4
|
|
|
3
5
|
module Mpesa
|
|
4
6
|
class Object
|
|
7
|
+
attr_reader :attributes
|
|
8
|
+
|
|
5
9
|
def initialize(attributes)
|
|
6
10
|
@attributes = OpenStruct.new(attributes)
|
|
7
11
|
end
|
|
@@ -14,5 +18,9 @@ module Mpesa
|
|
|
14
18
|
def respond_to_missing?(_method, _include_private = false)
|
|
15
19
|
true
|
|
16
20
|
end
|
|
21
|
+
|
|
22
|
+
def to_hash
|
|
23
|
+
attributes.to_h
|
|
24
|
+
end
|
|
17
25
|
end
|
|
18
26
|
end
|
data/lib/mpesa/resource.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mpesa
|
|
2
4
|
class Resource
|
|
3
5
|
attr_reader :client, :args
|
|
@@ -16,6 +18,8 @@ module Mpesa
|
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
def handle_response(response)
|
|
21
|
+
return response unless client.raise_errors
|
|
22
|
+
|
|
19
23
|
case response.status
|
|
20
24
|
when 400
|
|
21
25
|
raise Error, "Your request was malformed. #{response.body['errorMessage']}"
|
|
@@ -30,5 +34,12 @@ module Mpesa
|
|
|
30
34
|
end
|
|
31
35
|
response
|
|
32
36
|
end
|
|
37
|
+
|
|
38
|
+
def format_phone(phone)
|
|
39
|
+
phone = phone.to_s
|
|
40
|
+
return phone if phone.match?(/\A254/)
|
|
41
|
+
|
|
42
|
+
phone.sub(/\A[+0]?(254)?(\d+)/, '254\2')
|
|
43
|
+
end
|
|
33
44
|
end
|
|
34
45
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mpesa
|
|
2
4
|
class Payout < Resource
|
|
3
|
-
PATH = 'mpesa/b2c/v1/paymentrequest'
|
|
5
|
+
PATH = 'mpesa/b2c/v1/paymentrequest'
|
|
4
6
|
|
|
5
7
|
def call
|
|
6
8
|
Object.new post_request(url: PATH, body: body).body
|
|
@@ -13,7 +15,7 @@ module Mpesa
|
|
|
13
15
|
'CommandID': args[:command_id],
|
|
14
16
|
'Amount': args[:amount],
|
|
15
17
|
'PartyA': client.shortcode || args[:shortcode],
|
|
16
|
-
'PartyB': args[:phone],
|
|
18
|
+
'PartyB': format_phone(args[:phone]),
|
|
17
19
|
'Remarks': args[:remarks],
|
|
18
20
|
'QueueTimeOutURL': args[:timeout_url],
|
|
19
21
|
'ResultURL': args[:result_url],
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mpesa
|
|
4
|
+
class Reversal < Resource
|
|
5
|
+
PATH = 'mpesa/reversal/v1/request'
|
|
6
|
+
|
|
7
|
+
def call
|
|
8
|
+
Object.new post_request(url: PATH, body: body).body
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def body
|
|
12
|
+
{
|
|
13
|
+
"Initiator": args[:initiator_username],
|
|
14
|
+
"SecurityCredential": credentials,
|
|
15
|
+
"CommandID": 'TransactionReversal',
|
|
16
|
+
"TransactionID": args[:transaction_id],
|
|
17
|
+
"Amount": args[:amount],
|
|
18
|
+
"ReceiverParty": args[:receiver],
|
|
19
|
+
"RecieverIdentifierType": args[:receiver_type],
|
|
20
|
+
"Remarks": args[:remarks] || 'check status',
|
|
21
|
+
"QueueTimeOutURL": args[:timeout_url],
|
|
22
|
+
"ResultURL": args[:result_url],
|
|
23
|
+
"Occasion": args[:occasion] || 'check status'
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def credentials
|
|
28
|
+
SecurityCred.new(args[:initiator_password], client.env).password_credential
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Mpesa
|
|
2
4
|
class Status < Resource
|
|
3
5
|
PATH = 'mpesa/transactionstatus/v1/query'
|
|
@@ -7,8 +9,21 @@ module Mpesa
|
|
|
7
9
|
|
|
8
10
|
def body
|
|
9
11
|
{
|
|
10
|
-
|
|
12
|
+
"CommandID": 'TransactionStatusQuery',
|
|
13
|
+
"PartyA": args[:shortcode] || client.shortcode,
|
|
14
|
+
"IdentifierType": args[:identifier_type],
|
|
15
|
+
"Remarks": args[:remarks] || 'check status',
|
|
16
|
+
"Initiator": args[:initiator_username],
|
|
17
|
+
"SecurityCredential": credentials,
|
|
18
|
+
"QueueTimeOutURL": args[:timeout_url],
|
|
19
|
+
"ResultURL": args[:result_url],
|
|
20
|
+
"TransactionID": args[:transaction_id],
|
|
21
|
+
"Occasion": args[:occasion] || 'check status'
|
|
11
22
|
}
|
|
12
23
|
end
|
|
24
|
+
|
|
25
|
+
def credentials
|
|
26
|
+
SecurityCred.new(args[:initiator_password], client.env).password_credential
|
|
27
|
+
end
|
|
13
28
|
end
|
|
14
29
|
end
|
data/lib/mpesa/resources/stk.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'base64'
|
|
2
4
|
|
|
3
5
|
module Mpesa
|
|
@@ -10,14 +12,14 @@ module Mpesa
|
|
|
10
12
|
|
|
11
13
|
def body
|
|
12
14
|
{
|
|
13
|
-
'BusinessShortCode':
|
|
15
|
+
'BusinessShortCode': shortcode,
|
|
14
16
|
'Password': password,
|
|
15
|
-
'Timestamp': timestamp
|
|
17
|
+
'Timestamp': timestamp,
|
|
16
18
|
'TransactionType': 'CustomerPayBillOnline',
|
|
17
19
|
'Amount': args[:amount],
|
|
18
|
-
'PartyA': args[:phone],
|
|
19
|
-
'PartyB':
|
|
20
|
-
'PhoneNumber': args[:phone],
|
|
20
|
+
'PartyA': format_phone(args[:phone]),
|
|
21
|
+
'PartyB': shortcode,
|
|
22
|
+
'PhoneNumber': format_phone(args[:phone]),
|
|
21
23
|
'CallBackURL': args[:callback_url],
|
|
22
24
|
'AccountReference': args[:reference],
|
|
23
25
|
'TransactionDesc': args[:trans_desc]
|
|
@@ -25,11 +27,15 @@ module Mpesa
|
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def password
|
|
28
|
-
Base64.strict_encode64("#{
|
|
30
|
+
Base64.strict_encode64("#{shortcode}#{args[:pass_key] || client.pass_key}#{timestamp}")
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def timestamp
|
|
32
|
-
Time.now.strftime('%Y%m%d%H%M%S')
|
|
34
|
+
Time.now.strftime('%Y%m%d%H%M%S')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def shortcode
|
|
38
|
+
args[:shortcode] || client.shortcode
|
|
33
39
|
end
|
|
34
40
|
end
|
|
35
41
|
end
|
|
@@ -1,7 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/cache'
|
|
4
|
+
require 'active_support/cache/memory_store'
|
|
5
|
+
require 'active_support/notifications'
|
|
6
|
+
|
|
1
7
|
module Mpesa
|
|
2
8
|
class Token < Resource
|
|
3
9
|
def token
|
|
10
|
+
if cache.exist?('token')
|
|
11
|
+
expires_at = cache.send(:read_entry, 'token')&.expires_at
|
|
12
|
+
Object.new({
|
|
13
|
+
"access_token": cache.fetch('token'),
|
|
14
|
+
"expires_in": expires_at - Time.now.to_f
|
|
15
|
+
})
|
|
16
|
+
else
|
|
17
|
+
cache_token
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def cache_token
|
|
22
|
+
res = call
|
|
23
|
+
cache.write('token', res.access_token, expires_in: res.expires_in)
|
|
24
|
+
res
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def call
|
|
4
28
|
Object.new get_request(url: 'oauth/v1/generate?grant_type=client_credentials', basic_auth: true).body
|
|
5
29
|
end
|
|
30
|
+
|
|
31
|
+
def cache
|
|
32
|
+
@cache ||= ActiveSupport::Cache::MemoryStore.new
|
|
33
|
+
end
|
|
6
34
|
end
|
|
7
35
|
end
|
data/lib/mpesa/version.rb
CHANGED
data/lib/mpesa.rb
CHANGED
data/mpesa.gemspec
CHANGED
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
|
|
|
30
30
|
spec.add_development_dependency 'bundler', '>= 2.1.4'
|
|
31
31
|
spec.add_development_dependency 'rake', '>= 12.3'
|
|
32
32
|
# dependancies
|
|
33
|
+
spec.add_runtime_dependency 'activesupport', '>= 5.0.0'
|
|
33
34
|
spec.add_runtime_dependency 'faraday', '>= 1.1'
|
|
34
35
|
spec.add_runtime_dependency 'faraday_middleware', '~> 1.1'
|
|
35
36
|
spec.add_runtime_dependency 'openssl', '>= 2.1'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mpesarb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Moses Gathuku
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-05-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -38,6 +38,20 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '12.3'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: activesupport
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: 5.0.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.0
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: faraday
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -187,6 +201,7 @@ extra_rdoc_files: []
|
|
|
187
201
|
files:
|
|
188
202
|
- ".github/workflows/mpesa.yml"
|
|
189
203
|
- ".gitignore"
|
|
204
|
+
- ".gitpod.yml"
|
|
190
205
|
- ".travis.yml"
|
|
191
206
|
- CHANGELOG.md
|
|
192
207
|
- CODE_OF_CONDUCT.md
|
|
@@ -210,6 +225,7 @@ files:
|
|
|
210
225
|
- lib/mpesa/resources/balance.rb
|
|
211
226
|
- lib/mpesa/resources/payout.rb
|
|
212
227
|
- lib/mpesa/resources/register.rb
|
|
228
|
+
- lib/mpesa/resources/reversal.rb
|
|
213
229
|
- lib/mpesa/resources/status.rb
|
|
214
230
|
- lib/mpesa/resources/stk.rb
|
|
215
231
|
- lib/mpesa/resources/token.rb
|
|
@@ -238,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
238
254
|
- !ruby/object:Gem::Version
|
|
239
255
|
version: '0'
|
|
240
256
|
requirements: []
|
|
241
|
-
rubygems_version: 3.
|
|
257
|
+
rubygems_version: 3.3.7
|
|
242
258
|
signing_key:
|
|
243
259
|
specification_version: 4
|
|
244
260
|
summary: a simple gem to integrate ruby with mpesa Apis
|