mpesa_stk 1.2.1.1 → 1.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/.sample.env +2 -1
- data/Gemfile.lock +11 -7
- data/README.md +51 -5
- data/lib/mpesa_stk.rb +1 -0
- data/lib/mpesa_stk/access_token.rb +8 -8
- data/lib/mpesa_stk/push.rb +131 -0
- data/lib/mpesa_stk/push_payment.rb +15 -15
- data/lib/mpesa_stk/version.rb +1 -1
- data/mpesa_stk.gemspec +2 -2
- metadata +17 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12e1c2a4f60b943357593f37099a3ef7e5a9f4c272a0aca0960452b504789fe0
|
4
|
+
data.tar.gz: 14c3633244b9867b275a1e10949f4b6880b62c04e42213c6b5b2f4ded24e4dc1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fe982c6d29a14a7ab22e2acc16d97b9411666c47edf664c5f77a9e0b398d7b6cf3c031bdd9c9e55003f4fb31a21ecaef65e5eeadb4f7893721c3c466ba06e57
|
7
|
+
data.tar.gz: c2dbf612bd39861047a24cf0497a01893ec6b0018ec20ee6f33cc8a36d0964e87172566f0090bcf4e29f076d099192dab6b0e859951029db8d32b38feb04171a
|
data/.sample.env
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mpesa_stk (1.
|
5
|
-
httparty (
|
4
|
+
mpesa_stk (1.3)
|
5
|
+
httparty (>= 0.15.6, < 0.19.0)
|
6
6
|
redis-namespace (~> 1.5, >= 1.5.3)
|
7
7
|
redis-rack (~> 2.0, >= 2.0.2)
|
8
8
|
|
@@ -14,11 +14,15 @@ GEM
|
|
14
14
|
coderay (1.1.2)
|
15
15
|
crack (0.4.3)
|
16
16
|
safe_yaml (~> 1.0.0)
|
17
|
-
dotenv (2.
|
17
|
+
dotenv (2.7.5)
|
18
18
|
hashdiff (1.0.1)
|
19
|
-
httparty (0.
|
19
|
+
httparty (0.18.1)
|
20
|
+
mime-types (~> 3.0)
|
20
21
|
multi_xml (>= 0.5.2)
|
21
22
|
method_source (0.8.2)
|
23
|
+
mime-types (3.3.1)
|
24
|
+
mime-types-data (~> 3.2015)
|
25
|
+
mime-types-data (3.2020.0512)
|
22
26
|
minitest (5.14.0)
|
23
27
|
multi_xml (0.6.0)
|
24
28
|
pry (0.10.4)
|
@@ -29,8 +33,8 @@ GEM
|
|
29
33
|
pry (>= 0.9.10, < 0.11.0)
|
30
34
|
public_suffix (4.0.4)
|
31
35
|
rack (2.2.2)
|
32
|
-
rake (
|
33
|
-
redis (4.1
|
36
|
+
rake (13.0.1)
|
37
|
+
redis (4.2.1)
|
34
38
|
redis-namespace (1.7.0)
|
35
39
|
redis (>= 3.0.4)
|
36
40
|
redis-rack (2.1.2)
|
@@ -50,7 +54,7 @@ PLATFORMS
|
|
50
54
|
|
51
55
|
DEPENDENCIES
|
52
56
|
bundler
|
53
|
-
dotenv (= 2.
|
57
|
+
dotenv (= 2.7.5)
|
54
58
|
minitest (~> 5.0)
|
55
59
|
mpesa_stk!
|
56
60
|
pry (~> 0.10.4)
|
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# MpesaStk
|
2
2
|
Lipa na M-Pesa Online Payment API is used to initiate a M-Pesa transaction on behalf of a customer using STK Push. This is the same technique mySafaricom App uses whenever the app is used to make payments.
|
3
3
|
|
4
|
-
|
4
|
+
[](https://badge.fury.io/rb/mpesa_stk.svg)
|
5
|
+

|
5
6
|
|
6
7
|
## Installation
|
7
8
|
|
@@ -22,6 +23,14 @@ This gem has a [Redis](https://redis.io/) dependency, so make sure it running
|
|
22
23
|
```ruby
|
23
24
|
$ redis-server
|
24
25
|
```
|
26
|
+
You can use command line to determine if redis is running:
|
27
|
+
```ruby
|
28
|
+
redis-cli ping
|
29
|
+
```
|
30
|
+
you should get back
|
31
|
+
```ruby
|
32
|
+
PONG
|
33
|
+
```
|
25
34
|
|
26
35
|
you need to setup your environment variables, checkout `.sample.env` for the values you need.
|
27
36
|
or run
|
@@ -35,12 +44,19 @@ secret=""
|
|
35
44
|
business_short_code=""
|
36
45
|
business_passkey=""
|
37
46
|
callback_url=""
|
47
|
+
till_number=""
|
38
48
|
```
|
39
49
|
|
40
50
|
* `key` and `secret` of the app created on your [developer account](https://developer.safaricom.co.ke/user/me/apps).
|
41
51
|
* `business_short_code` and `business_pass_key` this can be found in [Test Credentials](https://developer.safaricom.co.ke/test_credentials).
|
42
52
|
* `callback_url` the url of your application where response will be sent. `make sure its a reachable/active url`
|
43
53
|
|
54
|
+
`Prod:`
|
55
|
+
|
56
|
+
when going live there information will be sent to your email.
|
57
|
+
|
58
|
+
for `buy_goods` push `business_short_code` will be equivalent to `store number` and `till_number` will remain as is.
|
59
|
+
|
44
60
|
### Testing out the gem in an actual Rails application
|
45
61
|
|
46
62
|
To test out the app on an actual rails application, do check out the following link:
|
@@ -53,18 +69,39 @@ https://github.com/mboya/stk
|
|
53
69
|
#### Sample application
|
54
70
|
Check out a rails sample application [here](https://github.com/mboya/stk)
|
55
71
|
|
56
|
-
### Testing the gem on the console
|
72
|
+
### Testing the gem on the console/app
|
73
|
+
When running the gem on a single safaricom app.
|
57
74
|
|
58
75
|
```ruby
|
59
76
|
$ irb
|
77
|
+
2.5.0 :001 > require 'mpesa_stk'
|
78
|
+
2.5.0 :002 > MpesaStk::PushPayment.call("500", "<YOUR PHONE NUMBER: 254711222333>")
|
60
79
|
```
|
61
80
|
|
81
|
+
When running the app on multiple safaricom apps, within the same project.
|
62
82
|
```ruby
|
63
|
-
|
83
|
+
$ irb
|
84
|
+
2.5.3 :001 > require 'mpesa_stk'
|
85
|
+
2.5.3 :002 > hash = Hash.new
|
86
|
+
2.5.3 :003 >
|
87
|
+
2.5.3 :004 > hash['key'] = key
|
88
|
+
2.5.3 :005 > hash['secret'] = secret
|
89
|
+
2.5.3 :006 > hash['business_short_code'] = business_short_code
|
90
|
+
2.5.3 :007 > hash['business_passkey'] = business_passkey
|
91
|
+
2.5.3 :008 > hash['callback_url'] = callback_url
|
92
|
+
2.5.3 :009 > hash['till_number'] = till_number
|
64
93
|
```
|
65
|
-
|
94
|
+
for STK push
|
66
95
|
```ruby
|
67
|
-
2.5.
|
96
|
+
2.5.3 :010 > MpesaStk::Push.pay_bill('05', "<YOUR PHONE NUMBER: 254711222333>", hash)
|
97
|
+
```
|
98
|
+
for Till Number push
|
99
|
+
```ruby
|
100
|
+
2.5.3 :010 > MpesaStk::Push.buy_goods('05', "<YOUR PHONE NUMBER: 254711222333>", hash)
|
101
|
+
```
|
102
|
+
possible error format if the request is not successful
|
103
|
+
```hash
|
104
|
+
{"requestId"=>"13022-8633727-1", "errorCode"=>"500.001.1001", "errorMessage"=>"Error Message"}
|
68
105
|
```
|
69
106
|
|
70
107
|
expected irb output after the command
|
@@ -82,12 +119,21 @@ the above response means the response has been successfully sent to Safaricom fo
|
|
82
119
|
|
83
120
|
### Mpesa Checkout/Express
|
84
121
|
This is the expected output on the mobile phone
|
122
|
+
|
85
123
|

|
86
124
|
|
87
125
|
### Callback url
|
88
126
|
|
89
127
|
After the pin code is entered on the checkout/express prompt. you will receive a request on the provided `callback_url` with the status of the action
|
90
128
|
|
129
|
+
sample payload that you will be getting on your callback
|
130
|
+
```hash
|
131
|
+
{"Body"=>{"stkCallback"=>{"MerchantRequestID"=>"3968-94214-1", "CheckoutRequestID"=>"ws_CO_160620191218268004", "ResultCode"=>0, "ResultDesc"=>"The service request is processed successfully.",
|
132
|
+
"CallbackMetadata"=>{"Item"=>[{"Name"=>"Amount", "Value"=>"05"}, {"Name"=>"MpesaReceiptNumber", "Value"=>"OFG4Z5EE9Y"}, {"Name"=>"TransactionDate", "Value"=>20190616121848},
|
133
|
+
{"Name"=>"PhoneNumber", "Value"=>254711222333}]}}}, "push"=>{"Body"=>{"stkCallback"=>{"MerchantRequestID"=>"3968-94214-1", "CheckoutRequestID"=>"ws_CO_160620191218268004", "ResultCode"=>0,
|
134
|
+
"ResultDesc"=>"The service request is processed successfully.", "CallbackMetadata"=>{"Item"=>[{"Name"=>"Amount", "Value"=>"05"}, {"Name"=>"MpesaReceiptNumber", "Value"=>"OFG4Z5EE9Y"}, {"Name"=>"TransactionDate",
|
135
|
+
"Value"=>20190616121848}, {"Name"=>"PhoneNumber", "Value"=>254711222333}]}}}}}
|
136
|
+
```
|
91
137
|
|
92
138
|
## Development
|
93
139
|
|
data/lib/mpesa_stk.rb
CHANGED
@@ -4,14 +4,14 @@ require 'redis'
|
|
4
4
|
module MpesaStk
|
5
5
|
class AccessToken
|
6
6
|
class << self
|
7
|
-
def call
|
8
|
-
new.access_token
|
7
|
+
def call(key = nil, secret = nil)
|
8
|
+
new(key, secret).access_token
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
def initialize
|
13
|
-
@key = ENV['key']
|
14
|
-
@secret = ENV['secret']
|
12
|
+
def initialize(key = nil, secret = nil)
|
13
|
+
@key = key.nil? ? ENV['key'] : key
|
14
|
+
@secret = secret.nil? ? ENV['secret'] : secret
|
15
15
|
@redis = Redis.new
|
16
16
|
|
17
17
|
load_from_redis
|
@@ -73,14 +73,14 @@ module MpesaStk
|
|
73
73
|
|
74
74
|
def headers
|
75
75
|
encode = encode_credentials @key, @secret
|
76
|
-
|
77
|
-
|
76
|
+
{
|
77
|
+
"Authorization" => "Basic #{encode}"
|
78
78
|
}
|
79
79
|
end
|
80
80
|
|
81
81
|
def encode_credentials key, secret
|
82
82
|
credentials = "#{key}:#{secret}"
|
83
|
-
|
83
|
+
Base64.encode64(credentials).split("\n").join
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require "mpesa_stk/access_token"
|
2
|
+
|
3
|
+
module MpesaStk
|
4
|
+
class Push
|
5
|
+
class << self
|
6
|
+
def pay_bill(amount, phone_number, hash = {})
|
7
|
+
new(amount, phone_number, "CustomerPayBillOnline", nil, hash["business_short_code"], hash["callback_url"], hash["business_passkey"], hash["key"], hash["secret"]).push_payment
|
8
|
+
end
|
9
|
+
|
10
|
+
def buy_goods(amount, phone_number, hash = {})
|
11
|
+
new(amount, phone_number, "CustomerBuyGoodsOnline", hash["till_number"], hash["business_short_code"], hash["callback_url"], hash["business_passkey"], hash["key"], hash["secret"]).push_payment
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :token, :amount, :phone_number, :till_number, :business_short_code, :callback_url, :business_passkey, :transaction_type
|
16
|
+
|
17
|
+
def initialize(amount, phone_number, transaction_type, till_number = nil, business_short_code = nil, callback_url = nil, business_passkey = nil, key = nil, secret = nil)
|
18
|
+
@token = MpesaStk::AccessToken.call(key, secret)
|
19
|
+
@transaction_type = transaction_type
|
20
|
+
@till_number = till_number
|
21
|
+
@business_short_code = business_short_code
|
22
|
+
@callback_url = callback_url
|
23
|
+
@business_passkey = business_passkey
|
24
|
+
@amount = amount
|
25
|
+
@phone_number = phone_number
|
26
|
+
end
|
27
|
+
|
28
|
+
def push_payment
|
29
|
+
response = HTTParty.post(url, headers: headers, body: body)
|
30
|
+
JSON.parse(response.body)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def url
|
36
|
+
"#{ENV['base_url']}#{ENV['process_request_url']}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def headers
|
40
|
+
{
|
41
|
+
"Authorization" => "Bearer #{token}",
|
42
|
+
"Content-Type" => "application/json"
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def body
|
47
|
+
{
|
48
|
+
BusinessShortCode: get_business_short_code,
|
49
|
+
Password: generate_password,
|
50
|
+
Timestamp: "#{timestamp}",
|
51
|
+
TransactionType: transaction_type,
|
52
|
+
Amount: "#{amount}",
|
53
|
+
PartyA: "#{phone_number}",
|
54
|
+
PartyB: get_till_number,
|
55
|
+
PhoneNumber: "#{phone_number}",
|
56
|
+
CallBackURL: get_callback_url,
|
57
|
+
AccountReference: generate_bill_reference_number(5),
|
58
|
+
TransactionDesc: generate_bill_reference_number(5)
|
59
|
+
}.to_json
|
60
|
+
end
|
61
|
+
|
62
|
+
def generate_bill_reference_number(number)
|
63
|
+
charset = Array('A'..'Z') + Array('a'..'z')
|
64
|
+
Array.new(number) { charset.sample }.join
|
65
|
+
end
|
66
|
+
|
67
|
+
def timestamp
|
68
|
+
DateTime.now.strftime("%Y%m%d%H%M%S").to_i
|
69
|
+
end
|
70
|
+
|
71
|
+
# shortcode
|
72
|
+
# passkey
|
73
|
+
# timestamp
|
74
|
+
def generate_password
|
75
|
+
key = "#{get_business_short_code}#{get_business_passkey}#{timestamp}"
|
76
|
+
Base64.encode64(key).split("\n").join
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_business_short_code
|
80
|
+
if business_short_code.nil? || business_short_code.eql?("")
|
81
|
+
if ENV['business_short_code'].nil? || ENV['business_short_code'].eql?("")
|
82
|
+
raise Exception.new "Business Short Code is not defined"
|
83
|
+
else
|
84
|
+
ENV['business_short_code']
|
85
|
+
end
|
86
|
+
else
|
87
|
+
business_short_code
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def get_business_passkey
|
92
|
+
if business_passkey.nil? || business_passkey.eql?("")
|
93
|
+
if ENV['business_passkey'].nil? || ENV['business_passkey'].eql?("")
|
94
|
+
raise Exception.new "Business Passkey is not defined"
|
95
|
+
else
|
96
|
+
ENV['business_passkey']
|
97
|
+
end
|
98
|
+
else
|
99
|
+
business_passkey
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def get_callback_url
|
104
|
+
if callback_url.nil? || callback_url.eql?("")
|
105
|
+
if ENV['callback_url'].nil? || ENV['callback_url'].eql?("")
|
106
|
+
raise Exception.new "Callback URL is not defined"
|
107
|
+
else
|
108
|
+
ENV['callback_url']
|
109
|
+
end
|
110
|
+
else
|
111
|
+
callback_url
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_till_number
|
116
|
+
if transaction_type.eql?("CustomerPayBillOnline")
|
117
|
+
get_business_short_code
|
118
|
+
else
|
119
|
+
if till_number.nil?
|
120
|
+
if ENV['till_number'].nil? || ENV['till_number'].eql?("")
|
121
|
+
raise Exception.new "Till number is not defined"
|
122
|
+
else
|
123
|
+
ENV['till_number']
|
124
|
+
end
|
125
|
+
else
|
126
|
+
till_number
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -10,7 +10,7 @@ module MpesaStk
|
|
10
10
|
|
11
11
|
attr_reader :token, :amount, :phone_number
|
12
12
|
|
13
|
-
def initialize
|
13
|
+
def initialize(amount, phone_number)
|
14
14
|
@token = MpesaStk::AccessToken.call
|
15
15
|
@amount = amount
|
16
16
|
@phone_number = phone_number
|
@@ -28,25 +28,25 @@ module MpesaStk
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def headers
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
{
|
32
|
+
"Authorization" => "Bearer #{token}",
|
33
|
+
"Content-Type" => "application/json"
|
34
34
|
}
|
35
35
|
end
|
36
36
|
|
37
37
|
def body
|
38
38
|
{
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
39
|
+
BusinessShortCode: "#{ENV['business_short_code']}",
|
40
|
+
Password: generate_password,
|
41
|
+
Timestamp: "#{timestamp}",
|
42
|
+
TransactionType: "CustomerPayBillOnline",
|
43
|
+
Amount: "#{amount}",
|
44
|
+
PartyA: "#{phone_number}",
|
45
|
+
PartyB: "#{ENV['business_short_code']}",
|
46
|
+
PhoneNumber: "#{phone_number}",
|
47
|
+
CallBackURL: "#{ENV['callback_url']}",
|
48
|
+
AccountReference: generate_bill_reference_number(5),
|
49
|
+
TransactionDesc: generate_bill_reference_number(5)
|
50
50
|
}.to_json
|
51
51
|
end
|
52
52
|
|
data/lib/mpesa_stk/version.rb
CHANGED
data/mpesa_stk.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
-
spec.add_dependency 'httparty', '
|
24
|
+
spec.add_dependency 'httparty', '>= 0.15.6', '< 0.19.0'
|
25
25
|
spec.add_dependency 'redis-rack', '~> 2.0', '>= 2.0.2'
|
26
26
|
spec.add_dependency 'redis-namespace', '~> 1.5', '>= 1.5.3'
|
27
27
|
|
@@ -32,5 +32,5 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_development_dependency 'pry', '~> 0.10.4'
|
33
33
|
spec.add_development_dependency 'pry-nav', '~> 0.2.4'
|
34
34
|
spec.add_development_dependency 'webmock', '~> 3.0', '>= 3.0.1'
|
35
|
-
spec.add_development_dependency "dotenv", "2.
|
35
|
+
spec.add_development_dependency "dotenv", "2.7.5"
|
36
36
|
end
|
metadata
CHANGED
@@ -1,30 +1,36 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mpesa_stk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: '1.3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mboya
|
8
8
|
- cess
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-06-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: httparty
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 0.15.6
|
21
|
+
- - "<"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.19.0
|
21
24
|
type: :runtime
|
22
25
|
prerelease: false
|
23
26
|
version_requirements: !ruby/object:Gem::Requirement
|
24
27
|
requirements:
|
25
|
-
- - "
|
28
|
+
- - ">="
|
26
29
|
- !ruby/object:Gem::Version
|
27
30
|
version: 0.15.6
|
31
|
+
- - "<"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.19.0
|
28
34
|
- !ruby/object:Gem::Dependency
|
29
35
|
name: redis-rack
|
30
36
|
requirement: !ruby/object:Gem::Requirement
|
@@ -161,14 +167,14 @@ dependencies:
|
|
161
167
|
requirements:
|
162
168
|
- - '='
|
163
169
|
- !ruby/object:Gem::Version
|
164
|
-
version: 2.
|
170
|
+
version: 2.7.5
|
165
171
|
type: :development
|
166
172
|
prerelease: false
|
167
173
|
version_requirements: !ruby/object:Gem::Requirement
|
168
174
|
requirements:
|
169
175
|
- - '='
|
170
176
|
- !ruby/object:Gem::Version
|
171
|
-
version: 2.
|
177
|
+
version: 2.7.5
|
172
178
|
description: initiate a M-Pesa transaction on behalf of a customer using STK Push.
|
173
179
|
email:
|
174
180
|
- mboyaberry@gmail.com
|
@@ -191,6 +197,7 @@ files:
|
|
191
197
|
- bin/setup
|
192
198
|
- lib/mpesa_stk.rb
|
193
199
|
- lib/mpesa_stk/access_token.rb
|
200
|
+
- lib/mpesa_stk/push.rb
|
194
201
|
- lib/mpesa_stk/push_payment.rb
|
195
202
|
- lib/mpesa_stk/version.rb
|
196
203
|
- mpesa_stk.gemspec
|
@@ -198,7 +205,7 @@ homepage: https://github.com/mboya/mpesa_stk
|
|
198
205
|
licenses:
|
199
206
|
- MIT
|
200
207
|
metadata: {}
|
201
|
-
post_install_message:
|
208
|
+
post_install_message:
|
202
209
|
rdoc_options: []
|
203
210
|
require_paths:
|
204
211
|
- lib
|
@@ -213,8 +220,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
213
220
|
- !ruby/object:Gem::Version
|
214
221
|
version: '0'
|
215
222
|
requirements: []
|
216
|
-
rubygems_version: 3.
|
217
|
-
signing_key:
|
223
|
+
rubygems_version: 3.0.8
|
224
|
+
signing_key:
|
218
225
|
specification_version: 4
|
219
226
|
summary: Lipa na M-Pesa Online Payment.
|
220
227
|
test_files: []
|