paymentsds-mpesa 0.1.0.pre.alpha.32 → 0.1.0.pre.alpha.33
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/lib/paymentsds/mpesa/errors/{unavailabe_server.rb → unavailable_server.rb} +0 -0
- data/lib/paymentsds/mpesa/version.rb +1 -1
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/checksums.yaml.gz +0 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data.tar.gz +0 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/.gitignore +13 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/.overcommit.yml +0 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/.rspec +3 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/.rubocop.yml +0 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/.travis.yml +6 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/Gemfile +7 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/LICENSE +201 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/README.md +261 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/Rakefile +6 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/bin/console +14 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/bin/setup +8 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa.rb +17 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/client.rb +29 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/configuration.rb +59 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/constants.rb +164 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/environment.rb +17 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/error_type.rb +8 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/constants.rb +50 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/direct_debt_missing.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/duplicate_direct_debt.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/errors.rb +26 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/inactive_account.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/initiator_authentication.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/insuficient_balance.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_amount.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_initiator_identifier.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_language_code.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_market.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_missing_properties.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_msisdn.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_receiver.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_reference.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_security_credential.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_shortcode.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_thirdparty_reference.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_transaction_id.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/invalid_transaction_reference.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/profile_problems.rb +0 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/request_timeout.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/transaction_cancelled.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/transaction_failed.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/unavailabe_server.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/unknown.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/unknown_status.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/errors/validation.rb +9 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/operation.rb +28 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/patterns.rb +12 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/result.rb +18 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/service.rb +311 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/lib/paymentsds/mpesa/version.rb +7 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/paymentsds-mpesa.gemspec +32 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/data/publish.sh +6 -0
- data/paymentsds-mpesa-0.1.0.pre.alpha.31/metadata.gz +0 -0
- metadata +57 -2
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Paymentsds
|
4
|
+
module MPesa
|
5
|
+
class Operation
|
6
|
+
attr_accessor :name
|
7
|
+
attr_accessor :method
|
8
|
+
attr_accessor :port
|
9
|
+
attr_accessor :path
|
10
|
+
attr_accessor :mapping
|
11
|
+
attr_accessor :requires
|
12
|
+
attr_accessor :validation
|
13
|
+
attr_accessor :optional
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
yield(self) if block_given?
|
17
|
+
end
|
18
|
+
|
19
|
+
def valid?
|
20
|
+
method_valid = ['get', 'post'].include? @method
|
21
|
+
port_valid = @port.to_s.match? /^[0-9]{1,5}$/
|
22
|
+
requires_is_array = @requires.is_a? Array
|
23
|
+
|
24
|
+
method_valid && port_valid && requires_is_array
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Paymentsds
|
2
|
+
module MPesa
|
3
|
+
class Result
|
4
|
+
attr_reader :error
|
5
|
+
attr_reader :data
|
6
|
+
|
7
|
+
def initialize(success, error, data)
|
8
|
+
@success = success
|
9
|
+
@error = error
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
def success?
|
14
|
+
@success
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,311 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'json'
|
3
|
+
require 'faraday'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
|
6
|
+
require_relative "errors/errors"
|
7
|
+
|
8
|
+
module Paymentsds
|
9
|
+
module MPesa
|
10
|
+
class Service
|
11
|
+
attr_accessor :config
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@config = Paymentsds::MPesa::Configuration.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def apply
|
18
|
+
@config.apply
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle_send(intent)
|
22
|
+
operation = detect_operation(intent)
|
23
|
+
handle_request(operation, intent)
|
24
|
+
end
|
25
|
+
|
26
|
+
def handle_receive(intent)
|
27
|
+
handle_request(:C2B_PAYMENT, intent)
|
28
|
+
end
|
29
|
+
|
30
|
+
def handle_revert(intent)
|
31
|
+
handle_request(:REVERSAL, intent)
|
32
|
+
end
|
33
|
+
|
34
|
+
def handle_query(_intent)
|
35
|
+
handle_request(:QUERY_TRANSACTION_STATUS, ntent)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def handle_request(opcode, intent)
|
41
|
+
data = fill_optional_properties(opcode, intent)
|
42
|
+
|
43
|
+
missing_properties = detect_missing_properties(opcode, data)
|
44
|
+
unless missing_properties.empty?
|
45
|
+
return Paymentsds::MPesa::Result.new(false, Paymentsds::MPesa::ErrorType::MISSING_PROPERTIES, missing_properties)
|
46
|
+
end
|
47
|
+
|
48
|
+
errors = detect_errors(opcode, data)
|
49
|
+
unless errors.empty?
|
50
|
+
return Paymentsds::MPesa::Result.new(false, Paymentsds::MPesa::ErrorType::VALIDATION_ERROR, errors)
|
51
|
+
end
|
52
|
+
|
53
|
+
perform_request(opcode, intent)
|
54
|
+
end
|
55
|
+
|
56
|
+
def detect_operation(intent)
|
57
|
+
if intent.key? :to
|
58
|
+
case intent[:to]
|
59
|
+
when /^((00|\+)?258)?8[45][0-9]{7}$/
|
60
|
+
:B2C_PAYMENT
|
61
|
+
when /^[0-9]{5,6}$/
|
62
|
+
:B2B_PAYMENT
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
raise InvalidDestination
|
67
|
+
end
|
68
|
+
|
69
|
+
def detect_missing_properties(opcode, intent)
|
70
|
+
operation = Paymentsds::MPesa::OPERATIONS[opcode]
|
71
|
+
|
72
|
+
operation[:required] - intent.keys
|
73
|
+
end
|
74
|
+
|
75
|
+
def detect_errors(opcode, intent)
|
76
|
+
operation = Paymentsds::MPesa::OPERATIONS[opcode]
|
77
|
+
|
78
|
+
errors = []
|
79
|
+
|
80
|
+
intent.each do |k, _v|
|
81
|
+
errors.push(k) unless (intent[k]).match operation[:validation][k]
|
82
|
+
end
|
83
|
+
|
84
|
+
errors
|
85
|
+
end
|
86
|
+
|
87
|
+
def fill_optional_properties(opcode, intent)
|
88
|
+
case opcode
|
89
|
+
when :C2B_PAYMENT
|
90
|
+
intent[:to] = @config.service_provider_code if !intent.key?(:to) && !@config.service_provider_code.nil?
|
91
|
+
when :B2B_PAYMENT
|
92
|
+
intent[:to] = @config.service_provider_code if !intent.key?(:to) && !@config.service_provider_code.nil?
|
93
|
+
when :B2C_PAYMENT
|
94
|
+
intent[:from] = @config.service_provider_code if !intent.key?(:from) && !@config.service_provider_code.nil?
|
95
|
+
when :REVERSAL
|
96
|
+
intent[:to] = @config.service_provider_code if !intent.key?(:to) && !@config.service_provider_code.nil?
|
97
|
+
|
98
|
+
if !intent.key?(:initiator_identifier) && !@config.initiator_identifier.nil?
|
99
|
+
intent[:initiator_identifier] = @config.initiator_identifier
|
100
|
+
end
|
101
|
+
|
102
|
+
if intent.key?(:security_credential) && !@config.security_credential.nil?
|
103
|
+
intent[:security_credential] = @config.security_credential
|
104
|
+
end
|
105
|
+
when :QUERY_TRANSACTION_STATUS
|
106
|
+
intent[:to] = @config.service_provider_code if !intent.key?(:to) && !@config.service_provider_code.nil?
|
107
|
+
end
|
108
|
+
|
109
|
+
intent
|
110
|
+
end
|
111
|
+
|
112
|
+
def build_request_body(opcode, intent)
|
113
|
+
operation = Paymentsds::MPesa::OPERATIONS[opcode]
|
114
|
+
|
115
|
+
body = {}
|
116
|
+
operation[:mapping].each do |k, v|
|
117
|
+
body[v] = intent[k]
|
118
|
+
end
|
119
|
+
|
120
|
+
body
|
121
|
+
end
|
122
|
+
|
123
|
+
def build_request_headers
|
124
|
+
generate_access_token
|
125
|
+
|
126
|
+
headers = {
|
127
|
+
'Authorization': "Bearer #{@config.auth}",
|
128
|
+
'Origin': @config.origin,
|
129
|
+
'Content-Type': 'application/json',
|
130
|
+
'User-Agent': @config.user_agent
|
131
|
+
}
|
132
|
+
|
133
|
+
headers
|
134
|
+
end
|
135
|
+
|
136
|
+
def perform_request(opcode, intent)
|
137
|
+
operation = Paymentsds::MPesa::OPERATIONS[opcode]
|
138
|
+
|
139
|
+
generate_access_token
|
140
|
+
|
141
|
+
request_data = {
|
142
|
+
base_url: "#{@config.environment.to_url}:#{operation[:port]}",
|
143
|
+
url: operation[:path],
|
144
|
+
method: operation[:method],
|
145
|
+
path: operation[:path],
|
146
|
+
headers: build_request_headers,
|
147
|
+
timeout: @config.timeout,
|
148
|
+
body: build_request_body(opcode, intent)
|
149
|
+
}
|
150
|
+
|
151
|
+
http_client = Faraday.new(url: request_data[:base_url]) do |client|
|
152
|
+
client.adapter Faraday.default_adapter
|
153
|
+
client.headers = request_data[:headers]
|
154
|
+
client.response :json
|
155
|
+
end
|
156
|
+
|
157
|
+
puts request_data[:base_url]
|
158
|
+
|
159
|
+
case operation[:method]
|
160
|
+
when :get
|
161
|
+
response = http_client.get(request_data[:path]) do |req|
|
162
|
+
req.params = request_data[:body]
|
163
|
+
req.options.timeout = request_data[:timeout]
|
164
|
+
end
|
165
|
+
|
166
|
+
when :post
|
167
|
+
response = http_client.post(request_data[:path]) do |req|
|
168
|
+
req.body = request_data[:body].to_json
|
169
|
+
req.options.timeout = request_data[:timeout]
|
170
|
+
end
|
171
|
+
|
172
|
+
when :put
|
173
|
+
response = http_client.put(request_data[:path]) do |req|
|
174
|
+
req.body = request_data[:body].to_json
|
175
|
+
req.options.timeout = request_data[:timeout]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
build_response(response)
|
180
|
+
end
|
181
|
+
|
182
|
+
def build_response(result)
|
183
|
+
|
184
|
+
case result.status
|
185
|
+
when 200
|
186
|
+
case result.body[:output_ResponseCode]
|
187
|
+
when Paymentsds::MPesa::INS0
|
188
|
+
response = Paymentsds::MPesa::Result.new(result.success?, nil, result.body)
|
189
|
+
else
|
190
|
+
raise UnknownError
|
191
|
+
end
|
192
|
+
|
193
|
+
when 201
|
194
|
+
case result.body[:output_ResponseCode]
|
195
|
+
when Paymentsds::MPesa::INS0
|
196
|
+
response = Paymentsds::MPesa::Result.new(result.success?, nil, result.body)
|
197
|
+
else
|
198
|
+
raise UnknownError
|
199
|
+
end
|
200
|
+
|
201
|
+
when 400
|
202
|
+
case result.body[:output_ResponseCode]
|
203
|
+
when Paymentsds::MPesa::INS13
|
204
|
+
raise InvalidShortcodeError
|
205
|
+
when Paymentsds::MPesa::INS14
|
206
|
+
raise InvalidReferenceError
|
207
|
+
when Paymentsds::MPesa::INS15
|
208
|
+
raise InvalidAmountError
|
209
|
+
when Paymentsds::MPesa::INS17
|
210
|
+
raise InvalidTransactionReferenceError
|
211
|
+
when Paymentsds::MPesa::INS18
|
212
|
+
raise InvalidTransactionIdError
|
213
|
+
when Paymentsds::MPesa::INS19
|
214
|
+
raise InvalidThirdPartyReferenceError
|
215
|
+
when Paymentsds::MPesa::INS20
|
216
|
+
raise InvalidMissingPropertiesError
|
217
|
+
when Paymentsds::MPesa::INS21
|
218
|
+
raise ValidationError
|
219
|
+
when Paymentsds::MPesa::INS22
|
220
|
+
raise InvalidOperationPartError
|
221
|
+
when Paymentsds::MPesa::INS23
|
222
|
+
raise UnknownStatusError
|
223
|
+
when Paymentsds::MPesa::INS24
|
224
|
+
raise InvalidInitiatorIdentifierError
|
225
|
+
when Paymentsds::MPesa::INS25
|
226
|
+
raise InvalidSecurityCredentialError
|
227
|
+
when Paymentsds::MPesa::INS993
|
228
|
+
raise DirectDebtMissingError
|
229
|
+
when Paymentsds::MPesa::INS994
|
230
|
+
raise DuplicatedDirectDebtError
|
231
|
+
when Paymentsds::MPesa::INS995
|
232
|
+
raise ProfileProblemsError
|
233
|
+
when Paymentsds::MPesa::INS996
|
234
|
+
raise InactiveAccountError
|
235
|
+
when Paymentsds::MPesa::INS997
|
236
|
+
raise InvalidLanguageCodeError
|
237
|
+
when Paymentsds::MPesa::INS998
|
238
|
+
raise InvalidMarketError
|
239
|
+
when Paymentsds::MPesa::INS2001
|
240
|
+
raise InitiatorAuthenticationError
|
241
|
+
when Paymentsds::MPesa::INS2002
|
242
|
+
raise InvalidReceiverError
|
243
|
+
when Paymentsds::MPesa::INS2051
|
244
|
+
raise InvalidMSISDNError
|
245
|
+
when Paymentsds::MPesa::INS2057
|
246
|
+
raise InvalidLanguageCodeError
|
247
|
+
else
|
248
|
+
raise UnknownError
|
249
|
+
end
|
250
|
+
|
251
|
+
when 401
|
252
|
+
case result.body[:output_ResponseCode]
|
253
|
+
when Paymentsds::MPesa::INS5
|
254
|
+
raise TransactionCancelledError
|
255
|
+
when Paymentsds::MPesa::INS6
|
256
|
+
raise TransactionFailedError
|
257
|
+
else
|
258
|
+
raise UnknownError
|
259
|
+
end
|
260
|
+
|
261
|
+
when 408
|
262
|
+
case result.body[:output_ResponseCode]
|
263
|
+
when Paymentsds::MPesa::INS9
|
264
|
+
raise RequestTimeoutError
|
265
|
+
else
|
266
|
+
raise UnknownError
|
267
|
+
end
|
268
|
+
|
269
|
+
when 409
|
270
|
+
case result.body[:output_ResponseCode]
|
271
|
+
when Paymentsds::MPesa::INS10
|
272
|
+
raise DuplicateTransactionError
|
273
|
+
else
|
274
|
+
raise UnknownError
|
275
|
+
end
|
276
|
+
|
277
|
+
when 422
|
278
|
+
case result.body[:output_ResponseCode]
|
279
|
+
when Paymentsds::MPesa::INS2006
|
280
|
+
raise InsufficientBalanceError
|
281
|
+
else
|
282
|
+
raise UnknownError
|
283
|
+
end
|
284
|
+
|
285
|
+
when 500
|
286
|
+
case result.body[:output_ResponseCode]
|
287
|
+
when Paymentsds::MPesa::INS1
|
288
|
+
raise InternalError
|
289
|
+
else
|
290
|
+
raise UnknownError
|
291
|
+
end
|
292
|
+
|
293
|
+
when 503
|
294
|
+
case result.body[:output_ResponseCode]
|
295
|
+
when Paymentsds::MPesa::INS16
|
296
|
+
raise UnavailableServerError
|
297
|
+
else
|
298
|
+
raise UnknownError
|
299
|
+
end
|
300
|
+
|
301
|
+
else
|
302
|
+
raise UnknownError
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
def generate_access_token
|
307
|
+
@config.generate_access_token
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|