africastalking-ruby 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2a117033fd96f8fd02fea7b920c4de4ca4fc3f867fd49e237f4c61a9db5a714f
4
- data.tar.gz: 5ff1623f5cadeb1535c52edae7810875ae96d9d189da4b99051adc72ebde43fc
3
+ metadata.gz: dca31bfa111626fd5bb545355e8e5153fcc5802506f0ff0130d42ec7684e4010
4
+ data.tar.gz: 891a67cb4eddc687c65b34cf914768539018a0265b94003c3d0f03493c360ebd
5
5
  SHA512:
6
- metadata.gz: 1cccc4bb7c8d0b427fd0e0a5e7bc3c22761d16a651b9970a621c750416a9b4a5b28057f09458aeb0f4c6b6fd5cd0a480013e86e2f63a2075cf7ddcb76969b1d0
7
- data.tar.gz: c25f68df3fda65f73978dd18cf864bb0e013f7ba0b246633f4b6f7ee051d975aa03b7999812072c5e2d138a66d38e971f454a812830990466583cebaa52529d0
6
+ metadata.gz: 44b4c9251a44965e922280d21b56e802564953048e2dd7216c58c206f3c1b7fcbd90bb71afcfb0577ee7106eafeebd0656183c593c80af6b761eba3214506f1c
7
+ data.tar.gz: f10b0d58c5f0b85a100c7925e3fd035b009e35cc7297ae212fba36ff74d81de5f0b53ee8efbf9696a500499742bba65a710283e85f3f185c876dafe003808adb
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- africastalking-ruby (2.0.0)
4
+ africastalking-ruby (2.1.0)
5
5
  httparty (= 0.16.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,3 +1,4 @@
1
+
1
2
  # AfricasTalking SDK
2
3
 
3
4
  > Provides convenient access to the Africa's Talking API from applications written in ruby.
@@ -5,12 +6,14 @@
5
6
  ## Documentation
6
7
  Take a look at the [API docs here](http://docs.africastalking.com).
7
8
 
9
+ [![Gem Version](https://badge.fury.io/rb/africastalking-ruby.svg)](https://badge.fury.io/rb/africastalking-ruby)
10
+
8
11
  ## Installation
9
12
 
10
13
  Add this line to your application's Gemfile:
11
14
 
12
15
  ```ruby
13
- gem "africastalking-ruby", :git => "git@github.com:AfricasTalkingLtd/africastalking-ruby.git"
16
+ gem "africastalking-ruby"
14
17
  ```
15
18
 
16
19
  And then execute:
@@ -19,7 +22,7 @@ And then execute:
19
22
 
20
23
  <!-- Or install it yourself as:
21
24
 
22
- $ gem install AfricasTalking -->
25
+ $ gem install africastalking-ruby -->
23
26
 
24
27
  ## Usage
25
28
 
@@ -69,8 +72,9 @@ airtime.send options
69
72
  ```
70
73
  - `options`
71
74
  - `recipients`: Contains an hash of arrays containing the following keys
72
- - `phoneNumber`: Recipient of airtime
73
- - `amount`: Amount sent `>= 10 && <= 10K` with currency e.g `KES 100`
75
+ - `phoneNumber`: Recipient of airtime `REQUIRED`
76
+ - `currency`:3-digit ISO format currency code . `REQUIRED`
77
+ - `amount`: Amount sent `>= 10 && <= 10K` with currency e.g `KES 100` `REQUIRED`
74
78
 
75
79
  ### Sms
76
80
 
@@ -129,9 +133,18 @@ sms.fetchSubscriptions options
129
133
  ```
130
134
  - `options`
131
135
  - `shortCode`: This is a premium short code mapped to your account. `REQUIRED`
132
- - `keyword`: Value is a premium keyword under the above short code and mapped to your account. `REQUIRED`
136
+ - `keyword`: Premium keyword under the above short code and mapped to your account. `REQUIRED`
133
137
  - `lastReceivedId`: ID of the subscription you believe to be your last. Defaults to `0`
134
138
 
139
+ #### Delete Subscription
140
+ ```ruby
141
+ sms.deleteSubscriptions options
142
+ ```
143
+ - `options`
144
+ - `shortCode`: This is a premium short code mapped to your account. `REQUIRED`
145
+ - `keyword`: Premium keyword under the above short code and mapped to your account. `REQUIRED`
146
+ - `phoneNumber`: PhoneNumber to be unsubscribed `REQUIRED`
147
+
135
148
  ### Voice
136
149
  ```ruby
137
150
  voice = @AT.voice
@@ -178,7 +191,7 @@ payments = @AT.payments
178
191
  ```
179
192
  #### Credit card checkout
180
193
  ```ruby
181
- payments.cardCheckout options
194
+ payments.cardCheckoutCharge options
182
195
  ```
183
196
  - `options`
184
197
  - `productName`: Payment Product as setup on your account. `REQUIRED`
@@ -190,6 +203,7 @@ payments.cardCheckout options
190
203
  - `number`: The payment card number. `REQUIRED`
191
204
  - `cvvNumber`: The 3 or 4 digit Card Verification Value. `REQUIRED`
192
205
  - `expiryMonth`: The expiration month on the card (e.g `8`) `REQUIRED`
206
+ - `expiryYear`: The expiration year on the card (e.g `2020`) `REQUIRED`
193
207
  - `authToken`: The card's ATM PIN. `REQUIRED`
194
208
  - `countryCode`: The 2-Digit countryCode where the card was issued (only `NG` is supported). `REQUIRED`
195
209
  - `metadata`: Some optional data to associate with transaction. `OPTIONAL`
@@ -197,7 +211,7 @@ payments.cardCheckout options
197
211
  #### Validate credit card checkout
198
212
 
199
213
  ```ruby
200
- payments.validateCardCheckout options
214
+ payments.cardCheckoutValidate options
201
215
  ```
202
216
  - `options`
203
217
  - `transactionId`: The transaction that your application wants to validate. `REQUIRED`
@@ -206,7 +220,7 @@ payments.validateCardCheckout options
206
220
 
207
221
  #### Initiate bank charge checkout
208
222
  ```ruby
209
- payments.initiateBankChargeCheckout options
223
+ payments.bankCheckoutCharge options
210
224
  ```
211
225
  - `options`
212
226
  - `productName`: Payment Product as setup on your account. `REQUIRED`
@@ -214,8 +228,15 @@ payments.initiateBankChargeCheckout options
214
228
 
215
229
  - `accountName`: The name of the bank account. `REQUIRED`
216
230
  - `accountNumber`: The account number. `REQUIRED`
217
- - `bankCode`: A 6-Digit [Integer Code](http://docs.africastalking.com/bank/checkout) for the bank that we allocate. See `payments.BANK.*` for supported banks. `REQUIRED`
218
231
  - `dateOfBirth`: Date of birth of the account owner (`YYYY-MM-DD`). Required for Zenith Bank Nigeria.
232
+ - `bankCode`: A 6-Digit [Integer Code](http://docs.africastalking.com/bank/checkout) for the bank that we allocate. Supported banks at the moment are: `REQUIRED`
233
+ ```ruby
234
+ payments.class::BANK_CODES['FCMB_NG']
235
+ payments.class::BANK_CODES['ZENITH_NG']
236
+ payments.class::BANK_CODES['ACCESS_NG']
237
+ payments.class::BANK_CODES['PROVIDUS_NG']
238
+ payments.class::BANK_CODES['STERLING_NG']
239
+ ```
219
240
 
220
241
  - `currencyCode`: 3-digit ISO format currency code (only `NGN` is supported). `REQUIRED`
221
242
  - `amount`: Payment amount. `REQUIRED`
@@ -225,7 +246,7 @@ payments.initiateBankChargeCheckout options
225
246
 
226
247
  #### Validate bank checkout
227
248
  ```ruby
228
- payments.validateBankCheckout options
249
+ payments.bankCheckoutValidate options
229
250
  ```
230
251
  - `options`
231
252
  - `transactionId`: The transaction that your application wants to validate. `REQUIRED`
@@ -243,7 +264,7 @@ payments.bankTransfer options
243
264
  - `bankAccount`: Bank account to be charged:
244
265
  - `accountName`: The name of the bank account.
245
266
  - `accountNumber`: The account number `REQUIRED`
246
- - `bankCode`: A 6-Digit Integer Code for the bank that we allocate; See `payments.BANK.*` for supported banks. `REQUIRED`
267
+ - `bankCode`: A 6-Digit Integer Code for the bank that we allocate; See `payments.class::BANK_CODES` for supported banks. `REQUIRED`
247
268
  - `currencyCode`: 3-digit ISO format currency code (only `NGN` is supported). `REQUIRED`
248
269
  - `amount`: Payment amount. `REQUIRED`
249
270
  - `narration`: A short description of the transaction `REQUIRED`
@@ -274,7 +295,6 @@ payments.mobileB2C options
274
295
  - `amount`: Payment amount. `REQUIRED`
275
296
  - `providerChannel`: This represents the payment channel the payment will be made from. eg paybill number. The payment channel must be mapped to you. The AfricasTalking default provider channel is used if not specified.
276
297
  - `reason`: This field contains a string showing the purpose for the payment. If set, it should be one of the following
277
-
278
298
  ```
279
299
  SalaryPayment
280
300
  SalaryPaymentWithWithdrawalChargePaid
@@ -282,7 +302,6 @@ payments.mobileB2C options
282
302
  BusinessPaymentWithWithdrawalChargePaid
283
303
  PromotionPayment
284
304
  ```
285
-
286
305
  - `metadata`: Some optional data to associate with transaction.
287
306
 
288
307
  #### Mobile B2B
@@ -298,23 +317,84 @@ payments.mobileB2B options
298
317
  ```
299
318
  Athena - Please note: This is not available on our production systems
300
319
  Mpesa
320
+
301
321
  ```
302
322
  - `transferType`: This contains the payment provider that is facilitating this transaction. Supported providers at the moment are:
303
-
304
- ```
305
- BusinessBuyGoods
306
- BusinessPayBill
307
- DisburseFundsToBusiness
308
- BusinessToBusinessTransfer
309
- ```
323
+ ```
324
+ BusinessBuyGoods
325
+ BusinessPayBill
326
+ DisburseFundsToBusiness
327
+ BusinessToBusinessTransfer
328
+ ```
310
329
  - `destinationChannel`: This value contains the name or number of the channel that will receive payment by the provider. `REQUIRED`
311
330
  - `destinationAccount`: This value contains the account name used by the business to receive money on the provided destinationChannel. `REQUIRED`
312
331
  - `currencyCode`: 3-digit ISO format currency code (e.g `KES`, `USD`, `UGX` etc.) `REQUIRED`
313
-
314
332
  - `amount`: Payment amount. `REQUIRED`
315
- - `metadata`: Some optional data to associate with transaction.`OPTIONAL`
333
+ - `metadata`: Some optional data to associate with transaction.`REQUIRED`
316
334
 
335
+ #### Wallet Transfer
336
+ ```ruby
337
+ payments.walletTransfer options
338
+ ```
339
+ - `options`
340
+ - `productName`: Your Payment Product as setup on your account. `REQUIRED`
341
+ - `targetProductCode`: Unique code ode of payment product receiving funds on Africa's Talking `REQUIRED`
342
+ - `currencyCode`: 3-digit ISO format currency code. `REQUIRED`
343
+ - `amount`: Amount to transfer. `REQUIRED`
344
+ - `metadata`: Additional data to associate with the transaction. `REQUIRED`
317
345
 
346
+ #### Topup Stash
347
+ ```ruby
348
+ payments.topupStash options
349
+ ```
350
+ - `options`
351
+ - `productName`: Your Payment Product as setup on your account. `REQUIRED`
352
+ - `currencyCode`: 3-digit ISO format currency code. `REQUIRED`
353
+ - `amount`: Amount to transfer. `REQUIRED`
354
+ - `metadata`: Additonal data to associate with the transaction. `REQUIRED`
355
+
356
+ #### Fetch Product Transactions
357
+ ```ruby
358
+ payments.fetchProductTransactions options
359
+ ```
360
+ - `options`
361
+ - `productName`: Your Payment Product as setup on your account. `REQUIRED`
362
+ - `filters`: Filters to use when fetching transactions:
363
+ - `pageNumber`: Page number to fetch results from. Starts from `1`. `REQUIRED`
364
+ - `count`: Number of results to fetch. `REQUIRED`
365
+ - `startDate`: Start Date to consider when fetching
366
+ - `endDate`: End Date to consider when fetching
367
+ - `category`: Category to consider when fetching
368
+ - `provider`: Provider to consider when fetching
369
+ - `status`: Status to consider when fetching
370
+ - `source`: Source to consider when fetching
371
+ - `destination`: Destination to consider when fetching
372
+ - `providerChannel`: Provider to consider when fetching
373
+
374
+ #### fetch Wallet Transactions
375
+ ```ruby
376
+ payments.fetchWalletTransactions options
377
+ ```
378
+ - `options`
379
+ - `filters`: Filters to use when fetching transactions:
380
+ - `pageNumber`: Page number to fetch results from. Starts from `1`. `REQUIRED`
381
+ - `count`: Number of results to fetch. `REQUIRED`
382
+ - `startDate`: Start Date to consider when fetching
383
+ - `endDate`: End Date to consider when fetching
384
+ - `categories`: Comma delimited list of categories to consider when fetching
385
+
386
+ #### Find Transaction
387
+ ```ruby
388
+ payments.findTransaction options
389
+ ```
390
+ - `options`
391
+ - `transactionId`: ID of trancation to find `REQUIRED`
392
+
393
+ #### Fetch Wallet Balance
394
+ ```ruby
395
+ payments.fetchWalletBalance
396
+ ```
397
+ - Fetch your payment wallet balance
318
398
 
319
399
 
320
400
  ## Development
@@ -60,10 +60,6 @@ module AfricasTalking
60
60
  uri = URI.parse(url_)
61
61
  http = Net::HTTP.new(uri.host, uri.port)
62
62
  http.use_ssl = true
63
- headers = {
64
- "apikey" => @apikey,
65
- "Accept" => "application/json"
66
- }
67
63
  if(data_ != nil)
68
64
  request = Net::HTTP::Post.new(uri.request_uri)
69
65
  request.set_form_data(data_)
@@ -82,19 +78,21 @@ module AfricasTalking
82
78
  return response.body
83
79
  end
84
80
 
85
- def sendJSONRequest (url_, data_)
81
+ def sendJSONRequest url_, data_, get_request = false
86
82
  uri = URI.parse(url_)
87
83
  http = Net::HTTP.new(uri.host, uri.port)
88
84
  http.use_ssl = true
89
- req = Net::HTTP::Post.new(uri.request_uri, 'Content-Type'=>"application/json")
85
+ if get_request === true
86
+ uri.query = URI.encode_www_form(data_)
87
+ req = Net::HTTP::Get.new(uri.request_uri, 'Content-Type'=>"application/json")
88
+ else
89
+ req = Net::HTTP::Post.new(uri.request_uri, 'Content-Type'=>"application/json")
90
+ req.body = data_.to_json
91
+ end
90
92
 
91
93
  req["apikey"] = @apikey
92
94
  req["Accept"] = "application/json"
93
-
94
- req.body = data_.to_json
95
-
96
95
  response = http.request(req)
97
-
98
96
  if (DEBUG)
99
97
  puts "Full response #{response.body}"
100
98
  end
@@ -112,7 +110,5 @@ module AfricasTalking
112
110
  end
113
111
  }
114
112
  return true
115
-
116
113
  end
117
-
118
114
  end
@@ -10,14 +10,18 @@ class Airtime
10
10
  end
11
11
 
12
12
  def send options
13
- recipients = options.collect{ |r| r }
14
- post_body = {
15
- 'username' => @username,
16
- 'recipients' => recipients.to_json
17
- }
18
13
  url = getAirtimeUrl() + "/send"
19
- response = sendNormalRequest(url, post_body)
20
- #
14
+
15
+ recipients = options.each{|item|
16
+ validateParamsPresence? item, %w(phoneNumber currencyCode amount)
17
+ item['amount'].to_s.prepend(item['currencyCode'].to_s + " ")
18
+ item.delete('currencyCode')
19
+ }
20
+ post_body = {
21
+ 'username' => @username,
22
+ 'recipients' => recipients.to_json,
23
+ }
24
+ response = sendNormalRequest(url, post_body)
21
25
  if (@response_code == HTTP_CREATED)
22
26
  responses = JSON.parse(response, :quirky_mode =>true)
23
27
  if (responses['responses'].length > 0)
@@ -31,7 +35,6 @@ class Airtime
31
35
  else
32
36
  raise AfricasTalkingException, responses['errorMessage']
33
37
  end
34
- else
35
38
  raise AfricasTalkingException, response
36
39
  end
37
40
  end
@@ -2,7 +2,6 @@ class Payments
2
2
  include AfricasTalking
3
3
  HTTP_CREATED = 201
4
4
  HTTP_OK = 200
5
- #Set debug flag to to true to view response body
6
5
  BANK_CODES = {
7
6
  'FCMB_NG' => 234001,
8
7
  'ZENITH_NG' => 234002,
@@ -27,26 +26,31 @@ class Payments
27
26
  'WEMA_NG' => 234021,
28
27
  'FIRST_NG' => 234022,
29
28
  }
29
+ PROVIDERS = {
30
+ 'MPESA' => 'Mpesa',
31
+ 'SEGOVIA' => 'Segovia',
32
+ 'FLUTTERWAVE' => 'Flutterwave',
33
+ 'ADMIN' => 'Admin',
34
+ 'ATHENA' => 'Athena',
35
+ }
30
36
  def initialize username, apikey
31
37
  @username = username
32
38
  @apikey = apikey
33
39
  end
34
40
 
35
41
  def mobileCheckout options
42
+ validateParamsPresence? options, %w(productName phoneNumber currencyCode amount metadata)
43
+ parameters = {
44
+ 'username' => @username,
45
+ 'productName' => options['productName'],
46
+ 'phoneNumber' => options['phoneNumber'],
47
+ 'currencyCode' => options['currencyCode'],
48
+ 'amount' => options['amount'],
49
+ 'metadata' => options['metadata']
50
+ }
36
51
  url = getMobilePaymentCheckoutUrl()
37
- if validateParamsPresence?(options, ['productName', 'phoneNumber', 'currencyCode', 'amount', 'metadata'])
38
- parameters = {
39
- 'username' => @username,
40
- 'productName' => options['productName'],
41
- 'phoneNumber' => options['phoneNumber'],
42
- 'currencyCode' => options['currencyCode'],
43
- 'amount' => options['amount'],
44
- 'metadata' => options['metadata']
45
- }
46
- response = sendJSONRequest(url, parameters)
47
- end
48
-
49
- if (@response_code == HTTP_CREATED)
52
+ response = sendJSONRequest(url, parameters)
53
+ if @response_code == HTTP_CREATED
50
54
  resultObj = JSON.parse(response, :quirky_mode =>true)
51
55
  #
52
56
  if (resultObj['status'] == 'PendingConfirmation')
@@ -58,48 +62,44 @@ class Payments
58
62
  end
59
63
 
60
64
  def mobileB2B options
61
- validOptions = validateParamsPresence?(options, ['productName', 'providerData', 'currencyCode', 'amount', 'metadata'])
62
- validProviderData = validateParamsPresence?(options['providerData'], ['provider', 'destinationAccount', 'destinationChannel', 'transferType'])
63
- if validOptions && validProviderData
64
- parameters = {
65
- 'username' => @username,
66
- 'productName' => options['productName'],
67
- 'provider' => options['providerData']['provider'],
68
- 'destinationChannel' => options['providerData']['destinationChannel'],
69
- 'destinationAccount' => options['providerData']['destinationAccount'],
70
- 'transferType' => options['providerData']['transferType'],
71
- 'currencyCode' => options['currencyCode'],
72
- 'amount' => options['amount'],
73
- 'metadata' => options['metadata']
74
- }
75
- url = getMobilePaymentB2BUrl()
76
- response = sendJSONRequest(url, parameters)
77
- end
78
-
65
+ validateParamsPresence? options, %w(productName providerData currencyCode amount metadata)
66
+ validateParamsPresence? options['providerData'], %w(provider destinationAccount destinationChannel transferType)
67
+ parameters = {
68
+ 'username' => @username,
69
+ 'productName' => options['productName'],
70
+ 'provider' => options['providerData']['provider'],
71
+ 'destinationChannel' => options['providerData']['destinationChannel'],
72
+ 'destinationAccount' => options['providerData']['destinationAccount'],
73
+ 'transferType' => options['providerData']['transferType'],
74
+ 'currencyCode' => options['currencyCode'],
75
+ 'amount' => options['amount'],
76
+ 'metadata' => options['metadata']
77
+ }
78
+ url = getMobilePaymentB2BUrl()
79
+ response = sendJSONRequest(url, parameters)
79
80
  if (@response_code == HTTP_CREATED)
80
81
  resultObj = JSON.parse(response, :quirky_mode =>true)
81
82
  #
82
- return MobileB2BResponse.new resultObj['status'], resultObj['transactionId'], resultObj['transactionFee'], resultObj['providerChannel']
83
+ return MobileB2BResponse.new resultObj['status'], resultObj['transactionId'], resultObj['transactionFee'], resultObj['providerChannel'], resultObj['errorMessage']
83
84
  end
84
85
  raise AfricasTalkingException, response
85
86
  end
86
87
 
87
88
 
88
89
  def mobileB2C options
89
- if validateParamsPresence?(options, ['recipients', 'productName'])
90
- parameters = {
91
- 'username' => @username,
92
- 'productName' => options['productName'],
93
- 'recipients' => options['recipients']
94
- }
95
- url = getMobilePaymentB2CUrl()
96
- response = sendJSONRequest(url, parameters)
97
- end
90
+ validateParamsPresence? options, %w(recipients productName)
91
+ parameters = {
92
+ 'username' => @username,
93
+ 'productName' => options['productName'],
94
+ 'recipients' => options['recipients']
95
+ }
96
+ url = getMobilePaymentB2CUrl()
97
+ response = sendJSONRequest(url, parameters)
98
98
  if (@response_code == HTTP_CREATED)
99
99
  resultObj = JSON.parse(response, :quirky_mode =>true)
100
100
  if (resultObj['entries'].length > 0)
101
101
  results = resultObj['entries'].collect{ |subscriber|
102
- MobileB2CResponse.new subscriber['provider'], subscriber['phoneNumber'], subscriber['providerChannel'], subscriber['transactionFee'], subscriber['status'], subscriber['value'], subscriber['transactionId']
102
+ MobileB2CResponse.new subscriber['provider'], subscriber['phoneNumber'], subscriber['providerChannel'], subscriber['transactionFee'], subscriber['status'], subscriber['value'], subscriber['transactionId'], subscriber['errorMessage']
103
103
  }
104
104
  #
105
105
  return results
@@ -110,20 +110,19 @@ class Payments
110
110
  raise AfricasTalkingException, response
111
111
  end
112
112
 
113
- def bankCheckout options
114
- if validateParamsPresence?(options, ['bankAccount', 'productName', 'currencyCode', 'amount', 'narration', 'metadata'])
115
- parameters = {
116
- 'username' => @username,
117
- 'productName' => options['productName'],
118
- 'bankAccount' => options['bankAccount'],
119
- 'currencyCode' => options['currencyCode'],
120
- 'amount' => options['amount'],
121
- 'narration' => options['narration'],
122
- 'metadata' => options['metadata']
123
- }
124
- url = getBankChargeCheckoutUrl()
125
- response = sendJSONRequest(url, parameters)
126
- end
113
+ def bankCheckoutCharge options
114
+ validateParamsPresence? options, %w(bankAccount productName currencyCode amount narration metadata)
115
+ parameters = {
116
+ 'username' => @username,
117
+ 'productName' => options['productName'],
118
+ 'bankAccount' => options['bankAccount'],
119
+ 'currencyCode' => options['currencyCode'],
120
+ 'amount' => options['amount'],
121
+ 'narration' => options['narration'],
122
+ 'metadata' => options['metadata']
123
+ }
124
+ url = getBankChargeCheckoutUrl()
125
+ response = sendJSONRequest(url, parameters)
127
126
  if (@response_code == HTTP_CREATED)
128
127
  resultObj = JSON.parse(response, :quirky_mode =>true)
129
128
  #
@@ -132,17 +131,16 @@ class Payments
132
131
  raise AfricasTalkingException, response
133
132
  end
134
133
 
135
- def validateBankCheckout options
136
- if validateParamsPresence?(options, ['transactionId', 'otp'])
137
- parameters = {
138
- 'username' => @username,
139
- 'transactionId' => options['transactionId'],
140
- 'otp' => options['otp']
141
- }
142
- #
143
- url = getValidateBankCheckoutUrl()
144
- response = sendJSONRequest(url, parameters)
145
- end
134
+ def bankCheckoutValidate options
135
+ validateParamsPresence? options, %w(transactionId otp)
136
+ parameters = {
137
+ 'username' => @username,
138
+ 'transactionId' => options['transactionId'],
139
+ 'otp' => options['otp']
140
+ }
141
+ #
142
+ url = getValidateBankCheckoutUrl()
143
+ response = sendJSONRequest(url, parameters)
146
144
  if (@response_code == HTTP_CREATED)
147
145
  resultObj = JSON.parse(response, :quirky_mode =>true)
148
146
  return ValidateBankCheckoutResponse.new resultObj['status'], resultObj['description']
@@ -151,15 +149,14 @@ class Payments
151
149
  end
152
150
 
153
151
  def bankTransfer options
154
- if validateParamsPresence?(options, ['productName', 'recipients'])
155
- parameters = {
156
- 'username' => @username,
157
- 'productName' => options['productName'],
158
- 'recipients' => options['recipients']
159
- }
160
- url = getBankTransferRequestUrl()
161
- response = sendJSONRequest(url, parameters)
162
- end
152
+ validateParamsPresence? options, %w(productName recipients)
153
+ parameters = {
154
+ 'username' => @username,
155
+ 'productName' => options['productName'],
156
+ 'recipients' => options['recipients']
157
+ }
158
+ url = getBankTransferRequestUrl()
159
+ response = sendJSONRequest(url, parameters)
163
160
  if (@response_code == HTTP_CREATED)
164
161
  resultObj = JSON.parse(response, :quirky_mode =>true)
165
162
 
@@ -178,30 +175,31 @@ class Payments
178
175
 
179
176
  end
180
177
 
181
- def cardCheckout options
182
- if validateParamsPresence?(options, ['productName', 'currencyCode', 'amount', 'narration', 'metadata'])
183
- parameters = {
184
- 'username' => @username,
185
- 'productName' => options['productName'],
186
- 'currencyCode' => options['currencyCode'],
187
- 'amount' => options['amount'],
188
- 'narration' => options['narration'],
189
- 'metadata' => options['metadata']
190
- }
191
- if (options['checkoutToken'] == nil && options['paymentCard'] == nil)
192
- raise AfricasTalkingException "Please make sure either the checkoutToken or paymentCard parameter is not empty"
193
- elsif (options['checkoutToken'] != nil && options['paymentCard'] != nil)
194
- raise AfricasTalkingException "If you have a checkoutToken please make sure paymentCard parameter is empty"
195
- end
196
- if (options['checkoutToken'] != nil)
197
- parameters['checkoutToken'] = options['checkoutToken']
198
- end
199
- if (options['paymentCard'] != nil)
178
+ def cardCheckoutCharge options
179
+ validateParamsPresence? options, %w(productName currencyCode amount narration metadata)
180
+ parameters = {
181
+ 'username' => @username,
182
+ 'productName' => options['productName'],
183
+ 'currencyCode' => options['currencyCode'],
184
+ 'amount' => options['amount'],
185
+ 'narration' => options['narration'],
186
+ 'metadata' => options['metadata']
187
+ }
188
+ if (options['checkoutToken'] == nil && options['paymentCard'] == nil)
189
+ raise AfricasTalkingException, "Please make sure either the checkoutToken or paymentCard parameter is not empty"
190
+ elsif (options['checkoutToken'] != nil && options['paymentCard'] != nil)
191
+ raise AfricasTalkingException, "If you have a checkoutToken please make sure paymentCard parameter is empty"
192
+ end
193
+ if (options['checkoutToken'] != nil)
194
+ parameters['checkoutToken'] = options['checkoutToken']
195
+ end
196
+ if (options['paymentCard'] != nil)
197
+ if validateParamsPresence?(options['paymentCard'], ['number', 'cvvNumber', 'expiryMonth', 'expiryYear', 'countryCode', 'authToken'])
200
198
  parameters['paymentCard'] = options['paymentCard']
201
199
  end
202
- url = getCardCheckoutChargeUrl()
203
- response = sendJSONRequest(url, parameters)
204
200
  end
201
+ url = getCardCheckoutChargeUrl()
202
+ response = sendJSONRequest(url, parameters)
205
203
  if (@response_code == HTTP_CREATED)
206
204
  resultObj = JSON.parse(response, :quirky_mode =>true)
207
205
  #
@@ -211,17 +209,15 @@ class Payments
211
209
 
212
210
  end
213
211
 
214
- def validateCardCheckout options
215
- if validateParamsPresence?(options, ['transactionId', 'otp'])
216
- parameters = {
217
- 'username' => @username,
218
- 'transactionId' => options['transactionId'],
219
- 'otp' => options['otp']
220
- }
221
- url = getValidateCardCheckoutUrl()
222
- #
223
- response = sendJSONRequest(url, parameters)
224
- end
212
+ def cardCheckoutValidate options
213
+ validateParamsPresence? options, %w(transactionId otp)
214
+ parameters = {
215
+ 'username' => @username,
216
+ 'transactionId' => options['transactionId'],
217
+ 'otp' => options['otp']
218
+ }
219
+ url = getValidateCardCheckoutUrl()
220
+ response = sendJSONRequest(url, parameters)
225
221
  if (@response_code == HTTP_CREATED)
226
222
  resultObj = JSON.parse(response, :quirky_mode =>true)
227
223
  return ValidateCardCheckoutResponse.new resultObj['status'], resultObj['description'], resultObj['checkoutToken']
@@ -230,19 +226,18 @@ class Payments
230
226
  raise AfricasTalkingException, response
231
227
  end
232
228
 
233
- def walletTransferRequest options
234
- if validateParamsPresence?(options, ['productName', 'targetProductCode', 'currencyCode', 'amount', 'metadata'])
235
- parameters = {
236
- 'username' => @username,
237
- 'productName' => options['productName'],
238
- 'targetProductCode' => options['targetProductCode'],
239
- 'currencyCode' => options['currencyCode'],
240
- 'amount' => options['amount'],
241
- 'metadata' => options['metadata']
242
- }
243
- url = getWalletTransferUrl()
244
- response = sendJSONRequest(url, parameters)
245
- end
229
+ def walletTransfer options
230
+ validateParamsPresence? options, %w(productName targetProductCode currencyCode amount metadata)
231
+ parameters = {
232
+ 'username' => @username,
233
+ 'productName' => options['productName'],
234
+ 'targetProductCode' => options['targetProductCode'],
235
+ 'currencyCode' => options['currencyCode'],
236
+ 'amount' => options['amount'],
237
+ 'metadata' => options['metadata']
238
+ }
239
+ url = getWalletTransferUrl()
240
+ response = sendJSONRequest(url, parameters)
246
241
  if (@response_code == HTTP_CREATED)
247
242
  resultObj = JSON.parse(response, :quirky_mode =>true)
248
243
  #
@@ -251,18 +246,17 @@ class Payments
251
246
  raise AfricasTalkingException, response
252
247
  end
253
248
 
254
- def topupStashRequest options
255
- if validateParamsPresence?(options, ['productName', 'currencyCode', 'amount', 'metadata'])
256
- parameters = {
257
- 'username' => @username,
258
- 'productName' => options['productName'],
259
- 'currencyCode' => options['currencyCode'],
260
- 'amount' => options['amount'],
261
- 'metadata' => options['metadata']
262
- }
263
- url = getTopupStashUrl()
264
- response = sendJSONRequest(url, parameters)
265
- end
249
+ def topupStash options
250
+ validateParamsPresence? options, %w(productName currencyCode amount metadata)
251
+ parameters = {
252
+ 'username' => @username,
253
+ 'productName' => options['productName'],
254
+ 'currencyCode' => options['currencyCode'],
255
+ 'amount' => options['amount'],
256
+ 'metadata' => options['metadata']
257
+ }
258
+ url = getTopupStashUrl()
259
+ response = sendJSONRequest(url, parameters)
266
260
  if (@response_code == HTTP_CREATED)
267
261
  resultObj = JSON.parse(response, :quirky_mode =>true)
268
262
  return TopupStashResponse.new resultObj['status'], resultObj['description'], resultObj['transactionId']
@@ -270,6 +264,104 @@ class Payments
270
264
  raise AfricasTalkingException, response
271
265
  end
272
266
 
267
+ def fetchProductTransactions options
268
+ validateParamsPresence? options, %w(productName filters)
269
+ filters = options['filters']
270
+ validateParamsPresence? filters, %w(pageNumber count)
271
+ parameters = {
272
+ 'username' => @username,
273
+ 'productName' => options['productName'],
274
+ 'pageNumber' => filters['pageNumber'],
275
+ 'count' => filters['count']
276
+ }
277
+ parameters['startDate'] = filters['startDate'] if !(filters['startDate'].nil? || filters['startDate'].empty?)
278
+ parameters['endDate'] = filters['endDate'] if !(filters['endDate'].nil? || filters['endDate'].empty?)
279
+ parameters['category'] = filters['category'] if !(filters['category'].nil? || filters['category'].empty?)
280
+ parameters['status'] = filters['status'] if !(filters['status'].nil? || filters['status'].empty?)
281
+ parameters['source'] = filters['source'] if !(filters['source'].nil? || filters['source'].empty?)
282
+ parameters['destination'] = filters['destination'] if !(filters['destination'].nil? || filters['destination'].empty?)
283
+ parameters['providerChannel'] = filters['providerChannel'] if !(filters['providerChannel'].nil? || filters['providerChannel'].empty?)
284
+ url = getFetchTransactionsUrl()
285
+ response = sendJSONRequest(url, parameters, true)
286
+ if (@response_code == HTTP_OK)
287
+ resultObj = JSON.parse(response, :quirky_mode =>true)
288
+ results = []
289
+ if (resultObj['responses'].length > 0)
290
+ results = resultObj['responses'].collect{ |item|
291
+ FetchTransactionsEntries.new item['sourceType'], item['source'], item['provider'], item['destinationType'], item['description'], item['providerChannel'], item['providerMetadata'],
292
+ item['status'], item['productName'], item['category'], item['destination'], item['value'], item['transactionId'], item['creationTime'], item['requestMetadata']
293
+ }
294
+ end
295
+ return FetchTransactionsResponse.new resultObj['status'], resultObj['description'], results
296
+ end
297
+ raise AfricasTalkingException, response
298
+ end
299
+
300
+ def fetchWalletTransactions options
301
+ validateParamsPresence? options, ['filters']
302
+ filters = options['filters']
303
+ validateParamsPresence? filters, %w(pageNumber count)
304
+ parameters = {
305
+ 'username' => @username,
306
+ 'pageNumber' => filters['pageNumber'],
307
+ 'count' => filters['count']
308
+ }
309
+ parameters['startDate'] = filters['startDate'] if !(filters['startDate'].nil? || filters['startDate'].empty?)
310
+ parameters['endDate'] = filters['endDate'] if !(filters['endDate'].nil? || filters['endDate'].empty?)
311
+ parameters['categories'] = filters['categories'] if !(filters['categories'].nil? || filters['categories'].empty?)
312
+ url = getFetchWalletUrl()
313
+ response = sendJSONRequest(url, parameters, true)
314
+ if (@response_code == HTTP_OK)
315
+ resultObj = JSON.parse(response, :quirky_mode =>true)
316
+ results = []
317
+ if (resultObj['responses'].length > 0)
318
+ results = resultObj['responses'].collect{ |item|
319
+ transactionData = TransactionData.new item['transactionData']['requestMetadata'], item['transactionData']['sourceType'],
320
+ item['transactionData']['source'], item['transactionData']['provider'], item['transactionData']['destinationType'],item['transactionData']['description'],
321
+ item['transactionData']['providerChannel'], item['transactionData']['providerRefId'], item['transactionData']['providerMetadata'],item['transactionData']['status'],
322
+ item['transactionData']['productName'], item['transactionData']['category'], item['transactionData']['transactionDate'], item['transactionData']['destination'],
323
+ item['transactionData']['value'], item['transactionData']['transactionId'], item['transactionData']['creationTime']
324
+ FetchWalletEntries.new item['description'], item['balance'], item['date'], item['category'], item['value'], item['transactionId'], transactionData
325
+ }
326
+ end
327
+ return FetchWalletResponse.new resultObj['status'], resultObj['description'], results
328
+ end
329
+ raise AfricasTalkingException, response
330
+ end
331
+
332
+ def findTransaction options
333
+ validateParamsPresence? options, ['transactionId']
334
+ parameters = {
335
+ 'username' => @username,
336
+ 'transactionId' => options['transactionId']
337
+ }
338
+ url = getFindTransactionUrl()
339
+ response = sendJSONRequest(url, parameters, true)
340
+ if (@response_code == HTTP_OK)
341
+ resultObj = JSON.parse(response, :quirky_mode =>true)
342
+ transactionData = nil
343
+ if resultObj['status'] === 'Success'
344
+ transactionData = TransactionData.new resultObj['data']['requestMetadata'], resultObj['data']['sourceType'],resultObj['data']['source'], resultObj['data']['provider'], resultObj['data']['destinationType'],resultObj['data']['description'],
345
+ resultObj['data']['providerChannel'], resultObj['data']['providerRefId'], resultObj['data']['providerMetadata'],resultObj['data']['status'], resultObj['data']['productName'], resultObj['data']['category'],
346
+ resultObj['data']['transactionDate'], resultObj['data']['destination'], resultObj['data']['value'], resultObj['data']['transactionId'], resultObj['data']['creationTime']
347
+ end
348
+ return FindTransactionResponse.new resultObj['status'], transactionData
349
+ end
350
+ raise AfricasTalkingException, response
351
+ end
352
+
353
+ def fetchWalletBalance
354
+ parameters = { 'username' => @username }
355
+ url = getFetchWalletBalanceUrl()
356
+ response = sendJSONRequest(url, parameters, true)
357
+ if (@response_code == HTTP_OK)
358
+ resultObj = JSON.parse(response, :quirky_mode =>true)
359
+
360
+ return FetchWalletBalanceResponse.new resultObj['status'], resultObj['balance']
361
+ end
362
+ raise AfricasTalkingException, response
363
+ end
364
+
273
365
  private
274
366
 
275
367
  def getPaymentHost()
@@ -320,6 +412,22 @@ class Payments
320
412
  return getPaymentHost() + "/topup/stash"
321
413
  end
322
414
 
415
+ def getFetchWalletUrl()
416
+ return getPaymentHost() + "/query/wallet/fetch"
417
+ end
418
+
419
+ def getFetchWalletBalanceUrl()
420
+ return getPaymentHost() + "/query/wallet/balance"
421
+ end
422
+
423
+ def getFetchTransactionsUrl()
424
+ return getPaymentHost() + "/query/transaction/fetch"
425
+ end
426
+
427
+ def getFindTransactionUrl()
428
+ return getPaymentHost() + "/query/transaction/find"
429
+ end
430
+
323
431
  def getApiHost()
324
432
  if(@username == "sandbox")
325
433
  return "https://api.sandbox.africastalking.com"
@@ -330,10 +438,11 @@ class Payments
330
438
 
331
439
  end
332
440
 
441
+
333
442
  class MobileB2CResponse
334
- attr_reader :provider, :phoneNumber, :providerChannel, :transactionFee, :status, :value, :transactionId
443
+ attr_reader :provider, :phoneNumber, :providerChannel, :transactionFee, :status, :value, :transactionId, :errorMessage
335
444
 
336
- def initialize provider_, phoneNumber_, providerChannel_, transactionFee_, status_, value_, transactionId_
445
+ def initialize provider_, phoneNumber_, providerChannel_, transactionFee_, status_, value_, transactionId_, errorMessage_
337
446
  @provider = provider_
338
447
  @phoneNumber = phoneNumber_
339
448
  @providerChannel = providerChannel_
@@ -341,17 +450,19 @@ class MobileB2CResponse
341
450
  @status = status_
342
451
  @value = value_
343
452
  @transactionId = transactionId_
453
+ @errorMessage = errorMessage_
344
454
  end
345
455
  end
346
456
 
347
457
  class MobileB2BResponse
348
- attr_reader :status, :transactionId, :transactionFee, :providerChannel
458
+ attr_reader :status, :transactionId, :transactionFee, :providerChannel, :errorMessage
349
459
 
350
- def initialize status_, transactionId_, transactionFee_, providerChannel_
460
+ def initialize status_, transactionId_, transactionFee_, providerChannel_, errorMessage_
351
461
  @providerChannel = providerChannel_
352
462
  @transactionId = transactionId_
353
463
  @transactionFee = transactionFee_
354
464
  @status = status_
465
+ @errorMessage = errorMessage_
355
466
  end
356
467
  end
357
468
 
@@ -375,12 +486,12 @@ class BankTransferResponse
375
486
  end
376
487
 
377
488
  class MobileCheckoutResponse
378
- attr_reader :status, :transactionFee, :transactionId, :providerChannel
379
- def initialize accountNumber_, status_, transactionId_, transactionFee_
380
- @accountNumber = accountNumber_
489
+ attr_reader :status, :description, :transactionId, :providerChannel
490
+ def initialize status_, description_, transactionId_, providerChannel_
491
+ @description = description_
381
492
  @status = status_
382
493
  @transactionId = transactionId_
383
- @transactionFee = transactionFee_
494
+ @providerChannel = providerChannel_
384
495
  end
385
496
  end
386
497
  class InitiateBankCheckoutResponse
@@ -433,4 +544,97 @@ class TopupStashResponse
433
544
  @status = status_
434
545
  @transactionId = transactionId_
435
546
  end
547
+ end
548
+
549
+ class FetchTransactionsEntries
550
+ attr_reader :sourceType, :source, :provider, :destinationType, :description, :providerChannel,
551
+ :providerMetadata, :status, :productName, :category, :destination, :value, :transactionId, :creationTime, :requestMetadata
552
+
553
+ def initialize sourceType_, source_, provider_, destinationType_, description_, providerChannel_, providerMetadata_, status_, productName_, category_, destination_, value_, transactionId_, creationTime_, requestMetadata_
554
+ @sourceType = sourceType_
555
+ @source = source_
556
+ @provider = provider_
557
+ @destinationType = destinationType_
558
+ @description = description_
559
+ @providerChannel = providerChannel_
560
+ @providerMetadata = providerMetadata_
561
+ @status = status_
562
+ @productName = productName_
563
+ @category = category_
564
+ @destination = destination_
565
+ @value = value_
566
+ @transactionId = transactionId_
567
+ @creationTime = creationTime_
568
+ @requestMetadata = requestMetadata_
569
+ end
570
+ end
571
+
572
+ class FetchTransactionsResponse
573
+ attr_reader :status, :description, :entries
574
+ def initialize status_, description_, entries_
575
+ @description = description_
576
+ @status = status_
577
+ @entries = entries_
578
+ end
579
+ end
580
+
581
+ class FetchWalletBalanceResponse
582
+ attr_reader :status, :balance
583
+ def initialize status_, balance_
584
+ @status = status_
585
+ @balance = balance_
586
+ end
587
+ end
588
+
589
+ class FetchWalletResponse
590
+ attr_reader :status, :description, :responses
591
+ def initialize status_, description_, responses_
592
+ @description = description_
593
+ @status = status_
594
+ @responses = responses_
595
+ end
596
+ end
597
+
598
+ class FetchWalletEntries
599
+ attr_reader :description, :balance, :date, :category, :value, :transactionId, :transactionData
600
+ def initialize description_, balance_, date_, category_, value_, transactionId_, transactionData_
601
+ @description = description_
602
+ @balance = balance_
603
+ @date = date_
604
+ @category = category_
605
+ @value = value_
606
+ @transactionId = transactionId_
607
+ @transactionData = transactionData_
608
+ end
609
+ end
610
+
611
+ class FindTransactionResponse
612
+ attr_reader :status, :transactionData
613
+ def initialize status_, transactionData_
614
+ @status = status_
615
+ @transactionData = transactionData_
616
+ end
617
+ end
618
+
619
+ class TransactionData
620
+ attr_reader :requestMetadata, :sourceType, :source, :provider, :destinationType, :description, :providerChannel, :providerRefId, :providerMetadata, :status, :productName, :category, :transactionDate, :destination, :value, :transactionId, :creationTime
621
+ def initialize requestMetadata_, sourceType_, source_, provider_, destinationType_, description_, providerChannel_, providerRefId_, providerMetadata_, status_, productName_, category_, transactionDate_, destination_, value_, transactionId_, creationTime_
622
+ @requestMetadata =requestMetadata_
623
+ @sourceType = sourceType_
624
+ @source = source_
625
+ @provider = provider_
626
+ @destinationType = destinationType_
627
+ @description = description_
628
+ @providerChannel = providerChannel_
629
+ @providerRefId = providerRefId_
630
+ @providerMetadata = providerMetadata_
631
+ @status = status_
632
+ @productName = productName_
633
+ @category = category_
634
+ @transactionDate = transactionDate_
635
+ @destination = destination_
636
+ @value = value_
637
+ @transactionId = transactionId_
638
+ @creationTime = creationTime_
639
+ end
436
640
  end
@@ -27,8 +27,8 @@ class Sms
27
27
  if options['from'] != nil
28
28
  post_body['from'] = options['from']
29
29
  end
30
- if options['enqueue'] != nil
31
- post_body['enqueue'] = options['enqueue']
30
+ if options['enqueue'] === true
31
+ post_body['enqueue'] = 1
32
32
  end
33
33
  if options['bulkSMSMode'] != nil
34
34
  post_body['bulkSMSMode'] = options['bulkSMSMode']
@@ -160,6 +160,28 @@ class Sms
160
160
  end
161
161
  end
162
162
 
163
+ def deleteSubcription options
164
+ post_body = {
165
+ 'username' => @username,
166
+ 'phoneNumber' => options['phoneNumber'],
167
+ 'shortCode' => options['shortCode'],
168
+ 'keyword' => options['keyword']
169
+ }
170
+ if options['checkoutToken'] != nil
171
+ post_body['checkoutToken'] = options['checkoutToken']
172
+ end
173
+ url = getSmsSubscriptionUrl() + "/delete"
174
+ if validateParamsPresence?(options, ['shortCode', 'keyword', 'phoneNumber'])
175
+ response = sendNormalRequest(url, post_body)
176
+ end
177
+ if(@response_code == HTTP_CREATED)
178
+ r = JSON.parse(response, :quirky_mode => true)
179
+ return DeleteSubscriptionResponse.new r['status'], r['description']
180
+ else
181
+ raise AfricasTalkingException, response
182
+ end
183
+ end
184
+
163
185
  private
164
186
 
165
187
  def getSmsUrl()
@@ -218,6 +240,14 @@ class CreateSubscriptionResponse
218
240
  end
219
241
  end
220
242
 
243
+ class DeleteSubscriptionResponse
244
+ attr_reader :status, :description
245
+ def initialize status_, description_
246
+ @description = description_
247
+ @status = status_
248
+ end
249
+ end
250
+
221
251
 
222
252
  class SendPremiumMessagesResponse
223
253
  attr_reader :recipients, :overview
@@ -1,3 +1,3 @@
1
1
  module AfricasTalking
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: africastalking-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Mwirigi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-02 00:00:00.000000000 Z
11
+ date: 2018-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler