mpesa_stk 1.3 → 2.0.0

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.
data/Rakefile CHANGED
@@ -1,10 +1,12 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
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 << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
8
10
  end
9
11
 
10
- task :default => :test
12
+ task default: :test
data/SECURITY.md ADDED
@@ -0,0 +1,21 @@
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ Use this section to tell people about which versions of your project are
6
+ currently being supported with security updates.
7
+
8
+ | Version | Supported |
9
+ | ------- | ------------------ |
10
+ | 5.1.x | :white_check_mark: |
11
+ | 5.0.x | :x: |
12
+ | 4.0.x | :white_check_mark: |
13
+ | < 4.0 | :x: |
14
+
15
+ ## Reporting a Vulnerability
16
+
17
+ Use this section to tell people how to report a vulnerability.
18
+
19
+ Tell them where to go, how often they can expect to get an update on a
20
+ reported vulnerability, what to expect if the vulnerability is accepted or
21
+ declined, etc.
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "mpesa_stk"
4
+ require 'bundler/setup'
5
+ require 'mpesa_stk'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "mpesa_stk"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -1,7 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018 mboya
4
+ #
5
+ # MIT License
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
1
25
  require 'base64'
26
+ require 'json'
2
27
  require 'redis'
3
28
 
4
29
  module MpesaStk
30
+ # Handles OAuth access token generation, caching, and refreshing for M-Pesa APIs
5
31
  class AccessToken
6
32
  class << self
7
33
  def call(key = nil, secret = nil)
@@ -10,34 +36,38 @@ module MpesaStk
10
36
  end
11
37
 
12
38
  def initialize(key = nil, secret = nil)
13
- @key = key.nil? ? ENV['key'] : key
14
- @secret = secret.nil? ? ENV['secret'] : secret
15
- @redis = Redis.new
39
+ @key = key.nil? ? ENV.fetch('key', nil) : key
40
+ @secret = secret.nil? ? ENV.fetch('secret', nil) : secret
41
+ begin
42
+ @redis = Redis.new
43
+ rescue Redis::CannotConnectError, Redis::ConnectionError => e
44
+ raise StandardError, "Failed to connect to Redis: #{e.message}"
45
+ end
16
46
 
17
47
  load_from_redis
18
48
  end
19
49
 
20
- def is_valid?
21
- has_token? && !token_expired?
50
+ def valid?
51
+ token? && !token_expired?
22
52
  end
23
53
 
24
54
  def token_expired?
25
55
  expire_time = @timestamp.to_i + @expires_in.to_i
26
- return expire_time < Time.now.to_i + 58
56
+ expire_time < Time.now.to_i + 58
27
57
  end
28
58
 
29
- def has_token?
30
- return !@token.nil?
59
+ def token?
60
+ !@token.nil?
31
61
  end
32
62
 
33
63
  def refresh
34
- get_new_access_token
64
+ new_access_token
35
65
  load_from_redis
36
66
  end
37
67
 
38
68
  def load_from_redis
39
69
  data = @redis.get(@key)
40
- if (data.nil? || data.empty?)
70
+ if data.nil? || data.empty?
41
71
  @token = nil
42
72
  @timestamp = nil
43
73
  @expires_in = nil
@@ -47,38 +77,40 @@ module MpesaStk
47
77
  @timestamp = parsed['time_stamp']
48
78
  @expires_in = parsed['expires_in']
49
79
  end
80
+ rescue Redis::BaseError => e
81
+ raise StandardError, "Redis error: #{e.message}"
50
82
  end
51
83
 
52
84
  def access_token
53
- if is_valid?
54
- return @token
55
- else
56
- refresh
57
- return @token
58
- end
85
+ refresh unless valid?
86
+ @token
59
87
  end
60
88
 
61
- def get_new_access_token
89
+ def new_access_token
62
90
  response = HTTParty.get(url, headers: headers)
63
91
 
64
- hash = JSON.parse(response.body).merge(Hash['time_stamp', Time.now.to_i])
92
+ raise StandardError, "Failed to get access token: #{response.code} - #{response.body}" unless response.success?
93
+
94
+ hash = JSON.parse(response.body).merge({ 'time_stamp' => Time.now.to_i })
65
95
  @redis.set @key, hash.to_json
96
+ rescue Redis::BaseError => e
97
+ raise StandardError, "Redis error while saving token: #{e.message}"
66
98
  end
67
99
 
68
100
  private
69
101
 
70
102
  def url
71
- "#{ENV['base_url']}#{ENV['token_generator_url']}"
103
+ "#{ENV.fetch('base_url', nil)}#{ENV.fetch('token_generator_url', nil)}"
72
104
  end
73
105
 
74
106
  def headers
75
107
  encode = encode_credentials @key, @secret
76
108
  {
77
- "Authorization" => "Basic #{encode}"
109
+ 'Authorization' => "Basic #{encode}"
78
110
  }
79
111
  end
80
112
 
81
- def encode_credentials key, secret
113
+ def encode_credentials(key, secret)
82
114
  credentials = "#{key}:#{secret}"
83
115
  Base64.encode64(credentials).split("\n").join
84
116
  end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018 mboya
4
+ #
5
+ # MIT License
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ require 'mpesa_stk/access_token'
26
+
27
+ module MpesaStk
28
+ # Query account balance for PayBill or Till Number
29
+ class AccountBalance
30
+ class << self
31
+ def query(hash = {})
32
+ new(hash).query_balance
33
+ end
34
+ end
35
+
36
+ attr_reader :token, :initiator, :security_credential, :party_a, :identifier_type, :result_url, :queue_timeout_url
37
+
38
+ def initialize(hash = {})
39
+ @token = MpesaStk::AccessToken.call(hash['key'], hash['secret'])
40
+ @initiator = hash['initiator'] || ENV.fetch('initiator', nil)
41
+ @security_credential = hash['security_credential'] || ENV.fetch('security_credential', nil)
42
+ @party_a = hash['party_a'] || ENV.fetch('business_short_code', nil)
43
+ @identifier_type = hash['identifier_type'] || '4'
44
+ @result_url = hash['result_url'] || ENV.fetch('result_url', nil)
45
+ @queue_timeout_url = hash['queue_timeout_url'] || ENV.fetch('queue_timeout_url', nil)
46
+ end
47
+
48
+ def query_balance
49
+ response = HTTParty.post(url, headers: headers, body: body)
50
+
51
+ raise StandardError, "Failed to query account balance: #{response.code} - #{response.body}" unless response.success?
52
+
53
+ JSON.parse(response.body)
54
+ end
55
+
56
+ private
57
+
58
+ def url
59
+ "#{ENV.fetch('base_url', nil)}#{ENV.fetch('account_balance_url', nil)}"
60
+ end
61
+
62
+ def headers
63
+ {
64
+ 'Authorization' => "Bearer #{token}",
65
+ 'Content-Type' => 'application/json'
66
+ }
67
+ end
68
+
69
+ def body
70
+ {
71
+ Initiator: get_initiator,
72
+ SecurityCredential: get_security_credential,
73
+ CommandID: 'AccountBalance',
74
+ PartyA: get_party_a,
75
+ IdentifierType: identifier_type,
76
+ ResultURL: get_result_url,
77
+ QueueTimeOutURL: get_queue_timeout_url
78
+ }.to_json
79
+ end
80
+
81
+ def get_initiator
82
+ if initiator.nil? || initiator.eql?('')
83
+ raise ArgumentError, 'Initiator is not defined' if ENV['initiator'].nil? || ENV['initiator'].eql?('')
84
+
85
+ ENV.fetch('initiator', nil)
86
+
87
+ else
88
+ initiator
89
+ end
90
+ end
91
+
92
+ def get_security_credential
93
+ if security_credential.nil? || security_credential.eql?('')
94
+ if ENV['security_credential'].nil? || ENV['security_credential'].eql?('')
95
+ raise ArgumentError, 'Security Credential is not defined'
96
+ end
97
+
98
+ ENV.fetch('security_credential', nil)
99
+
100
+ else
101
+ security_credential
102
+ end
103
+ end
104
+
105
+ def get_party_a
106
+ if party_a.nil? || party_a.eql?('')
107
+ if ENV['business_short_code'].nil? || ENV['business_short_code'].eql?('')
108
+ raise ArgumentError, 'PartyA (Business Short Code) is not defined'
109
+ end
110
+
111
+ ENV.fetch('business_short_code', nil)
112
+
113
+ else
114
+ party_a
115
+ end
116
+ end
117
+
118
+ def get_result_url
119
+ if result_url.nil? || result_url.eql?('')
120
+ raise ArgumentError, 'Result URL is not defined' if ENV['result_url'].nil? || ENV['result_url'].eql?('')
121
+
122
+ ENV.fetch('result_url', nil)
123
+
124
+ else
125
+ result_url
126
+ end
127
+ end
128
+
129
+ def get_queue_timeout_url
130
+ if queue_timeout_url.nil? || queue_timeout_url.eql?('')
131
+ if ENV['queue_timeout_url'].nil? || ENV['queue_timeout_url'].eql?('')
132
+ raise ArgumentError, 'Queue Timeout URL is not defined'
133
+ end
134
+
135
+ ENV.fetch('queue_timeout_url', nil)
136
+
137
+ else
138
+ queue_timeout_url
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018 mboya
4
+ #
5
+ # MIT License
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ require 'mpesa_stk/access_token'
26
+
27
+ module MpesaStk
28
+ # Business to Business payment API - send money between businesses
29
+ class B2B
30
+ class << self
31
+ def pay(amount, receiver_party, hash = {})
32
+ new(amount, receiver_party, hash).send_payment
33
+ end
34
+ end
35
+
36
+ attr_reader :token, :amount, :receiver_party, :initiator, :security_credential, :command_id,
37
+ :sender_identifier_type, :receiver_identifier_type, :party_a, :account_reference,
38
+ :result_url, :queue_timeout_url
39
+
40
+ def initialize(amount, receiver_party, hash = {})
41
+ @token = MpesaStk::AccessToken.call(hash['key'], hash['secret'])
42
+ @amount = amount
43
+ @receiver_party = receiver_party
44
+ @initiator = hash['initiator'] || ENV.fetch('initiator', nil)
45
+ @security_credential = hash['security_credential'] || ENV.fetch('security_credential', nil)
46
+ @command_id = hash['command_id'] || 'BusinessPayBill'
47
+ @sender_identifier_type = hash['sender_identifier_type'] || '4'
48
+ @receiver_identifier_type = hash['receiver_identifier_type'] || '4'
49
+ @party_a = hash['party_a'] || ENV.fetch('business_short_code', nil)
50
+ @account_reference = hash['account_reference'] || ''
51
+ @result_url = hash['result_url'] || ENV.fetch('result_url', nil)
52
+ @queue_timeout_url = hash['queue_timeout_url'] || ENV.fetch('queue_timeout_url', nil)
53
+ end
54
+
55
+ def send_payment
56
+ response = HTTParty.post(url, headers: headers, body: body)
57
+
58
+ raise StandardError, "Failed to send B2B payment: #{response.code} - #{response.body}" unless response.success?
59
+
60
+ JSON.parse(response.body)
61
+ end
62
+
63
+ private
64
+
65
+ def url
66
+ "#{ENV.fetch('base_url', nil)}#{ENV.fetch('b2b_url', nil)}"
67
+ end
68
+
69
+ def headers
70
+ {
71
+ 'Authorization' => "Bearer #{token}",
72
+ 'Content-Type' => 'application/json'
73
+ }
74
+ end
75
+
76
+ def body
77
+ {
78
+ Initiator: get_initiator,
79
+ SecurityCredential: get_security_credential,
80
+ CommandID: command_id,
81
+ SenderIdentifierType: sender_identifier_type,
82
+ RecieverIdentifierType: receiver_identifier_type,
83
+ Amount: amount.to_s,
84
+ PartyA: get_party_a,
85
+ PartyB: receiver_party,
86
+ AccountReference: account_reference,
87
+ QueueTimeOutURL: get_queue_timeout_url,
88
+ ResultURL: get_result_url
89
+ }.to_json
90
+ end
91
+
92
+ def get_initiator
93
+ if initiator.nil? || initiator.eql?('')
94
+ raise ArgumentError, 'Initiator is not defined' if ENV['initiator'].nil? || ENV['initiator'].eql?('')
95
+
96
+ ENV.fetch('initiator', nil)
97
+
98
+ else
99
+ initiator
100
+ end
101
+ end
102
+
103
+ def get_security_credential
104
+ if security_credential.nil? || security_credential.eql?('')
105
+ if ENV['security_credential'].nil? || ENV['security_credential'].eql?('')
106
+ raise ArgumentError, 'Security Credential is not defined'
107
+ end
108
+
109
+ ENV.fetch('security_credential', nil)
110
+
111
+ else
112
+ security_credential
113
+ end
114
+ end
115
+
116
+ def get_party_a
117
+ if party_a.nil? || party_a.eql?('')
118
+ if ENV['business_short_code'].nil? || ENV['business_short_code'].eql?('')
119
+ raise ArgumentError, 'PartyA (Business Short Code) is not defined'
120
+ end
121
+
122
+ ENV.fetch('business_short_code', nil)
123
+
124
+ else
125
+ party_a
126
+ end
127
+ end
128
+
129
+ def get_result_url
130
+ if result_url.nil? || result_url.eql?('')
131
+ raise ArgumentError, 'Result URL is not defined' if ENV['result_url'].nil? || ENV['result_url'].eql?('')
132
+
133
+ ENV.fetch('result_url', nil)
134
+
135
+ else
136
+ result_url
137
+ end
138
+ end
139
+
140
+ def get_queue_timeout_url
141
+ if queue_timeout_url.nil? || queue_timeout_url.eql?('')
142
+ if ENV['queue_timeout_url'].nil? || ENV['queue_timeout_url'].eql?('')
143
+ raise ArgumentError, 'Queue Timeout URL is not defined'
144
+ end
145
+
146
+ ENV.fetch('queue_timeout_url', nil)
147
+
148
+ else
149
+ queue_timeout_url
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,151 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018 mboya
4
+ #
5
+ # MIT License
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"), to deal
9
+ # in the Software without restriction, including without limitation the rights
10
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ # copies of the Software, and to permit persons to whom the Software is
12
+ # furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included in
15
+ # all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ # THE SOFTWARE.
24
+
25
+ require 'mpesa_stk/access_token'
26
+
27
+ module MpesaStk
28
+ # Business to Customer payment API - send money from business to customers
29
+ class B2C
30
+ class << self
31
+ def pay(amount, phone_number, hash = {})
32
+ new(amount, phone_number, hash).send_payment
33
+ end
34
+ end
35
+
36
+ attr_reader :token, :amount, :phone_number, :initiator_name, :security_credential, :command_id, :party_a, :remarks,
37
+ :result_url, :queue_timeout_url, :occasion
38
+
39
+ def initialize(amount, phone_number, hash = {})
40
+ @token = MpesaStk::AccessToken.call(hash['key'], hash['secret'])
41
+ @amount = amount
42
+ @phone_number = phone_number
43
+ @initiator_name = hash['initiator_name'] || ENV.fetch('initiator_name', nil)
44
+ @security_credential = hash['security_credential'] || ENV.fetch('security_credential', nil)
45
+ @command_id = hash['command_id'] || 'BusinessPayment'
46
+ @party_a = hash['party_a'] || ENV.fetch('business_short_code', nil)
47
+ @remarks = hash['remarks'] || 'Payment'
48
+ @result_url = hash['result_url'] || ENV.fetch('result_url', nil)
49
+ @queue_timeout_url = hash['queue_timeout_url'] || ENV.fetch('queue_timeout_url', nil)
50
+ @occasion = hash['occasion']
51
+ end
52
+
53
+ def send_payment
54
+ response = HTTParty.post(url, headers: headers, body: body)
55
+
56
+ raise StandardError, "Failed to send B2C payment: #{response.code} - #{response.body}" unless response.success?
57
+
58
+ JSON.parse(response.body)
59
+ end
60
+
61
+ private
62
+
63
+ def url
64
+ "#{ENV.fetch('base_url', nil)}#{ENV.fetch('b2c_url', nil)}"
65
+ end
66
+
67
+ def headers
68
+ {
69
+ 'Authorization' => "Bearer #{token}",
70
+ 'Content-Type' => 'application/json'
71
+ }
72
+ end
73
+
74
+ def body
75
+ body_hash = {
76
+ InitiatorName: get_initiator_name,
77
+ SecurityCredential: get_security_credential,
78
+ CommandID: command_id,
79
+ Amount: amount.to_s,
80
+ PartyA: get_party_a,
81
+ PartyB: phone_number,
82
+ Remarks: remarks,
83
+ QueueTimeOutURL: get_queue_timeout_url,
84
+ ResultURL: get_result_url
85
+ }
86
+ body_hash[:Occasion] = occasion if occasion
87
+ body_hash.to_json
88
+ end
89
+
90
+ def get_initiator_name
91
+ if initiator_name.nil? || initiator_name.eql?('')
92
+ raise ArgumentError, 'Initiator Name is not defined' if ENV['initiator_name'].nil? || ENV['initiator_name'].eql?('')
93
+
94
+ ENV.fetch('initiator_name', nil)
95
+
96
+ else
97
+ initiator_name
98
+ end
99
+ end
100
+
101
+ def get_security_credential
102
+ if security_credential.nil? || security_credential.eql?('')
103
+ if ENV['security_credential'].nil? || ENV['security_credential'].eql?('')
104
+ raise ArgumentError, 'Security Credential is not defined'
105
+ end
106
+
107
+ ENV.fetch('security_credential', nil)
108
+
109
+ else
110
+ security_credential
111
+ end
112
+ end
113
+
114
+ def get_party_a
115
+ if party_a.nil? || party_a.eql?('')
116
+ if ENV['business_short_code'].nil? || ENV['business_short_code'].eql?('')
117
+ raise ArgumentError, 'PartyA (Business Short Code) is not defined'
118
+ end
119
+
120
+ ENV.fetch('business_short_code', nil)
121
+
122
+ else
123
+ party_a
124
+ end
125
+ end
126
+
127
+ def get_result_url
128
+ if result_url.nil? || result_url.eql?('')
129
+ raise ArgumentError, 'Result URL is not defined' if ENV['result_url'].nil? || ENV['result_url'].eql?('')
130
+
131
+ ENV.fetch('result_url', nil)
132
+
133
+ else
134
+ result_url
135
+ end
136
+ end
137
+
138
+ def get_queue_timeout_url
139
+ if queue_timeout_url.nil? || queue_timeout_url.eql?('')
140
+ if ENV['queue_timeout_url'].nil? || ENV['queue_timeout_url'].eql?('')
141
+ raise ArgumentError, 'Queue Timeout URL is not defined'
142
+ end
143
+
144
+ ENV.fetch('queue_timeout_url', nil)
145
+
146
+ else
147
+ queue_timeout_url
148
+ end
149
+ end
150
+ end
151
+ end