rave_ruby 0.1.1
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 +7 -0
- data/.gitignore +23 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +1743 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rave_ruby/error.rb +48 -0
- data/lib/rave_ruby/rave_modules/base_endpoints.rb +21 -0
- data/lib/rave_ruby/rave_modules/util.rb +46 -0
- data/lib/rave_ruby/rave_objects/account.rb +68 -0
- data/lib/rave_ruby/rave_objects/base/base.rb +106 -0
- data/lib/rave_ruby/rave_objects/base/charge_base.rb +154 -0
- data/lib/rave_ruby/rave_objects/base/mobile_money_base.rb +44 -0
- data/lib/rave_ruby/rave_objects/base/mpesa_base.rb +41 -0
- data/lib/rave_ruby/rave_objects/base/payment_plan_base.rb +86 -0
- data/lib/rave_ruby/rave_objects/base/preauth_base.rb +84 -0
- data/lib/rave_ruby/rave_objects/base/sub_account_base.rb +34 -0
- data/lib/rave_ruby/rave_objects/base/subscription_base.rb +78 -0
- data/lib/rave_ruby/rave_objects/base/transfer_base.rb +80 -0
- data/lib/rave_ruby/rave_objects/base/ussd_base.rb +60 -0
- data/lib/rave_ruby/rave_objects/card.rb +91 -0
- data/lib/rave_ruby/rave_objects/list_banks.rb +18 -0
- data/lib/rave_ruby/rave_objects/mobile_money.rb +58 -0
- data/lib/rave_ruby/rave_objects/mpesa.rb +59 -0
- data/lib/rave_ruby/rave_objects/payment_plan.rb +61 -0
- data/lib/rave_ruby/rave_objects/preauth.rb +111 -0
- data/lib/rave_ruby/rave_objects/sub_account.rb +55 -0
- data/lib/rave_ruby/rave_objects/subscription.rb +51 -0
- data/lib/rave_ruby/rave_objects/transactions.rb +24 -0
- data/lib/rave_ruby/rave_objects/transfer.rb +79 -0
- data/lib/rave_ruby/rave_objects/uganda_mobile_money.rb +58 -0
- data/lib/rave_ruby/rave_objects/ussd.rb +59 -0
- data/lib/rave_ruby/version.rb +3 -0
- data/lib/rave_ruby.rb +74 -0
- data/rave_ruby.gemspec +46 -0
- metadata +144 -0
data/README.md
ADDED
@@ -0,0 +1,1743 @@
|
|
1
|
+
# RaveRuby
|
2
|
+
|
3
|
+
[](https://travis-ci.org/MaestroJolly/rave-ruby) [](https://badge.fury.io/rb/rave_ruby)
|
4
|
+
|
5
|
+
This is a ruby gem for easy integration of Rave API for various applications written in ruby language from [Rave](https://rave.flutterwave.com) by [Flutterwave.](https://developer.flutterwave.com/reference)
|
6
|
+
|
7
|
+
## Documentation
|
8
|
+
|
9
|
+
See [Here](https://developer.flutterwave.com/reference) for Rave API Docs.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'rave_ruby'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install rave_ruby
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
### Initialization
|
30
|
+
|
31
|
+
#### Instantiate rave object in sandbox with environment variable:
|
32
|
+
|
33
|
+
To use [Rave](https://ravesandbox.flutterwave.com), you need to instantiate the RaveRuby class with your [API](https://ravesandbox.flutterwave.com/dashboard/settings/apis) keys which are your public and secret keys. We recommend that you store your API keys in your environment variable named `RAVE_PUBLIC_KEY` and `RAVE_SECRET_KEY`. Instantiating your rave object after adding your API keys in your environment is as illustrated below:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
rave = RaveRuby.new
|
37
|
+
```
|
38
|
+
This throws a `RaveBadKeyError` if no key is found in the environment variable or invalid public or secret key is found.
|
39
|
+
|
40
|
+
#### Instantiate rave object in sandbox without environment variable:
|
41
|
+
|
42
|
+
You can instantiate your rave object by setting your public and secret keys by passing them as an argument of the `RaveRuby` class just as displayed below:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
rave = RaveRuby.new("YOUR_RAVE_SANDBOX_PUBLIC_KEY", "YOUR_RAVE_SANDBOX_SECRET_KEY")
|
46
|
+
```
|
47
|
+
|
48
|
+
#### `NOTE:` It is best practice to always set your API keys to your environment variable for security purpose. Please be warned not use this package without setting your API keys in your environment variables in production.
|
49
|
+
|
50
|
+
#### To instantiate rave object in production with environment variable:
|
51
|
+
|
52
|
+
Simply use it as displayed below:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
rave = RaveRuby.new("YOUR_RAVE_LIVE_PUBLIC_KEY", "YOUR_RAVE_LIVE_SECRET_KEY", true)
|
56
|
+
```
|
57
|
+
|
58
|
+
## Rave Objects
|
59
|
+
|
60
|
+
- [Account.new(rave)](#accountnewrave)
|
61
|
+
- [Card.new(rave)](#cardnewrave)
|
62
|
+
- [Preauth.new(rave)](#preauthnewrave)
|
63
|
+
- [MobileMoney.new(rave)](#mobilemoneynewrave)
|
64
|
+
- [Mpesa.new(rave)](#mpesanewrave)
|
65
|
+
- [SubAccount.new(rave)](#subaccountnewrave)
|
66
|
+
- [PaymentPlan.new(rave)](#paymentplannewrave)
|
67
|
+
- [Subscription.new(rave)](#subscriptionnewrave)
|
68
|
+
- [Transfer.new(rave)](#transfernewrave)
|
69
|
+
- [UgandaMobileMoney.new(rave)](#ugandamobilemoneynewrave)
|
70
|
+
- [Ussd.new(rave)](#ussdnewrave)
|
71
|
+
- [ListBanks.new(rave)](#listbanksnewrave)
|
72
|
+
|
73
|
+
## `Account.new(rave)`
|
74
|
+
|
75
|
+
To perform account transactions, instantiate the account object and pass rave object as its argument.
|
76
|
+
|
77
|
+
Its functions includes:
|
78
|
+
|
79
|
+
- `.initiate_charge`
|
80
|
+
- `.validate_charge`
|
81
|
+
- `.verify_charge`
|
82
|
+
|
83
|
+
### `.initiate_charge(payload)`
|
84
|
+
|
85
|
+
This function is called to initiate account transaction. The payload should be a ruby hash with account details. Its parameters should include the following:
|
86
|
+
|
87
|
+
- `accountbank`,
|
88
|
+
|
89
|
+
- `accountnumber`,
|
90
|
+
|
91
|
+
- `amount`,
|
92
|
+
|
93
|
+
- `email`,
|
94
|
+
|
95
|
+
- `phonenumber`,
|
96
|
+
|
97
|
+
- `IP`
|
98
|
+
|
99
|
+
You can also add your custom transaction reference `(txRef)`, if not, one would be automatically generated for you in which we used the ruby `securerandom` module for generating this in the `Util` module.
|
100
|
+
|
101
|
+
#### Sample account charge call:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
response = charge_account.initiate_charge(payload)
|
105
|
+
```
|
106
|
+
#### which returns:
|
107
|
+
|
108
|
+
It returns this response in ruby hash. A sample response:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
{
|
112
|
+
"error"=>false, "status"=>"success", "validation_required"=>true, "message"=>"V-COMP", "suggested_auth"=>nil, "txRef"=>"MC-2232eed54ca72f8ae2125f49020fb592", "flwRef"=>"ACHG-1544908923260", "chargeResponseCode"=>"02", "chargeResponseMessage"=>"Pending OTP validation", "amount"=>100, "currency"=>"NGN", "validateInstruction"=>"Please dial *901*4*1# to get your OTP. Enter the OTP gotten in the field below", "paymentType"=>"account", "authModelUsed"=>"AUTH", "authurl"=>"NO-URL"
|
113
|
+
}
|
114
|
+
|
115
|
+
```
|
116
|
+
A `RaveServerError` is raised if there's an error with the charge.
|
117
|
+
|
118
|
+
#### Sample error response if an exception is raised:
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
{
|
122
|
+
"status":"error","message":"Sorry that account number is invalid. Please check and try again","data":{"code":"FLW_ERR","message":"Sorry that account number is invalid. Please check and try again","err_tx":{"id":360210,"flwRef":"ACHG-1544910130710","chargeResponseCode":"RR","chargeResponseMessage":"Sorry that account number is invalid. Please check and try again","status":"failed","merchantbearsfee":1,"appfee":"1.4","merchantfee":"0","charged_amount":"100.00"
|
123
|
+
}}}
|
124
|
+
|
125
|
+
```
|
126
|
+
|
127
|
+
### `.validate_charge(flwRef, "OTP")`
|
128
|
+
|
129
|
+
After a successful charge, most times you will be asked to verify with OTP. To check if this is required, check the validation_required key in the response of the charge call i.e `response["validation_required"]` is equal to `true`.
|
130
|
+
|
131
|
+
In the case that an `authUrl` is returned from your charge call, you may skip the validation step and simply pass your authurl to the end-user as displayed below:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
authurl = response['authurl']
|
135
|
+
```
|
136
|
+
|
137
|
+
If validation is required by OTP, you need to pass the `flwRef` from the response of the charge call as well as the OTP.
|
138
|
+
|
139
|
+
#### Sample validate_charge call is:
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
response = charge_account.validate_charge(response["flwRef"], "12345")
|
143
|
+
```
|
144
|
+
|
145
|
+
#### which returns:
|
146
|
+
|
147
|
+
It returns this response in ruby hash with the `txRef` and `flwRef` amongst its successful response:
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
{
|
151
|
+
"error"=>false, "status"=>"success", "message"=>"Charge Complete", "txRef"=>"MC-c0c707a798de82f34b937e6126844d6c", "flwRef"=>"ACHG-1544963949493", "amount"=>100, "currency"=>"NGN", "chargeResponseCode"=>"00", "chargeResponseMessage"=>"Pending OTP validation"
|
152
|
+
}
|
153
|
+
```
|
154
|
+
|
155
|
+
If an error occurs during OTP validation, you will receive a response similiar to this:
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
{
|
159
|
+
"error"=>true, "status"=>"success", "message"=>"Charge Complete", "txRef"=>"MC-4cd9b2e4a9a104f92273ce194993ab50", "flwRef"=>"ACHG-1544969082006", "amount"=>100, "currency"=>"NGN", "chargeResponseCode"=>"02", "chargeResponseMessage"=>"Pending OTP validation"
|
160
|
+
}
|
161
|
+
```
|
162
|
+
With `chargeResponseCode` still equals to `02` which means it didn't validate successfully and is till pending validation.
|
163
|
+
|
164
|
+
Otherwise if validation is successful using OTP, you will receive a response similar to this:
|
165
|
+
|
166
|
+
```ruby
|
167
|
+
{
|
168
|
+
"error"=>false, "status"=>"success", "message"=>"Charge Complete", "txRef"=>"MC-c0c707a798de82f34b937e6126844d6c", "flwRef"=>"ACHG-1544963949493", "amount"=>100, "currency"=>"NGN", "chargeResponseCode"=>"00", "chargeResponseMessage"=>"Pending OTP validation"
|
169
|
+
}
|
170
|
+
```
|
171
|
+
|
172
|
+
With `chargeResponseCode` equals to `00` which means it validated successfully.
|
173
|
+
|
174
|
+
### `.verify_charge(txRef)`
|
175
|
+
|
176
|
+
You can call the `verify_charge` function to check if your transaction was completed successfully. To do this, you have to pass the transaction reference generated at the point of making your charge call. This is the txRef in the response parameter returned in any of the `initiate_charge` or `validate_charge` call.
|
177
|
+
|
178
|
+
#### Sample verify_charge call:
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
response = charge_account.verify_charge(response["txRef"])
|
182
|
+
```
|
183
|
+
|
184
|
+
#### which returns:
|
185
|
+
|
186
|
+
It returns this response in ruby hash with the `txRef`, `flwRef` and `transaction_complete` which indicates the transaction is successfully completed.
|
187
|
+
|
188
|
+
Full sample response returned if a transaction is successfully verified:
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
{
|
192
|
+
"error"=>false, "transaction_complete"=>true, "data"=>{"txid"=>360744, "txref"=>"MC-c0c707a798de82f34b937e6126844d6c", "flwref"=>"ACHG-1544963949493", "devicefingerprint"=>"69e6b7f0b72037aa8428b70fbe03986c", "cycle"=>"one-time", "amount"=>100, "currency"=>"NGN", "chargedamount"=>100, "appfee"=>1.4, "merchantfee"=>0, "merchantbearsfee"=>1, "chargecode"=>"00", "chargemessage"=>"Pending OTP validation", "authmodel"=>"AUTH", "ip"=>"::ffff:10.11.193.41", "narration"=>"Simply Recharge", "status"=>"successful",
|
193
|
+
"vbvcode"=>"N/A", "vbvmessage"=>"N/A", "authurl"=>"NO-URL", "acctcode"=>"00", "acctmessage"=>"Approved Or Completed Successfully", "paymenttype"=>"account", "paymentid"=>"90", "fraudstatus"=>"ok", "chargetype"=>"normal", "createdday"=>0, "createddayname"=>"SUNDAY", "createdweek"=>50, "createdmonth"=>11, "createdmonthname"=>"DECEMBER", "createdquarter"=>4, "createdyear"=>2018, "createdyearisleap"=>false, "createddayispublicholiday"=>0, "createdhour"=>12, "createdminute"=>39, "createdpmam"=>"pm", "created"=>"2018-12-16T12:39:08.000Z", "customerid"=>64794, "custphone"=>"08134836828", "custnetworkprovider"=>"MTN", "custname"=>"ifunanya Ikemma", "custemail"=>"mijux@xcodes.net", "custemailprovider"=>"COMPANY EMAIL", "custcreated"=>"2018-11-26T11:35:24.000Z", "accountid"=>6076, "acctbusinessname"=>"Simply Recharge", "acctcontactperson"=>"Jolaoso Yusuf", "acctcountry"=>"NG", "acctbearsfeeattransactiontime"=>1, "acctparent"=>1, "acctvpcmerchant"=>"N/A", "acctalias"=>nil, "acctisliveapproved"=>0, "orderref"=>"URF_1544963948269_113435", "paymentplan"=>nil, "paymentpage"=>nil, "raveref"=>"RV31544963947776E1DB61E313", "amountsettledforthistransaction"=>98.6, "account"=>{"id"=>90, "account_number"=>"0690000033", "account_bank"=>"044", "first_name"=>"NO-NAME", "last_name"=>"NO-LNAME", "account_is_blacklisted"=>0, "createdAt"=>"2017-04-26T12:54:22.000Z", "updatedAt"=>"2018-12-16T12:39:23.000Z", "deletedAt"=>nil, "account_token"=>{"token"=>"flw-t03a483b4eecf61cda-k3n-mock"}}, "meta"=>[]}
|
194
|
+
}
|
195
|
+
|
196
|
+
```
|
197
|
+
|
198
|
+
If a transaction couldn't be verified successfully, `error` and `transaction_complete` would both come as `false`.
|
199
|
+
|
200
|
+
#### Full Account Transaction Flow:
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
require 'rave_ruby'
|
204
|
+
|
205
|
+
# This is a rave object which is expecting public and secret keys
|
206
|
+
|
207
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
208
|
+
|
209
|
+
|
210
|
+
# This is used to perform card charge
|
211
|
+
|
212
|
+
payload = {
|
213
|
+
"accountbank" => "044",
|
214
|
+
"accountnumber" => "0690000033",
|
215
|
+
"currency" => "NGN",
|
216
|
+
"payment_type" => "account",
|
217
|
+
"country" => "NG",
|
218
|
+
"amount" => "100",
|
219
|
+
"email" => "mijux@xcodes.net",
|
220
|
+
"phonenumber" => "08134836828",
|
221
|
+
"firstname" => "Maestro",
|
222
|
+
"lastname" => "Jolly",
|
223
|
+
"IP" => "355426087298442",
|
224
|
+
"redirect_url" => "https://rave-webhook.herokuapp.com/receivepayment",
|
225
|
+
"device_fingerprint" => "69e6b7f0b72037aa8428b70fbe03986c"
|
226
|
+
}
|
227
|
+
|
228
|
+
charge_account = Account.new(rave)
|
229
|
+
|
230
|
+
response = charge_account.initiate_charge(payload)
|
231
|
+
print response
|
232
|
+
|
233
|
+
# perform validation if it is required
|
234
|
+
|
235
|
+
if response["validation_required"]
|
236
|
+
response = charge_account.validate_charge(response["flwRef"], "12345")
|
237
|
+
print response
|
238
|
+
end
|
239
|
+
|
240
|
+
# verify charge
|
241
|
+
|
242
|
+
response = charge_account.verify_charge(response["txRef"])
|
243
|
+
print response
|
244
|
+
```
|
245
|
+
|
246
|
+
## `Card.new(rave)`
|
247
|
+
|
248
|
+
To perform card transactions, instantiate the card object and pass rave object as its argument.
|
249
|
+
|
250
|
+
Its functions includes:
|
251
|
+
|
252
|
+
- `.initiate_charge`
|
253
|
+
- `.get_auth_type`
|
254
|
+
- `.update_payload`
|
255
|
+
- `.tokenized_charge`
|
256
|
+
- `.validate_charge`
|
257
|
+
- `.verify_charge`
|
258
|
+
|
259
|
+
### `.initiate_charge(payload)`
|
260
|
+
|
261
|
+
This function is called to initiate card transaction. The payload should be a ruby hash with card details. Its parameters should include the following:
|
262
|
+
|
263
|
+
- `cardno`,
|
264
|
+
|
265
|
+
- `cvv`,
|
266
|
+
|
267
|
+
- `expirymonth`,
|
268
|
+
|
269
|
+
- `expiryyear`,
|
270
|
+
|
271
|
+
- `amount`,
|
272
|
+
|
273
|
+
- `email`,
|
274
|
+
|
275
|
+
- `phonenumber`,
|
276
|
+
|
277
|
+
- `firstname`,
|
278
|
+
|
279
|
+
- `lastname`,
|
280
|
+
|
281
|
+
- `IP`
|
282
|
+
|
283
|
+
You can also add your custom transaction reference `(txRef)`, if not, one would be automatically generated for you in which we used the ruby `securerandom` module for generating this in the `Util` module.
|
284
|
+
|
285
|
+
#### Sample card charge call:
|
286
|
+
|
287
|
+
```ruby
|
288
|
+
response = charge_card.initiate_charge(payload)
|
289
|
+
```
|
290
|
+
You need to make this initial charge call to get the suggested_auth for the transaction.
|
291
|
+
|
292
|
+
#### which returns:
|
293
|
+
|
294
|
+
It returns this response in ruby hash. A sample response:
|
295
|
+
|
296
|
+
```ruby
|
297
|
+
{
|
298
|
+
"error"=>false, "status"=>"success", "validation_required"=>true, "message"=>"AUTH_SUGGESTION", "suggested_auth"=>"PIN", "txRef"=>nil, "flwRef"=>nil, "chargeResponseCode"=>nil, "chargeResponseMessage"=>nil, "amount"=>nil, "currency"=>nil, "validateInstruction"=>nil, "paymentType"=>nil, "authModelUsed"=>nil, "authurl"=>nil
|
299
|
+
}
|
300
|
+
|
301
|
+
```
|
302
|
+
|
303
|
+
A `RaveServerError` is raised if there's an error with the card charge.
|
304
|
+
|
305
|
+
#### Sample error response if an exception is raised:
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
{
|
309
|
+
"status":"error","message":"Card number is invalid","data":{"code":"ERR","message":"Card number is invalid"
|
310
|
+
}
|
311
|
+
}
|
312
|
+
|
313
|
+
```
|
314
|
+
|
315
|
+
### `.update_payload(suggested_auth, payload, pin or address)`
|
316
|
+
|
317
|
+
You need to update the payload with `pin` or `address` parameters depending on the `suggested_auth` returned from the initial charge call i.e `suggested_auth = response["suggested_auth"]` and passing it as a parameter of the `.get_auth_type(suggested_auth)` method.
|
318
|
+
|
319
|
+
If the `suggested_auth` returned is `pin`, update the payload with this method `charge_card.update_payload(suggested_auth, payload, pin: "CUSTOMER CARD PIN")`.
|
320
|
+
|
321
|
+
If the `suggested_auth` returned is `address`, update the payload with this method `charge_card.update_payload(suggested_auth, payload, address:{"A RUBY HASH OF CUSTOMER'S BILLING ADDRESS"})`.
|
322
|
+
|
323
|
+
This is what the ruby hash billing address consists:
|
324
|
+
|
325
|
+
- `billingzip`,
|
326
|
+
|
327
|
+
- `billingcity`,
|
328
|
+
|
329
|
+
- `billingaddress`,
|
330
|
+
|
331
|
+
- `billingstate`,
|
332
|
+
|
333
|
+
- `billingcountry`
|
334
|
+
|
335
|
+
After updating the payload, you will need to make the `.initiate_charge` call again with the updated payload, as displayed below:
|
336
|
+
|
337
|
+
```ruby
|
338
|
+
response = charge_card.initiate_charge(updated_payload)
|
339
|
+
|
340
|
+
```
|
341
|
+
|
342
|
+
This is a sample response returned after updating payload with suggested_auth `pin`:
|
343
|
+
|
344
|
+
```ruby
|
345
|
+
{
|
346
|
+
"error"=>false, "status"=>"success", "validation_required"=>true, "message"=>"V-COMP", "suggested_auth"=>nil, "txRef"=>"MC-d8c02b9bdf21d02aa7ab276cda3177ae", "flwRef"=>"FLW-MOCK-68d8095eab1abdb69805be0a55d84630", "chargeResponseCode"=>"02", "chargeResponseMessage"=>"Please enter the OTP sent to your mobile number 080****** and email te**@rave**.com", "amount"=>10, "currency"=>"NGN", "validateInstruction"=>nil, "paymentType"=>"card", "authModelUsed"=>"PIN", "authurl"=>"N/A"
|
347
|
+
}
|
348
|
+
```
|
349
|
+
|
350
|
+
### `.validate_charge(flwRef, "OTP")`
|
351
|
+
|
352
|
+
After a successful charge, most times you will be asked to verify with OTP. To check if this is required, check the validation_required key in the response of the charge call i.e `response["validation_required"]` is equal to `true`.
|
353
|
+
|
354
|
+
In the case that an `authUrl` is returned from your charge call, you may skip the validation step and simply pass your authurl to the end-user as displayed below:
|
355
|
+
|
356
|
+
```ruby
|
357
|
+
authurl = response['authurl']
|
358
|
+
```
|
359
|
+
|
360
|
+
If validation is required by OTP, you need to pass the `flwRef` from the response of the charge call as well as the OTP.
|
361
|
+
|
362
|
+
A sample validate_charge call is:
|
363
|
+
|
364
|
+
```ruby
|
365
|
+
response = charge_card.validate_charge(response["flwRef"], "12345")
|
366
|
+
```
|
367
|
+
|
368
|
+
#### which returns:
|
369
|
+
|
370
|
+
It returns this response in ruby hash with the `txRef` and `flwRef` amongst its successful response:
|
371
|
+
|
372
|
+
```ruby
|
373
|
+
{
|
374
|
+
"error"=>false, "status"=>"success", "message"=>"Charge Complete", "txRef"=>"MC-d8c02b9bdf21d02aa7ab276cda3177ae", "flwRef"=>"FLW-MOCK-68d8095eab1abdb69805be0a55d84630", "amount"=>10, "currency"=>"NGN", "chargeResponseCode"=>"00", "chargeResponseMessage"=>"Please enter the OTP sent to your mobile number 080****** and email te**@rave**.com"
|
375
|
+
}
|
376
|
+
```
|
377
|
+
|
378
|
+
If an error occurs during OTP validation, you will receive a response similiar to this:
|
379
|
+
|
380
|
+
```ruby
|
381
|
+
{
|
382
|
+
"error"=>true, "status"=>"success", "message"=>"Charge Complete", "txRef"=>"MC-155418209b1cf2812da3ceb57e541ef0", "flwRef"=>"FLW-MOCK-35167122c73ccdd8ee796b71042af101", "amount"=>100, "currency"=>"NGN", "chargeResponseCode"=>"02", "chargeResponseMessage"=>"Pending OTP validation"
|
383
|
+
}
|
384
|
+
```
|
385
|
+
With `chargeResponseCode` still equals to `02` which means it didn't validate successfully and is till pending validation.
|
386
|
+
|
387
|
+
Otherwise if validation is successful using OTP, you will receive a response similar to this:
|
388
|
+
|
389
|
+
```ruby
|
390
|
+
{
|
391
|
+
"error"=>false, "status"=>"success", "message"=>"Charge Complete", "txRef"=>"MC-eac8888322fa44343d1a3ed7c8025fde", "flwRef"=>"FLW-MOCK-01cb1be7b183cfdec0d5225316647378", "amount"=>10, "currency"=>"NGN", "chargeResponseCode"=>"00", "chargeResponseMessage"=>"Please enter the OTP sent to your mobile number 080****** and email te**@rave**.com"
|
392
|
+
}
|
393
|
+
```
|
394
|
+
With `chargeResponseCode` equals to `00` which means it validated successfully.
|
395
|
+
|
396
|
+
### `.verify_charge(txRef)`
|
397
|
+
|
398
|
+
You can call the `verify_charge` function to check if your transaction was completed successfully. To do this, you have to pass the transaction reference generated at the point of making your charge call. This is the txRef in the response parameter returned in any of the `initiate_charge` or `validate_charge` call.
|
399
|
+
|
400
|
+
#### Sample verify_charge call:
|
401
|
+
|
402
|
+
```ruby
|
403
|
+
response = charge_card.verify_charge(response["txRef"])
|
404
|
+
```
|
405
|
+
|
406
|
+
#### which returns:
|
407
|
+
|
408
|
+
It returns this response in ruby hash with the `txRef`, `flwRef` and `transaction_complete` which indicates the transaction is successfully completed.
|
409
|
+
|
410
|
+
Full sample response returned if a transaction is successfully verified:
|
411
|
+
|
412
|
+
```ruby
|
413
|
+
{
|
414
|
+
"error"=>false, "transaction_complete"=>true, "data"=>{"txid"=>362093, "txref"=>"MC-eac8888322fa44343d1a3ed7c8025fde", "flwref"=>"FLW-MOCK-01cb1be7b183cfdec0d5225316647378", "devicefingerprint"=>"69e6b7f0b72037aa8428b70fbe03986c", "cycle"=>"one-time", "amount"=>10, "currency"=>"NGN", "chargedamount"=>10, "appfee"=>0.14, "merchantfee"=>0, "merchantbearsfee"=>1, "chargecode"=>"00", "chargemessage"=>"Please enter the OTP sent to your mobile number 080****** and email te**@rave**.com", "authmodel"=>"PIN", "ip"=>"::ffff:10.69.80.227", "narration"=>"CARD Transaction ", "status"=>"successful", "vbvcode"=>"00", "vbvmessage"=>"successful", "authurl"=>"N/A", "acctcode"=>nil, "acctmessage"=>nil, "paymenttype"=>"card", "paymentid"=>"861", "fraudstatus"=>"ok", "chargetype"=>"normal", "createdday"=>1, "createddayname"=>"MONDAY", "createdweek"=>51, "createdmonth"=>11, "createdmonthname"=>"DECEMBER", "createdquarter"=>4, "createdyear"=>2018, "createdyearisleap"=>false, "createddayispublicholiday"=>0, "createdhour"=>17, "createdminute"=>4, "createdpmam"=>"pm", "created"=>"2018-12-17T17:04:45.000Z", "customerid"=>51655, "custphone"=>"0902620185", "custnetworkprovider"=>"AIRTEL", "custname"=>"temi desola", "custemail"=>"user@gmail.com", "custemailprovider"=>"GMAIL", "custcreated"=>"2018-09-24T07:59:14.000Z", "accountid"=>6076, "acctbusinessname"=>"Simply Recharge", "acctcontactperson"=>"Jolaoso Yusuf", "acctcountry"=>"NG", "acctbearsfeeattransactiontime"=>1, "acctparent"=>1, "acctvpcmerchant"=>"N/A", "acctalias"=>nil, "acctisliveapproved"=>0, "orderref"=>"URF_1545066285779_8747935", "paymentplan"=>nil, "paymentpage"=>nil, "raveref"=>"RV3154506628468675C4CD519A", "amountsettledforthistransaction"=>9.86, "card"=>{"expirymonth"=>"09", "expiryyear"=>"19", "cardBIN"=>"543889", "last4digits"=>"0229", "brand"=>"MASHREQ BANK CREDITSTANDARD", "card_tokens"=>[{"embedtoken"=>"flw-t1nf-75aa4a20695a54c1846e0e8bcae754ee-m03k", "shortcode"=>"671c0", "expiry"=>"9999999999999"}], "type"=>"MASTERCARD", "life_time_token"=>"flw-t1nf-75aa4a20695a54c1846e0e8bcae754ee-m03k"}, "meta"=>[{"id"=>1257583, "metaname"=>"flightID", "metavalue"=>"123949494DC", "createdAt"=>"2018-12-17T17:04:46.000Z", "updatedAt"=>"2018-12-17T17:04:46.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>362093}]}
|
415
|
+
}
|
416
|
+
```
|
417
|
+
|
418
|
+
`NOTE:` You can tokenize a card after charging the card for the first time for subsequent transactions done with the card without having to send the card details everytime a transaction is done. The card token can be gotten from the `.verify_charge` response, here's how to get the card token from our sample verify response:
|
419
|
+
|
420
|
+
`response['card']['card_tokens']['embed_tokens']` which is similar to this: `flw-t1nf-75aa4a20695a54c1846e0e8bcae754ee-m03k`
|
421
|
+
|
422
|
+
### `.tokenized_charge(payload)`
|
423
|
+
|
424
|
+
This function is called to perform a charge a tokenized card. Its payload includes;
|
425
|
+
|
426
|
+
- `token`,
|
427
|
+
|
428
|
+
- `country`,
|
429
|
+
|
430
|
+
- `amount`,
|
431
|
+
|
432
|
+
- `email`,
|
433
|
+
|
434
|
+
- `firstname`,
|
435
|
+
|
436
|
+
- `lastname`,
|
437
|
+
|
438
|
+
- `txRef`,
|
439
|
+
|
440
|
+
- `currency`
|
441
|
+
|
442
|
+
#### Sample tokenized charge call:
|
443
|
+
|
444
|
+
```ruby
|
445
|
+
response = charge_card.tokenized_charge(payload)
|
446
|
+
```
|
447
|
+
|
448
|
+
#### which returns:
|
449
|
+
|
450
|
+
It returns this response in ruby hash. A sample response:
|
451
|
+
|
452
|
+
```ruby
|
453
|
+
{
|
454
|
+
"error"=>false, "status"=>"success", "validation_required"=>false, "message"=>"Charge success", "suggested_auth"=>nil, "txRef"=>"MC-f1085c1793bfaf171e667a21be6ec121", "flwRef"=>"FLW-M03K-218f54e6a06dc7da152f115c561f32d2", "chargeResponseCode"=>"00", "chargeResponseMessage"=>"Approved", "amount"=>10, "currency"=>"NGN", "validateInstruction"=>nil, "paymentType"=>"card", "authModelUsed"=>"noauth", "authurl"=>"N/A"
|
455
|
+
}
|
456
|
+
|
457
|
+
```
|
458
|
+
You can now verify the transaction by calling the `.verify_charge` function to verify the transaction and get the full response of the transaction.
|
459
|
+
|
460
|
+
#### Sample verify_charge call:
|
461
|
+
|
462
|
+
```ruby
|
463
|
+
response = charge_card.verify_charge(response["txRef"])
|
464
|
+
```
|
465
|
+
|
466
|
+
#### which returns:
|
467
|
+
|
468
|
+
It returns this response in ruby hash with the `txRef`, `flwRef` and `transaction_complete` which indicates the transaction is successfully completed.
|
469
|
+
|
470
|
+
Full sample response returned if a transaction is successfully verified:
|
471
|
+
|
472
|
+
```ruby
|
473
|
+
{
|
474
|
+
"error"=>false, "transaction_complete"=>true, "data"=>{"txid"=>390050, "txref"=>"MC-f1085c1793bfaf171e667a21be6ec121", "flwref"=>"FLW-M03K-218f54e6a06dc7da152f115c561f32d2", "devicefingerprint"=>"N/A", "cycle"=>"one-time", "amount"=>10, "currency"=>"NGN", "chargedamount"=>10, "appfee"=>0.14, "merchantfee"=>0, "merchantbearsfee"=>1, "chargecode"=>"00", "chargemessage"=>"Approved", "authmodel"=>"noauth", "ip"=>"355426087298442", "narration"=>"Simply Recharge", "status"=>"successful", "vbvcode"=>"00", "vbvmessage"=>"Approved", "authurl"=>"N/A", "acctcode"=>nil, "acctmessage"=>nil, "paymenttype"=>"card", "paymentid"=>"861", "fraudstatus"=>"ok", "chargetype"=>"normal", "createdday"=>1, "createddayname"=>"MONDAY", "createdweek"=>3, "createdmonth"=>0, "createdmonthname"=>"JANUARY", "createdquarter"=>1, "createdyear"=>2019, "createdyearisleap"=>false, "createddayispublicholiday"=>0, "createdhour"=>12, "createdminute"=>57, "createdpmam"=>"pm", "created"=>"2019-01-14T12:57:33.000Z", "customerid"=>51655, "custphone"=>"0902620185", "custnetworkprovider"=>"AIRTEL", "custname"=>"temi desola", "custemail"=>"user@gmail.com", "custemailprovider"=>"GMAIL", "custcreated"=>"2018-09-24T07:59:14.000Z", "accountid"=>6076, "acctbusinessname"=>"Simply Recharge", "acctcontactperson"=>"Jolaoso Yusuf", "acctcountry"=>"NG", "acctbearsfeeattransactiontime"=>1, "acctparent"=>1, "acctvpcmerchant"=>"N/A", "acctalias"=>nil, "acctisliveapproved"=>0, "orderref"=>"URF_86BFB6FF6B6BB6CD6C9E", "paymentplan"=>nil, "paymentpage"=>nil, "raveref"=>nil, "amountsettledforthistransaction"=>9.86, "card"=>{"expirymonth"=>"09", "expiryyear"=>"19", "cardBIN"=>"543889", "last4digits"=>"0229", "brand"=>"MASHREQ BANK CREDITSTANDARD", "card_tokens"=>[{"embedtoken"=>"flw-t1nf-75aa4a20695a54c1846e0e8bcae754ee-m03k", "shortcode"=>"671c0", "expiry"=>"9999999999999"}], "type"=>"MASTERCARD", "life_time_token"=>"flw-t1nf-75aa4a20695a54c1846e0e8bcae754ee-m03k"}, "meta"=>[{"id"=>1263976, "metaname"=>"flightID", "metavalue"=>"123949494DC", "createdAt"=>"2019-01-14T12:57:33.000Z", "updatedAt"=>"2019-01-14T12:57:33.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>390050}]}
|
475
|
+
}
|
476
|
+
```
|
477
|
+
|
478
|
+
If a transaction couldn't be verified successfully, `error` and `transaction_complete` would both come as `false`.
|
479
|
+
|
480
|
+
#### Full Card Transaction Flow:
|
481
|
+
|
482
|
+
```ruby
|
483
|
+
|
484
|
+
require 'rave_ruby'
|
485
|
+
|
486
|
+
# This is a rave object which is expecting public and secret keys
|
487
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
488
|
+
|
489
|
+
# This is used to perform card charge
|
490
|
+
|
491
|
+
payload = {
|
492
|
+
"cardno" => "5438898014560229",
|
493
|
+
"cvv" => "890",
|
494
|
+
"expirymonth" => "09",
|
495
|
+
"expiryyear" => "19",
|
496
|
+
"currency" => "NGN",
|
497
|
+
"country" => "NG",
|
498
|
+
"amount" => "10",
|
499
|
+
"email" => "user@gmail.com",
|
500
|
+
"phonenumber" => "0902620185",
|
501
|
+
"firstname" => "temi",
|
502
|
+
"lastname" => "desola",
|
503
|
+
"IP" => "355426087298442",
|
504
|
+
"meta" => [{"metaname": "flightID", "metavalue": "123949494DC"}],
|
505
|
+
"redirect_url" => "https://rave-webhook.herokuapp.com/receivepayment",
|
506
|
+
"device_fingerprint" => "69e6b7f0b72037aa8428b70fbe03986c"
|
507
|
+
}
|
508
|
+
|
509
|
+
charge_card = Card.new(rave)
|
510
|
+
|
511
|
+
response = charge_card.initiate_charge(payload)
|
512
|
+
|
513
|
+
# update payload with suggested auth
|
514
|
+
if response["suggested_auth"]
|
515
|
+
suggested_auth = response["suggested_auth"]
|
516
|
+
auth_arg = charge_card.get_auth_type(suggested_auth)
|
517
|
+
if auth_arg == :pin
|
518
|
+
updated_payload = charge_card.update_payload(suggested_auth, payload, pin: "3310")
|
519
|
+
elsif auth_arg == :address
|
520
|
+
updated_payload = charge_card.update_payload(suggested_auth, payload, address:{"billingzip"=> "07205", "billingcity"=> "Hillside", "billingaddress"=> "470 Mundet PI", "billingstate"=> "NJ", "billingcountry"=> "US"})
|
521
|
+
end
|
522
|
+
|
523
|
+
# perform the second charge after payload is updated with suggested auth
|
524
|
+
response = charge_card.initiate_charge(updated_payload)
|
525
|
+
print response
|
526
|
+
|
527
|
+
# perform validation if it is required
|
528
|
+
if response["validation_required"]
|
529
|
+
response = charge_card.validate_charge(response["flwRef"], "12345")
|
530
|
+
print response
|
531
|
+
end
|
532
|
+
else
|
533
|
+
# You can handle the get the auth url from this response and load it for the customer to complete the transaction if an auth url is returned in the response.
|
534
|
+
print response
|
535
|
+
end
|
536
|
+
|
537
|
+
# verify charge
|
538
|
+
response = charge_card.verify_charge(response["txRef"])
|
539
|
+
print response
|
540
|
+
|
541
|
+
```
|
542
|
+
|
543
|
+
## `Preauth.new(rave)`
|
544
|
+
|
545
|
+
This is used to process a preauthorized card transaction.
|
546
|
+
|
547
|
+
Its functions includes:
|
548
|
+
|
549
|
+
- `.initiate_charge`
|
550
|
+
- `.capture`
|
551
|
+
- `.refund`
|
552
|
+
- `.void`
|
553
|
+
- `.verify_preauth`
|
554
|
+
|
555
|
+
The payload should be a ruby hash containing card information. It should have the following parameters:
|
556
|
+
|
557
|
+
- `token`,
|
558
|
+
|
559
|
+
- `country`,
|
560
|
+
|
561
|
+
- `amount`,
|
562
|
+
|
563
|
+
- `email`,
|
564
|
+
|
565
|
+
- `firstname`,
|
566
|
+
|
567
|
+
- `lastname`,
|
568
|
+
|
569
|
+
- `IP`,
|
570
|
+
|
571
|
+
- `txRef`,
|
572
|
+
|
573
|
+
- `currency`
|
574
|
+
|
575
|
+
`NOTE:` You need to use the same email used when charging the card for the first time to successfully charge the card.
|
576
|
+
|
577
|
+
You can also add your custom transaction reference `(txRef)`, if not, one would be automatically generated for you in which we used the ruby `securerandom` module for generating this in the `Util` module.
|
578
|
+
|
579
|
+
#### Sample preauth charge call:
|
580
|
+
|
581
|
+
```ruby
|
582
|
+
response = preauth.initiate_charge(payload)
|
583
|
+
```
|
584
|
+
#### which returns:
|
585
|
+
|
586
|
+
It returns this response in ruby hash. A sample response:
|
587
|
+
|
588
|
+
```ruby
|
589
|
+
{
|
590
|
+
"error"=>false, "status"=>"pending-capture", "message"=>"Charge success", "validation_required"=>false, "txRef"=>"MC-0df3e7e6cd58b226d4ba2a3d03dd200b", "flwRef"=>"FLW-PREAUTH-M03K-abdc01e69aa424b9e1ac44987ec21ec3", "amount"=>1000, "currency"=>"NGN", "paymentType"=>"card"
|
591
|
+
}
|
592
|
+
|
593
|
+
```
|
594
|
+
|
595
|
+
### `.capture(flwRef)`
|
596
|
+
|
597
|
+
The capture method is called after the preauth card has been charged. It takes in the `flwRef` from the charge response and call optionally take in amount less than the original amount authorised on the card as displayed below.
|
598
|
+
|
599
|
+
#### Sample capture call:
|
600
|
+
|
601
|
+
```ruby
|
602
|
+
response = preauth.capture(response["flwRef"], "30")
|
603
|
+
```
|
604
|
+
|
605
|
+
#### which returns:
|
606
|
+
|
607
|
+
It returns this response in ruby hash. A sample response:
|
608
|
+
|
609
|
+
```ruby
|
610
|
+
{
|
611
|
+
"error"=>false, "status"=>"successful", "message"=>"Capture complete", "validation_required"=>false, "txRef"=>"MC-0df3e7e6cd58b226d4ba2a3d03dd200b", "flwRef"=>"FLW-PREAUTH-M03K-abdc01e69aa424b9e1ac44987ec21ec3", "amount"=>30, "currency"=>"NGN", "chargeResponseCode"=>"00", "chargeResponseMessage"=>"Approved", "paymentType"=>"card"
|
612
|
+
}
|
613
|
+
|
614
|
+
```
|
615
|
+
|
616
|
+
### `.refund(flwRef)`
|
617
|
+
|
618
|
+
This is called to perform a `refund` of a preauth transaction.
|
619
|
+
|
620
|
+
#### Sample refund call:
|
621
|
+
|
622
|
+
```ruby
|
623
|
+
response = preauth.refund(response["flwRef"])
|
624
|
+
|
625
|
+
```
|
626
|
+
|
627
|
+
### `.void(flwRef)`
|
628
|
+
|
629
|
+
This is called to `void` a preauth transaction.
|
630
|
+
|
631
|
+
#### Sample void call:
|
632
|
+
|
633
|
+
```ruby
|
634
|
+
response = preauth.void(response["flwRef"])
|
635
|
+
|
636
|
+
```
|
637
|
+
|
638
|
+
### `.verify_preauth(txRef)`
|
639
|
+
|
640
|
+
The verify_preauth method can be called after capture is successfully completed by passing the `txRef` from the `charge` or `capture` response as its argument as shown below.
|
641
|
+
|
642
|
+
#### Sample verify_preauth call:
|
643
|
+
|
644
|
+
```ruby
|
645
|
+
response = preauth.verify_preauth(response["txRef"])
|
646
|
+
|
647
|
+
```
|
648
|
+
|
649
|
+
#### which returns:
|
650
|
+
|
651
|
+
It returns this response in ruby hash. A sample response:
|
652
|
+
|
653
|
+
```ruby
|
654
|
+
{
|
655
|
+
"error"=>false, "transaction_complete"=>true, "data"=>{"txid"=>370365, "txref"=>"MC-0df3e7e6cd58b226d4ba2a3d03dd200b", "flwref"=>"FLW-PREAUTH-M03K-abdc01e69aa424b9e1ac44987ec21ec3", "devicefingerprint"=>"N/A", "cycle"=>"one-time", "amount"=>30, "currency"=>"NGN", "chargedamount"=>30.42, "appfee"=>0.42, "merchantfee"=>0, "merchantbearsfee"=>0, "chargecode"=>"00", "chargemessage"=>"Approved", "authmodel"=>"noauth", "ip"=>"190.233.222.1", "narration"=>"TOKEN CHARGE", "status"=>"successful", "vbvcode"=>"00", "vbvmessage"=>"Approved", "authurl"=>"N/A", "acctcode"=>"FLWPREAUTH-M03K-CP-1545740097601", "acctmessage"=>"CAPTURE
|
656
|
+
REFERENCE", "paymenttype"=>"card", "paymentid"=>"861", "fraudstatus"=>"ok", "chargetype"=>"preauth", "createdday"=>2, "createddayname"=>"TUESDAY", "createdweek"=>52, "createdmonth"=>11, "createdmonthname"=>"DECEMBER", "createdquarter"=>4, "createdyear"=>2018, "createdyearisleap"=>false, "createddayispublicholiday"=>0, "createdhour"=>12, "createdminute"=>14, "createdpmam"=>"pm", "created"=>"2018-12-25T12:14:54.000Z", "customerid"=>51655, "custphone"=>"0902620185", "custnetworkprovider"=>"AIRTEL", "custname"=>"temi desola", "custemail"=>"user@gmail.com", "custemailprovider"=>"GMAIL", "custcreated"=>"2018-09-24T07:59:14.000Z", "accountid"=>6076, "acctbusinessname"=>"Simply Recharge", "acctcontactperson"=>"Jolaoso Yusuf", "acctcountry"=>"NG", "acctbearsfeeattransactiontime"=>1, "acctparent"=>1, "acctvpcmerchant"=>"N/A", "acctalias"=>nil, "acctisliveapproved"=>0, "orderref"=>nil, "paymentplan"=>nil, "paymentpage"=>nil, "raveref"=>nil, "amountsettledforthistransaction"=>30, "card"=>{"expirymonth"=>"09", "expiryyear"=>"19", "cardBIN"=>"543889", "last4digits"=>"0229", "brand"=>"MASHREQ BANK CREDITSTANDARD", "card_tokens"=>[{"embedtoken"=>"flw-t1nf-75aa4a20695a54c1846e0e8bcae754ee-m03k", "shortcode"=>"671c0", "expiry"=>"9999999999999"}], "type"=>"MASTERCARD", "life_time_token"=>"flw-t1nf-75aa4a20695a54c1846e0e8bcae754ee-m03k"}, "meta"=>[{"id"=>1259456, "metaname"=>"trxauthorizeid", "metavalue"=>"M03K-i0-8673be673b828e4b2863ef6d39d56cce", "createdAt"=>"2018-12-25T12:14:54.000Z", "updatedAt"=>"2018-12-25T12:14:54.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>370365}, {"id"=>1259457, "metaname"=>"trxreference", "metavalue"=>"FLW-PREAUTH-M03K-abdc01e69aa424b9e1ac44987ec21ec3", "createdAt"=>"2018-12-25T12:14:54.000Z", "updatedAt"=>"2018-12-25T12:14:54.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>370365}, {"id"=>1259458, "metaname"=>"old_amount", "metavalue"=>"1000", "createdAt"=>"2018-12-25T12:14:57.000Z", "updatedAt"=>"2018-12-25T12:14:57.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>370365}, {"id"=>1259459, "metaname"=>"old_charged_amount", "metavalue"=>"1000", "createdAt"=>"2018-12-25T12:14:57.000Z", "updatedAt"=>"2018-12-25T12:14:57.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>370365}, {"id"=>1259460, "metaname"=>"old_fee", "metavalue"=>"", "createdAt"=>"2018-12-25T12:14:57.000Z", "updatedAt"=>"2018-12-25T12:14:57.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>370365}, {"id"=>1259461, "metaname"=>"old_merchant_fee",
|
657
|
+
"metavalue"=>"0", "createdAt"=>"2018-12-25T12:14:57.000Z", "updatedAt"=>"2018-12-25T12:14:57.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>370365}]}
|
658
|
+
}
|
659
|
+
|
660
|
+
```
|
661
|
+
|
662
|
+
#### Full Preauth Transaction Flow:
|
663
|
+
|
664
|
+
```ruby
|
665
|
+
require 'rave_ruby'
|
666
|
+
|
667
|
+
|
668
|
+
# This is a rave object which is expecting public and secret keys
|
669
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
670
|
+
|
671
|
+
|
672
|
+
# This is the payload for preauth charge
|
673
|
+
|
674
|
+
payload = {
|
675
|
+
"token" => "flw-t1nf-75aa4a20695a54c1846e0e8bcae754ee-m03k",
|
676
|
+
"country" => "NG",
|
677
|
+
"amount" => "1000",
|
678
|
+
"email" => "user@gmail.com",
|
679
|
+
"firstname" => "temi",
|
680
|
+
"lastname" => "Oyekole",
|
681
|
+
"IP" => "190.233.222.1",
|
682
|
+
"currency" => "NGN",
|
683
|
+
}
|
684
|
+
|
685
|
+
|
686
|
+
# Instantiate the preauth object
|
687
|
+
preauth = Preauth.new(rave)
|
688
|
+
|
689
|
+
# Perform a charge with the card token from the saved from the card charge
|
690
|
+
response = preauth.initiate_charge(payload)
|
691
|
+
print response
|
692
|
+
|
693
|
+
# Perform capture
|
694
|
+
response = preauth.capture(response["flwRef"], "30")
|
695
|
+
print response
|
696
|
+
|
697
|
+
# Perform a refund
|
698
|
+
# response = preauth.refund(response["flwRef"])
|
699
|
+
# print response
|
700
|
+
|
701
|
+
# Void transaction
|
702
|
+
# response = preauth.void(response["flwRef"])
|
703
|
+
# print response
|
704
|
+
|
705
|
+
# Verify transaction
|
706
|
+
response = preauth.verify_preauth(response["txRef"])
|
707
|
+
print response
|
708
|
+
|
709
|
+
|
710
|
+
```
|
711
|
+
|
712
|
+
|
713
|
+
## `MobileMoney.new(rave)`
|
714
|
+
|
715
|
+
To perform ghana mobile money transactions, instantiate the mobile money object and pass rave object as its argument.
|
716
|
+
|
717
|
+
Its functions includes:
|
718
|
+
|
719
|
+
- `.initiate_charge`
|
720
|
+
- `.verify_charge`
|
721
|
+
|
722
|
+
### `.initiate_charge(payload)`
|
723
|
+
|
724
|
+
This function is called to initiate mobile money transaction. The payload should be a ruby hash with mobile money details. Its parameters should include the following:
|
725
|
+
|
726
|
+
- `amount`,
|
727
|
+
|
728
|
+
- `email`,
|
729
|
+
|
730
|
+
- `phonenumber`,
|
731
|
+
|
732
|
+
- `network`,
|
733
|
+
|
734
|
+
You can also add your custom transaction reference `(txRef)`, if not, one would be automatically generated for you in which we used the ruby `securerandom` module for generating this in the `Util` module.
|
735
|
+
|
736
|
+
#### Sample mobile money charge call:
|
737
|
+
|
738
|
+
```ruby
|
739
|
+
response = charge_mobile_money.initiate_charge(payload)
|
740
|
+
```
|
741
|
+
#### which returns:
|
742
|
+
|
743
|
+
It returns this response in ruby hash. A sample response:
|
744
|
+
|
745
|
+
```ruby
|
746
|
+
|
747
|
+
{
|
748
|
+
"error"=>false, "status"=>"success-pending-validation", "validation_required"=>true, "txRef"=>"MC-83d9405416ff2a7312d8e3d5fceb3d52", "flwRef"=>"flwm3s4m0c1545818908919", "amount"=>50, "currency"=>"GHS", "validateInstruction"=>nil, "authModelUsed"=>"MOBILEMONEY", "paymentType"=>"mobilemoneygh"
|
749
|
+
}
|
750
|
+
|
751
|
+
```
|
752
|
+
|
753
|
+
### `.verify_charge(txRef)`
|
754
|
+
|
755
|
+
You can call the `verify_charge` function to check if your transaction was completed successfully. To do this, you have to pass the transaction reference generated at the point of making your charge call. This is the txRef in the response parameter returned in any of the `initiate_charge` call.
|
756
|
+
|
757
|
+
#### Sample verify_charge call:
|
758
|
+
|
759
|
+
```ruby
|
760
|
+
response = charge_mobile_money.verify_charge(response["txRef"])
|
761
|
+
```
|
762
|
+
|
763
|
+
#### which returns:
|
764
|
+
|
765
|
+
It returns this response in ruby hash with the `txRef`, `flwRef` and `transaction_complete` which indicates the transaction is successfully completed.
|
766
|
+
|
767
|
+
Full sample response returned if a transaction is successfully verified:
|
768
|
+
|
769
|
+
```ruby
|
770
|
+
|
771
|
+
{
|
772
|
+
"error"=>false, "transaction_complete"=>true, "data"=>{"txid"=>371101, "txref"=>"MC-1c2a66b7bb6e55c254cad2a61b0ea47b", "flwref"=>"flwm3s4m0c1545824547181", "devicefingerprint"=>"N/A", "cycle"=>"one-time", "amount"=>50, "currency"=>"GHS", "chargedamount"=>50, "appfee"=>0.7, "merchantfee"=>0, "merchantbearsfee"=>1, "chargecode"=>"00", "chargemessage"=>"Pending Payment Validation", "authmodel"=>"MOBILEMONEY",
|
773
|
+
"ip"=>"::ffff:10.37.131.195", "narration"=>"Simply Recharge", "status"=>"successful", "vbvcode"=>"N/A", "vbvmessage"=>"N/A", "authurl"=>"NO-URL", "acctcode"=>"00", "acctmessage"=>"Approved", "paymenttype"=>"mobilemoneygh", "paymentid"=>"N/A", "fraudstatus"=>"ok", "chargetype"=>"normal", "createdday"=>3, "createddayname"=>"WEDNESDAY", "createdweek"=>52, "createdmonth"=>11, "createdmonthname"=>"DECEMBER", "createdquarter"=>4, "createdyear"=>2018, "createdyearisleap"=>false, "createddayispublicholiday"=>0, "createdhour"=>11, "createdminute"=>42, "createdpmam"=>"am", "created"=>"2018-12-26T11:42:26.000Z", "customerid"=>59839, "custphone"=>"08082000503", "custnetworkprovider"=>"AIRTEL", "custname"=>"Anonymous Customer", "custemail"=>"cezojejaze@nyrmusic.com", "custemailprovider"=>"COMPANY EMAIL", "custcreated"=>"2018-11-01T17:26:40.000Z", "accountid"=>6076, "acctbusinessname"=>"Simply Recharge", "acctcontactperson"=>"Jolaoso Yusuf", "acctcountry"=>"NG", "acctbearsfeeattransactiontime"=>1, "acctparent"=>1, "acctvpcmerchant"=>"N/A", "acctalias"=>nil, "acctisliveapproved"=>0, "orderref"=>"URF_MMGH_1545824546523_5297935", "paymentplan"=>nil, "paymentpage"=>nil, "raveref"=>nil, "amountsettledforthistransaction"=>49.3, "meta"=>[]}
|
774
|
+
|
775
|
+
}
|
776
|
+
```
|
777
|
+
|
778
|
+
If a transaction couldn't be verified successfully, `error` and `transaction_complete` would both come as `false`.
|
779
|
+
|
780
|
+
#### Full Mobile Money Transaction Flow:
|
781
|
+
|
782
|
+
```ruby
|
783
|
+
|
784
|
+
require 'rave_ruby'
|
785
|
+
|
786
|
+
|
787
|
+
# This is a rave object which is expecting public and secret keys
|
788
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
789
|
+
|
790
|
+
|
791
|
+
# This is used to perform mobile money charge
|
792
|
+
|
793
|
+
payload = {
|
794
|
+
"amount" => "50",
|
795
|
+
"email" => "cezojejaze@nyrmusic.com",
|
796
|
+
"phonenumber" => "08082000503",
|
797
|
+
"network" => "MTN",
|
798
|
+
"redirect_url" => "https://webhook.site/6eb017d1-c605-4faa-b543-949712931895",
|
799
|
+
"IP" => ""
|
800
|
+
}
|
801
|
+
|
802
|
+
# To initiate mobile money transaction
|
803
|
+
charge_mobile_money = MobileMoney.new(rave)
|
804
|
+
|
805
|
+
response = charge_mobile_money.initiate_charge(payload)
|
806
|
+
|
807
|
+
print response
|
808
|
+
|
809
|
+
# To verify the mobile money transaction
|
810
|
+
response = charge_mobile_money.verify_charge(response["txRef"])
|
811
|
+
|
812
|
+
print response
|
813
|
+
|
814
|
+
```
|
815
|
+
|
816
|
+
## `Mpesa.new(rave)`
|
817
|
+
|
818
|
+
To perform mpesa transactions, instantiate the mpesa object and pass rave object as its argument.
|
819
|
+
|
820
|
+
Its functions includes:
|
821
|
+
|
822
|
+
- `.initiate_charge`
|
823
|
+
- `.verify_charge`
|
824
|
+
|
825
|
+
### `.initiate_charge(payload)`
|
826
|
+
|
827
|
+
This function is called to initiate mpesa transaction. The payload should be a ruby hash with mpesa details. Its parameters should include the following:
|
828
|
+
|
829
|
+
- `amount`,
|
830
|
+
|
831
|
+
- `email`,
|
832
|
+
|
833
|
+
- `phonenumber`,
|
834
|
+
|
835
|
+
|
836
|
+
You can also add your custom transaction reference `(txRef)`, if not, one would be automatically generated for you in which we used the ruby `securerandom` module for generating this in the `Util` module.
|
837
|
+
|
838
|
+
#### Sample mpesa charge call:
|
839
|
+
|
840
|
+
```ruby
|
841
|
+
response = charge_mpesa.initiate_charge(payload)
|
842
|
+
```
|
843
|
+
#### which returns:
|
844
|
+
|
845
|
+
It returns this response in ruby hash. A sample response:
|
846
|
+
|
847
|
+
```ruby
|
848
|
+
|
849
|
+
{
|
850
|
+
"error"=>false, "status"=>"pending", "validation_required"=>true, "txRef"=>"MC-0ad3251bcdde39b16c225e9fc46e992c", "flwRef"=>"8833703548", "amount"=>"100", "currency"=>"KES", "paymentType"=>"mpesa"
|
851
|
+
}
|
852
|
+
|
853
|
+
```
|
854
|
+
|
855
|
+
### `.verify_charge(txRef)`
|
856
|
+
|
857
|
+
You can call the `verify_charge` function to check if your transaction was completed successfully. To do this, you have to pass the transaction reference generated at the point of making your charge call. This is the txRef in the response parameter returned in any of the `initiate_charge` call.
|
858
|
+
|
859
|
+
#### Sample verify_charge call:
|
860
|
+
|
861
|
+
```ruby
|
862
|
+
response = charge_mpesa.verify_charge(response["txRef"])
|
863
|
+
```
|
864
|
+
|
865
|
+
#### which returns:
|
866
|
+
|
867
|
+
It returns this response in ruby hash with the `txRef`, `flwRef` and `transaction_complete` which indicates the transaction is successfully completed.
|
868
|
+
|
869
|
+
Full sample response returned if a transaction is successfully verified:
|
870
|
+
|
871
|
+
```ruby
|
872
|
+
|
873
|
+
{
|
874
|
+
"error"=>false, "transaction_complete"=>true, "data"=>{"txid"=>372498, "txref"=>"MC-0ad3251bcdde39b16c225e9fc46e992c", "flwref"=>"8833703548", "devicefingerprint"=>"N/A", "cycle"=>"one-time", "amount"=>100, "currency"=>"KES", "chargedamount"=>100, "appfee"=>1.4, "merchantfee"=>0, "merchantbearsfee"=>0, "chargecode"=>"00", "chargemessage"=>nil, "authmodel"=>"VBVSECURECODE", "ip"=>"::ffff:10.43.205.176", "narration"=>"funds payment", "status"=>"successful", "vbvcode"=>"N/A", "vbvmessage"=>"N/A", "authurl"=>"N/A", "acctcode"=>"00", "acctmessage"=>"MPESA COMPLETED", "paymenttype"=>"mpesa", "paymentid"=>"N/A", "fraudstatus"=>"ok", "chargetype"=>"normal", "createdday"=>4, "createddayname"=>"THURSDAY", "createdweek"=>52, "createdmonth"=>11, "createdmonthname"=>"DECEMBER", "createdquarter"=>4, "createdyear"=>2018, "createdyearisleap"=>false, "createddayispublicholiday"=>0, "createdhour"=>18, "createdminute"=>50, "createdpmam"=>"pm", "created"=>"2018-12-27T18:50:51.000Z", "customerid"=>65231, "custphone"=>"0926420185", "custnetworkprovider"=>"UNKNOWN PROVIDER", "custname"=>"Anonymous customer", "custemail"=>"user@exampe.com", "custemailprovider"=>"COMPANY EMAIL", "custcreated"=>"2018-11-27T15:23:38.000Z", "accountid"=>6076, "acctbusinessname"=>"Simply Recharge", "acctcontactperson"=>"Jolaoso Yusuf", "acctcountry"=>"NG", "acctbearsfeeattransactiontime"=>1,
|
875
|
+
"acctparent"=>1, "acctvpcmerchant"=>"N/A", "acctalias"=>nil, "acctisliveapproved"=>0, "orderref"=>"8833703548", "paymentplan"=>nil, "paymentpage"=>nil, "raveref"=>nil, "amountsettledforthistransaction"=>98.6, "meta"=>[{"id"=>1259900, "metaname"=>"MPESARESPONSE", "metavalue"=>"{\"billrefnumber\":\"8833703548\",\"transactionamount\":\"100.00\",\"transactionid\":372498,\"type\":\"mpesa\"}", "createdAt"=>"2018-12-27T18:50:56.000Z", "updatedAt"=>"2018-12-27T18:50:56.000Z", "deletedAt"=>nil, "getpaidTransactionId"=>372498}]}
|
876
|
+
}
|
877
|
+
```
|
878
|
+
|
879
|
+
If a transaction couldn't be verified successfully, `error` and `transaction_complete` would both come as `false`.
|
880
|
+
|
881
|
+
#### Full Mpesa Transaction Flow:
|
882
|
+
|
883
|
+
```ruby
|
884
|
+
|
885
|
+
require 'rave_ruby'
|
886
|
+
|
887
|
+
|
888
|
+
# This is a rave object which is expecting public and secret keys
|
889
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
890
|
+
|
891
|
+
|
892
|
+
# This is used to perform mpesa charge
|
893
|
+
|
894
|
+
payload = {
|
895
|
+
"amount" => "100",
|
896
|
+
"phonenumber" => "0926420185",
|
897
|
+
"email" => "user@exampe.com",
|
898
|
+
"IP" => "40.14.290",
|
899
|
+
"narration" => "funds payment",
|
900
|
+
}
|
901
|
+
|
902
|
+
# To initiate mpesa transaction
|
903
|
+
charge_mpesa = Mpesa.new(rave)
|
904
|
+
|
905
|
+
response = charge_mpesa.initiate_charge(payload)
|
906
|
+
|
907
|
+
print response
|
908
|
+
|
909
|
+
# To verify the mpesa transaction
|
910
|
+
response = charge_mpesa.verify_charge(response["txRef"])
|
911
|
+
|
912
|
+
print response
|
913
|
+
|
914
|
+
```
|
915
|
+
|
916
|
+
## `SubAccount.new(rave)`
|
917
|
+
|
918
|
+
This is used to process and manage subaccount flow. Instantiate the subaccount object and pass rave object as its argument.
|
919
|
+
|
920
|
+
Its functions includes:
|
921
|
+
|
922
|
+
- `.create_subaccount`
|
923
|
+
- `.list_subaccounts`
|
924
|
+
- `.fetch_subaccount`
|
925
|
+
- `.delete_subaccount`
|
926
|
+
|
927
|
+
### `.create_subaccount(payload)`
|
928
|
+
|
929
|
+
This function is called to initiate subaccount transaction. The payload should be a ruby hash with the subaccount details. Its parameters should include the following:
|
930
|
+
|
931
|
+
- `account_bank`,
|
932
|
+
|
933
|
+
- `account_number`,
|
934
|
+
|
935
|
+
- `business_name`,
|
936
|
+
|
937
|
+
- `business_email`,
|
938
|
+
|
939
|
+
- `business_contact`,
|
940
|
+
|
941
|
+
- `business_contact_mobile`,
|
942
|
+
|
943
|
+
- `business_mobile`,
|
944
|
+
|
945
|
+
- `split_type`,
|
946
|
+
|
947
|
+
- `split_value`,
|
948
|
+
|
949
|
+
#### `NOTE:`
|
950
|
+
|
951
|
+
- split_type can be set as percentage or flat when set as percentage it means you want to take a percentage fee on all transactions, and vice versa for flat this means you want to take a flat fee on every transaction.
|
952
|
+
|
953
|
+
- split_value can be a percentage value or flat value depending on what was set on split_type.
|
954
|
+
|
955
|
+
#### Sample create_subaccount call:
|
956
|
+
|
957
|
+
```ruby
|
958
|
+
response = subaccount.create_subaccount(payload)
|
959
|
+
```
|
960
|
+
|
961
|
+
#### which returns:
|
962
|
+
|
963
|
+
It returns this response in ruby hash. A sample response:
|
964
|
+
|
965
|
+
```ruby
|
966
|
+
{
|
967
|
+
"error"=>false, "id"=>350, "data"=>{"id"=>350, "account_number"=>"0690000033", "account_bank"=>"044", "business_name"=>"Test Stores", "fullname"=>"Bale Gary", "date_created"=>"2018-12-28T16:20:40.000Z", "meta"=>[{"metaname"=>"MarketplaceID", "metavalue"=>"ggs-920900"}], "account_id"=>14101, "split_ratio"=>1, "split_type"=>"flat", "split_value"=>3000, "subaccount_id"=>"RS_CC09B109AA8F0CA5D9CE067492C548DA", "bank_name"=>"ACCESS BANK NIGERIA", "country"=>"NG"}
|
968
|
+
}
|
969
|
+
|
970
|
+
```
|
971
|
+
|
972
|
+
### `.list_subaccounts`
|
973
|
+
|
974
|
+
This function is called to list all subaccounts under an account. The function can be initiated by calling it on a subaccount object.
|
975
|
+
|
976
|
+
#### Sample list_subaccount call:
|
977
|
+
|
978
|
+
```ruby
|
979
|
+
response = subaccount.list_subaccounts
|
980
|
+
```
|
981
|
+
|
982
|
+
#### which returns:
|
983
|
+
|
984
|
+
It returns this response in ruby hash. A sample response:
|
985
|
+
|
986
|
+
```ruby
|
987
|
+
|
988
|
+
{
|
989
|
+
"error"=>false, "data"=>{"status"=>"success", "message"=>"SUBACCOUNTS", "data"=>{"page_info"=>{"total"=>6, "current_page"=>1, "total_pages"=>1}, "subaccounts"=>[{"id"=>350, "account_number"=>"0690000033", "account_bank"=>"044", "business_name"=>"Test Stores", "fullname"=>"Bale Gary", "date_created"=>"2018-12-28T16:20:40.000Z", "meta"=>[{"metaname"=>"MarketplaceID", "metavalue"=>"ggs-920900"}], "account_id"=>14101, "split_ratio"=>1, "split_type"=>"flat", "split_value"=>3000, "subaccount_id"=>"RS_CC09B109AA8F0CA5D9CE067492C548DA", "bank_name"=>"ACCESS BANK NIGERIA", "country"=>"NG"}, {"id"=>344, "account_number"=>"0690000041", "account_bank"=>"044", "business_name"=>"Sub 2", "fullname"=>"Alexis Rogers", "date_created"=>"2018-12-21T11:39:09.000Z", "meta"=>nil, "account_id"=>13633, "split_ratio"=>1, "split_type"=>"flat", "split_value"=>100, "subaccount_id"=>"RS_A75DB3502DDE69D07834A770888C26EE", "bank_name"=>"ACCESS BANK NIGERIA", "country"=>"NG"}, {"id"=>343, "account_number"=>"0690000031", "account_bank"=>"044", "business_name"=>"Sub 1", "fullname"=>"Forrest Green", "date_created"=>"2018-12-21T11:37:00.000Z", "meta"=>nil, "account_id"=>13632, "split_ratio"=>1, "split_type"=>"flat", "split_value"=>40, "subaccount_id"=>"RS_D073562598485BCEEB0A5287F99623FC", "bank_name"=>"ACCESS BANK NIGERIA", "country"=>"NG"}, {"id"=>325, "account_number"=>"0690000032", "account_bank"=>"044", "business_name"=>"Jake Stores", "fullname"=>"Pastor Bright", "date_created"=>"2018-12-13T20:34:51.000Z", "meta"=>[{"metaname"=>"MarketplaceID", "metavalue"=>"ggs-920900"}], "account_id"=>13212, "split_ratio"=>1, "split_type"=>"flat", "split_value"=>3000, "subaccount_id"=>"RS_4091F27A32D176070DA3CAF018E3450E", "bank_name"=>"ACCESS BANK NIGERIA", "country"=>"NG"}, {"id"=>126, "account_number"=>"0690000037", "account_bank"=>"044", "business_name"=>"Sub Account 2", "fullname"=>"Ibra Mili", "date_created"=>"2018-10-12T15:08:48.000Z", "meta"=>nil, "account_id"=>9522, "split_ratio"=>1, "split_type"=>"flat", "split_value"=>500, "subaccount_id"=>"RS_AE7B0858E69C6BFEB5C143CAA0A13FC3", "bank_name"=>"ACCESS BANK NIGERIA", "country"=>"NG"}, {"id"=>125, "account_number"=>"0690000035", "account_bank"=>"044", "business_name"=>"sub account 1", "fullname"=>"Peter Crouch", "date_created"=>"2018-10-12T14:39:41.000Z", "meta"=>nil, "account_id"=>9520, "split_ratio"=>1, "split_type"=>"flat", "split_value"=>100, "subaccount_id"=>"RS_2B1B3B6985172B9046A58DCA9E9026E0", "bank_name"=>"ACCESS BANK NIGERIA", "country"=>"NG"}]}}
|
990
|
+
}
|
991
|
+
|
992
|
+
```
|
993
|
+
|
994
|
+
### `.fetch_subaccount(subaccount_id)`
|
995
|
+
|
996
|
+
This function is used to fetch a subaccount details by taking in the subaccount id as its argument.
|
997
|
+
|
998
|
+
#### Sample fetch_subaccount call:
|
999
|
+
|
1000
|
+
```ruby
|
1001
|
+
response = subaccount.fetch_subaccount("RS_CC09B109AA8F0CA5D9CE067492C548DA")
|
1002
|
+
```
|
1003
|
+
|
1004
|
+
#### which returns:
|
1005
|
+
|
1006
|
+
It returns this response in ruby hash. A sample response:
|
1007
|
+
|
1008
|
+
```ruby
|
1009
|
+
{
|
1010
|
+
"error"=>false, "data"=>{"status"=>"success", "message"=>"SUBACCOUNT", "data"=>{"id"=>350, "account_number"=>"0690000033", "account_bank"=>"044", "business_name"=>"Test Stores", "fullname"=>"Bale Gary", "date_created"=>"2018-12-28T16:20:40.000Z", "meta"=>[{"metaname"=>"MarketplaceID", "metavalue"=>"ggs-920900"}], "account_id"=>14101, "split_ratio"=>1, "split_type"=>"flat", "split_value"=>3000, "subaccount_id"=>"RS_CC09B109AA8F0CA5D9CE067492C548DA", "bank_name"=>"ACCESS BANK NIGERIA", "country"=>"NG"}}
|
1011
|
+
}
|
1012
|
+
```
|
1013
|
+
|
1014
|
+
### `.delete_subaccount(subaccount_id)`
|
1015
|
+
|
1016
|
+
This function is used to delete a subaccount by taking in the subaccount id as its argument.
|
1017
|
+
|
1018
|
+
#### Sample delete_subaccount call:
|
1019
|
+
|
1020
|
+
```ruby
|
1021
|
+
response = subaccount.delete_subaccount("RS_CC09B109AA8F0CA5D9CE067492C548DA")
|
1022
|
+
```
|
1023
|
+
|
1024
|
+
#### which returns:
|
1025
|
+
|
1026
|
+
It returns this response in ruby hash. A sample response:
|
1027
|
+
|
1028
|
+
```ruby
|
1029
|
+
{
|
1030
|
+
"error"=>false, "data"=>{"status"=>"success", "message"=>"SUBACCOUNT-DELETED", "data"=>"Deleted"}
|
1031
|
+
}
|
1032
|
+
```
|
1033
|
+
|
1034
|
+
#### Full SubAccount Flow:
|
1035
|
+
|
1036
|
+
```ruby
|
1037
|
+
|
1038
|
+
require 'rave_ruby'
|
1039
|
+
|
1040
|
+
|
1041
|
+
# This is a rave object which is expecting public and secret keys
|
1042
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
1043
|
+
|
1044
|
+
|
1045
|
+
# This is the payload for sub account creation
|
1046
|
+
|
1047
|
+
payload = {
|
1048
|
+
"account_bank" => "044",
|
1049
|
+
"account_number" => "0690000033",
|
1050
|
+
"business_name" => "Test Stores",
|
1051
|
+
"business_email" => "test@test.com",
|
1052
|
+
"business_contact" => "john doe",
|
1053
|
+
"business_contact_mobile" => "09083772",
|
1054
|
+
"business_mobile" => "0188883882",
|
1055
|
+
"split_type" => "flat",
|
1056
|
+
"split_value" => 3000,
|
1057
|
+
"meta" => [{"metaname": "MarketplaceID", "metavalue": "ggs-920900"}]
|
1058
|
+
}
|
1059
|
+
|
1060
|
+
# Instantiate the subaccount object
|
1061
|
+
subaccount = SubAccount.new(rave)
|
1062
|
+
|
1063
|
+
# This is used to create a subaccount
|
1064
|
+
response = subaccount.create_subaccount(payload)
|
1065
|
+
print response
|
1066
|
+
|
1067
|
+
# This is used to list all subaccounts
|
1068
|
+
response = subaccount.list_subaccounts
|
1069
|
+
print response
|
1070
|
+
|
1071
|
+
# This is used to fetch a subaccount by taking in the subaccount id
|
1072
|
+
response = subaccount.fetch_subaccount("RS_A59429B9C94C5A862F731711290B9ADD")
|
1073
|
+
print response
|
1074
|
+
|
1075
|
+
# This is used to delete a subaccount by taking in the subaccount id
|
1076
|
+
response = subaccount.delete_subaccount("RS_A59429B9C94C5A862F731711290B9ADD")
|
1077
|
+
print response
|
1078
|
+
|
1079
|
+
```
|
1080
|
+
|
1081
|
+
## `PaymentPlan.new(rave)`
|
1082
|
+
|
1083
|
+
This is used to process and manage payment plan flow. Instantiate the paymentplan object and pass rave object as its argument.
|
1084
|
+
|
1085
|
+
Its functions includes:
|
1086
|
+
|
1087
|
+
- `.create_payment_plan`
|
1088
|
+
- `.list_payment_plans`
|
1089
|
+
- `.fetch_payment_plan`
|
1090
|
+
- `.edit_payment_plan`
|
1091
|
+
- `.cancel_payment_plan`
|
1092
|
+
|
1093
|
+
### `.create_payment_plan(payload)`
|
1094
|
+
|
1095
|
+
This function is called to initiate payment plan transaction. The payload should be a ruby hash with the payment plan details. Its parameters should include the following:
|
1096
|
+
|
1097
|
+
- `amount`,
|
1098
|
+
|
1099
|
+
- `name`,
|
1100
|
+
|
1101
|
+
- `interval`,
|
1102
|
+
|
1103
|
+
- `duration`,
|
1104
|
+
|
1105
|
+
#### `NOTE:`
|
1106
|
+
|
1107
|
+
- amount: this is the amount for the plan
|
1108
|
+
|
1109
|
+
- name: This is what would appear on the subscription reminder email
|
1110
|
+
|
1111
|
+
- interval: This are the charge intervals possible values are:
|
1112
|
+
|
1113
|
+
```
|
1114
|
+
daily;
|
1115
|
+
weekly;
|
1116
|
+
monthly;
|
1117
|
+
yearly;
|
1118
|
+
quarterly;
|
1119
|
+
bi-anually;
|
1120
|
+
every 2 days;
|
1121
|
+
every 90 days;
|
1122
|
+
every 5 weeks;
|
1123
|
+
every 12 months;
|
1124
|
+
every 6 years;
|
1125
|
+
every x y (where x is a number and y is the period e.g. every 5 months)
|
1126
|
+
|
1127
|
+
```
|
1128
|
+
- duration: This is the frequency, it is numeric, e.g. if set to 5 and intervals is set to monthly you would be charged 5 months, and then the subscription stops.
|
1129
|
+
|
1130
|
+
`If duration is not passed, any subscribed customer will be charged indefinitely.`
|
1131
|
+
|
1132
|
+
#### Sample create_payment_plan call:
|
1133
|
+
|
1134
|
+
```ruby
|
1135
|
+
response = payment_plan.create_payment_plan(payload)
|
1136
|
+
```
|
1137
|
+
|
1138
|
+
#### which returns:
|
1139
|
+
|
1140
|
+
It returns this response in ruby hash. A sample response:
|
1141
|
+
|
1142
|
+
```ruby
|
1143
|
+
{
|
1144
|
+
"error"=>false, "data"=>{"id"=>1298, "name"=>"New Test Plan", "amount"=>1000, "interval"=>"monthly", "duration"=>5, "status"=>"active",
|
1145
|
+
"currency"=>"NGN", "plan_token"=>"rpp_9002500b0440b470f02c", "date_created"=>"2018-12-30T10:54:06.000Z"}
|
1146
|
+
}
|
1147
|
+
|
1148
|
+
```
|
1149
|
+
|
1150
|
+
### `.list_payment_plans`
|
1151
|
+
|
1152
|
+
This function is called to list all payment plans under an account. The function can be initiated by calling it on a paymentplan object.
|
1153
|
+
|
1154
|
+
#### Sample list_payment_plans call:
|
1155
|
+
|
1156
|
+
```ruby
|
1157
|
+
response = payment_plan.list_payment_plans
|
1158
|
+
```
|
1159
|
+
|
1160
|
+
#### which returns:
|
1161
|
+
|
1162
|
+
It returns this response in ruby hash. A sample response:
|
1163
|
+
|
1164
|
+
```ruby
|
1165
|
+
{
|
1166
|
+
"error"=>false, "status"=>"success", "message"=>"QUERIED-PAYMENTPLANS", "data"=>{"page_info"=>{"total"=>21, "current_page"=>1, "total_pages"=>3}, "paymentplans"=>[{"id"=>1298, "name"=>"New Test Plan", "amount"=>1000, "interval"=>"monthly", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_9002500b0440b470f02c", "date_created"=>"2018-12-30T10:54:06.000Z"}, {"id"=>1225, "name"=>"Test Plan", "amount"=>100, "interval"=>"daily", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_6da8f78957b92b3e9128", "date_created"=>"2018-12-12T20:22:43.000Z"}, {"id"=>1196, "name"=>"Jack's Plan", "amount"=>100, "interval"=>"daily", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_49ae581c01d998841116", "date_created"=>"2018-12-04T16:42:58.000Z"}, {"id"=>1195, "name"=>"Test Plan", "amount"=>100, "interval"=>"daily", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_7156462224bc29c5e429", "date_created"=>"2018-12-04T16:39:41.000Z"}, {"id"=>1194, "name"=>"Test Plan", "amount"=>100, "interval"=>"daily", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_a361053c176ae01ae6ea", "date_created"=>"2018-12-04T16:39:14.000Z"}, {"id"=>1193, "name"=>"Test Plan", "amount"=>100, "interval"=>"daily", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_4a6ca4bedef850362dbd", "date_created"=>"2018-12-04T16:34:10.000Z"}, {"id"=>1192, "name"=>"Test Plan", "amount"=>100, "interval"=>"daily", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_7185c10c96eae1b62c92", "date_created"=>"2018-12-04T16:33:22.000Z"}, {"id"=>1191, "name"=>"Test Plan", "amount"=>100, "interval"=>"daily", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_c0bcf71beb2d048d0883", "date_created"=>"2018-12-04T16:32:00.000Z"}, {"id"=>1190, "name"=>"Test Plan", "amount"=>100, "interval"=>"daily", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_607c22f130a5a90e51af", "date_created"=>"2018-12-04T16:27:27.000Z"}, {"id"=>1154, "name"=>"N/A", "amount"=>0, "interval"=>"daily", "duration"=>0, "status"=>"cancelled", "currency"=>"NGN", "plan_token"=>"rpp_cb2ec11390fd718b6eb0", "date_created"=>"2018-11-27T11:31:21.000Z"}]}
|
1167
|
+
}
|
1168
|
+
```
|
1169
|
+
|
1170
|
+
### `.fetch_payment_plan(payment_plan_id, payment_plan_name)`
|
1171
|
+
|
1172
|
+
This function is used to fetch a payment plan details by taking in the payment plan id and payment plan name as its argument.
|
1173
|
+
|
1174
|
+
#### Sample fetch_payment_plan call:
|
1175
|
+
|
1176
|
+
```ruby
|
1177
|
+
response = payment_plan.fetch_payment_plan("1298", "New Test Plan")
|
1178
|
+
```
|
1179
|
+
|
1180
|
+
#### which returns:
|
1181
|
+
|
1182
|
+
It returns this response in ruby hash. A sample response:
|
1183
|
+
|
1184
|
+
```ruby
|
1185
|
+
{
|
1186
|
+
"error"=>false, "data"=>{"page_info"=>{"total"=>1, "current_page"=>1, "total_pages"=>1}, "paymentplans"=>[{"id"=>1298, "name"=>"New Test Plan", "amount"=>1000, "interval"=>"monthly", "duration"=>5, "status"=>"active", "currency"=>"NGN", "plan_token"=>"rpp_9002500b0440b470f02c", "date_created"=>"2018-12-30T10:54:06.000Z"}]}
|
1187
|
+
}
|
1188
|
+
```
|
1189
|
+
|
1190
|
+
### `.edit_payment_plan(payment_plan_id, payment_plan_name)`
|
1191
|
+
|
1192
|
+
This function is used to edit a payment plan by taking in the the payment plan id and payment plan name as its argument.
|
1193
|
+
|
1194
|
+
#### Sample edit_payment_plan call:
|
1195
|
+
|
1196
|
+
```ruby
|
1197
|
+
|
1198
|
+
response = payment_plan.edit_payment_plan("1298", {"name" => "Updated Test Plan", "status" => "active"})
|
1199
|
+
```
|
1200
|
+
|
1201
|
+
#### which returns:
|
1202
|
+
|
1203
|
+
It returns this response in ruby hash. A sample response:
|
1204
|
+
|
1205
|
+
```ruby
|
1206
|
+
{
|
1207
|
+
"error"=>false, "data"=>{"id"=>1298, "name"=>"Updated Test Plan", "uuid"=>"rpp_9002500b0440b470f02c", "status"=>"active", "start"=>nil,
|
1208
|
+
"stop"=>nil, "initial_charge_amount"=>nil, "currency"=>"NGN", "amount"=>1000, "duration"=>5, "interval"=>"monthly", "createdAt"=>"2018-12-30T10:54:06.000Z", "updatedAt"=>"2018-12-30T11:26:17.000Z", "deletedAt"=>nil, "AccountId"=>3328, "paymentpageId"=>nil}
|
1209
|
+
}
|
1210
|
+
```
|
1211
|
+
|
1212
|
+
### `.cancel_payment_plan("payment_plan_id")`
|
1213
|
+
|
1214
|
+
This function is used to cancel a payment plan by taking in the payment plan id as its argument.
|
1215
|
+
|
1216
|
+
#### Sample cancel_payment_plan call:
|
1217
|
+
|
1218
|
+
```ruby
|
1219
|
+
response = payment_plan.cancel_payment_plan("1298")
|
1220
|
+
```
|
1221
|
+
#### which returns:
|
1222
|
+
|
1223
|
+
It returns this response in ruby hash. A sample response:
|
1224
|
+
|
1225
|
+
```ruby
|
1226
|
+
{
|
1227
|
+
"error"=>false, "data"=>{"id"=>1298, "name"=>"Updated Test Plan", "uuid"=>"rpp_9002500b0440b470f02c", "status"=>"cancelled", "start"=>nil, "stop"=>nil, "initial_charge_amount"=>nil, "currency"=>"NGN", "amount"=>1000, "duration"=>5, "interval"=>"monthly", "createdAt"=>"2018-12-30T10:54:06.000Z", "updatedAt"=>"2018-12-30T11:44:55.000Z", "deletedAt"=>nil, "AccountId"=>3328, "paymentpageId"=>nil}
|
1228
|
+
}
|
1229
|
+
```
|
1230
|
+
|
1231
|
+
#### Full PaymentPlan Flow:
|
1232
|
+
|
1233
|
+
```ruby
|
1234
|
+
|
1235
|
+
require 'rave_ruby'
|
1236
|
+
|
1237
|
+
|
1238
|
+
# This is a rave object which is expecting public and secret keys
|
1239
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
1240
|
+
|
1241
|
+
# payment plan payload
|
1242
|
+
payload = {
|
1243
|
+
"amount" => 1000,
|
1244
|
+
"name" => "New Test Plan",
|
1245
|
+
"interval" => "monthly",
|
1246
|
+
"duration" => 5
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
|
1250
|
+
# create an instance of the payment plan object
|
1251
|
+
payment_plan = PaymentPlan.new(rave)
|
1252
|
+
|
1253
|
+
# method to create payment plan
|
1254
|
+
# response = payment_plan.create_payment_plan(payload)
|
1255
|
+
# print response
|
1256
|
+
|
1257
|
+
# # method to list all payment plan
|
1258
|
+
# response = payment_plan.list_payment_plans
|
1259
|
+
# print response
|
1260
|
+
|
1261
|
+
# method to fetch payment plan
|
1262
|
+
response = payment_plan.fetch_payment_plan("1298", "New Test Plan")
|
1263
|
+
print response
|
1264
|
+
|
1265
|
+
|
1266
|
+
# method to edit payment plan
|
1267
|
+
response = payment_plan.edit_payment_plan("1298", {"name" => "Updated Test Plan", "status" => "active"})
|
1268
|
+
print response
|
1269
|
+
|
1270
|
+
# method to cancel payment plan
|
1271
|
+
response = payment_plan.cancel_payment_plan("1298")
|
1272
|
+
print response
|
1273
|
+
|
1274
|
+
```
|
1275
|
+
## `Subscription.new(rave)`
|
1276
|
+
|
1277
|
+
This is used to process and manage subscription flow. Instantiate the subscription object and pass rave object as its argument.
|
1278
|
+
|
1279
|
+
Its functions includes:
|
1280
|
+
|
1281
|
+
- `.list_all_subscription`
|
1282
|
+
- `.fetch_subscription`
|
1283
|
+
- `.activate_subscription`
|
1284
|
+
- `.cancel_subscription`
|
1285
|
+
|
1286
|
+
### `.list_all_subscription`
|
1287
|
+
|
1288
|
+
This function is called to fetch and list all subscription.
|
1289
|
+
|
1290
|
+
#### Sample list_all_subscription call:
|
1291
|
+
|
1292
|
+
```ruby
|
1293
|
+
response = subscription.list_all_subscription
|
1294
|
+
```
|
1295
|
+
#### which returns:
|
1296
|
+
|
1297
|
+
It returns this response in ruby hash. A sample response:
|
1298
|
+
|
1299
|
+
```ruby
|
1300
|
+
{
|
1301
|
+
"error"=>false, "status"=>"success", "message"=>"SUBSCRIPTIONS-FETCHED", "data"=>{"page_info"=>{"total"=>0, "current_page"=>0, "total_pages"=>0}, "plansubscriptions"=>[]}, "plansubscriptions"=>[]
|
1302
|
+
}
|
1303
|
+
```
|
1304
|
+
|
1305
|
+
### `.fetch_subscription("subscription_id", "subscription_email")`
|
1306
|
+
|
1307
|
+
This function is called to fetch a single subscription taking the subscription id and subscription email as its arguments.
|
1308
|
+
|
1309
|
+
#### Sample fetch_subscription call:
|
1310
|
+
|
1311
|
+
```ruby
|
1312
|
+
response = subscription.fetch_subscription("1", "test@test.com")
|
1313
|
+
```
|
1314
|
+
#### which returns:
|
1315
|
+
|
1316
|
+
It returns this response in ruby hash. A sample response:
|
1317
|
+
|
1318
|
+
```ruby
|
1319
|
+
{
|
1320
|
+
"error"=>false, "status"=>"success", "message"=>"SUBSCRIPTIONS-FETCHED", "data"=>{"page_info"=>{"total"=>0, "current_page"=>0, "total_pages"=>0}, "plansubscriptions"=>[]}
|
1321
|
+
}
|
1322
|
+
```
|
1323
|
+
|
1324
|
+
### `.activate_subscription("subscription_id")`
|
1325
|
+
|
1326
|
+
This function is called to activate a subscription taking the subscription id as its argument.
|
1327
|
+
|
1328
|
+
#### Sample activate_subscription call:
|
1329
|
+
|
1330
|
+
```ruby
|
1331
|
+
response = subscription.activate_subscription(1533)
|
1332
|
+
```
|
1333
|
+
#### which returns:
|
1334
|
+
|
1335
|
+
It returns this response in ruby hash. A sample response:
|
1336
|
+
|
1337
|
+
```ruby
|
1338
|
+
|
1339
|
+
```
|
1340
|
+
|
1341
|
+
### `.cancel_subscription("subscription_id")`
|
1342
|
+
|
1343
|
+
This function is called to cancel a subscription taking the subscription id as its argument.
|
1344
|
+
|
1345
|
+
#### Sample cancel_subscription call:
|
1346
|
+
|
1347
|
+
```ruby
|
1348
|
+
response = subscription.cancel_subscription(1533)
|
1349
|
+
```
|
1350
|
+
#### which returns:
|
1351
|
+
|
1352
|
+
It returns this response in ruby hash. A sample response:
|
1353
|
+
|
1354
|
+
```ruby
|
1355
|
+
|
1356
|
+
```
|
1357
|
+
|
1358
|
+
### Full Subscription Flow
|
1359
|
+
|
1360
|
+
```ruby
|
1361
|
+
require 'rave_ruby'
|
1362
|
+
|
1363
|
+
# This is a rave object which is expecting public and secret keys
|
1364
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
1365
|
+
|
1366
|
+
subscription = Subscription.new(rave)
|
1367
|
+
response = subscription.list_all_subscription
|
1368
|
+
print response
|
1369
|
+
response = subscription.fetch_subscription("1", "test@test.com")
|
1370
|
+
print response
|
1371
|
+
response = subscription.activate_subscription(1533)
|
1372
|
+
print response
|
1373
|
+
response = subscription.cancel_subscription(1533)
|
1374
|
+
print response
|
1375
|
+
```
|
1376
|
+
|
1377
|
+
## `Transfer.new(rave)`
|
1378
|
+
|
1379
|
+
This is used to initiate transfer flow. Instantiate the transfer object and pass rave object as its argument.
|
1380
|
+
|
1381
|
+
Its functions includes:
|
1382
|
+
|
1383
|
+
- `.initiate_transfer`
|
1384
|
+
- `.bulk_transfer`
|
1385
|
+
- `.get_fee`
|
1386
|
+
- `.get_balance`
|
1387
|
+
- `.fetch`
|
1388
|
+
- `.fetch_all_transfers`
|
1389
|
+
|
1390
|
+
### `.initiate_transfer`
|
1391
|
+
|
1392
|
+
This function is called to initiate a single transfer from one account to another. The payload should be a ruby hash with the beneficiary's account details. Its parameters should include the following:
|
1393
|
+
|
1394
|
+
- `account_bank`,
|
1395
|
+
|
1396
|
+
- `account_number`,
|
1397
|
+
|
1398
|
+
- `amount`,
|
1399
|
+
|
1400
|
+
- `narration`,
|
1401
|
+
|
1402
|
+
- `currency`,
|
1403
|
+
|
1404
|
+
#### `NOTE:`
|
1405
|
+
|
1406
|
+
For international transfers, you must pass a meta parameter as part of your payload as shown in the sample below:
|
1407
|
+
|
1408
|
+
```ruby
|
1409
|
+
"meta": [
|
1410
|
+
{
|
1411
|
+
"AccountNumber": "09182972BH",
|
1412
|
+
"RoutingNumber": "0000000002993",
|
1413
|
+
"SwiftCode": "ABJG190",
|
1414
|
+
"BankName": "BANK OF AMERICA, N.A., SAN FRANCISCO, CA",
|
1415
|
+
"BeneficiaryName": "Mark Cuban",
|
1416
|
+
"BeneficiaryAddress": "San Francisco, 4 Newton",
|
1417
|
+
"BeneficiaryCountry": "US"
|
1418
|
+
}
|
1419
|
+
]
|
1420
|
+
```
|
1421
|
+
#### Sample initiate_transfer call:
|
1422
|
+
|
1423
|
+
```ruby
|
1424
|
+
response = transfer.initiate_transfer(payload)
|
1425
|
+
```
|
1426
|
+
#### which returns:
|
1427
|
+
|
1428
|
+
It returns this response in ruby hash. A sample response:
|
1429
|
+
|
1430
|
+
```ruby
|
1431
|
+
|
1432
|
+
{
|
1433
|
+
"error"=>false, "id"=>4520, "data"=>{"id"=>4520, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2019-01-02T08:07:26.000Z", "currency"=>"NGN", "amount"=>500, "fee"=>45, "status"=>"NEW", "reference"=>"MC-df53da98eb0d7475c9e33727dec09e78", "meta"=>nil, "narration"=>"New transfer", "complete_message"=>"", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}
|
1434
|
+
}
|
1435
|
+
```
|
1436
|
+
|
1437
|
+
### `.bulk_transfer`
|
1438
|
+
|
1439
|
+
This function is called to initiate a bulk transfer. The payload should be a ruby hash with the beneficiaries account details. Its parameters should include the following:
|
1440
|
+
|
1441
|
+
- `title`,
|
1442
|
+
|
1443
|
+
- `bulk_data`,
|
1444
|
+
|
1445
|
+
#### `NOTE:`
|
1446
|
+
|
1447
|
+
The bulk_data should consist of an array of the beneficiaries account details which includes `account_bank`, `account_number`, `amount`, `narration`, `currency`, `reference`.
|
1448
|
+
|
1449
|
+
#### Sample bulk_transfer call:
|
1450
|
+
|
1451
|
+
```ruby
|
1452
|
+
response = transfer.bulk_transfer(payload)
|
1453
|
+
```
|
1454
|
+
#### which returns:
|
1455
|
+
|
1456
|
+
It returns this response in ruby hash. A sample response:
|
1457
|
+
|
1458
|
+
```ruby
|
1459
|
+
|
1460
|
+
{
|
1461
|
+
"error"=>false, "status"=>"success", "message"=>"BULK-TRANSFER-CREATED", "id"=>765, "data"=>{"id"=>765, "date_created"=>"2019-01-02T08:20:20.000Z", "approver"=>"N/A"}
|
1462
|
+
}
|
1463
|
+
```
|
1464
|
+
|
1465
|
+
### `.get_fee`
|
1466
|
+
|
1467
|
+
This function is called to get transfer rates for all Rave supported currencies. You may or may not pass in a currency as its argument. If you do not pass in a currency, all Rave supported currencies transfer rates will be returned.
|
1468
|
+
|
1469
|
+
#### Sample get_fee call:
|
1470
|
+
|
1471
|
+
```ruby
|
1472
|
+
response = transfer.get_fee(currency)
|
1473
|
+
```
|
1474
|
+
#### which returns:
|
1475
|
+
|
1476
|
+
It returns this response in ruby hash. A sample response:
|
1477
|
+
|
1478
|
+
```ruby
|
1479
|
+
{
|
1480
|
+
"error"=>false, "data"=>{"status"=>"success", "message"=>"TRANSFER-FEES", "data"=>[{"id"=>1, "fee_type"=>"value", "currency"=>"NGN", "fee"=>45, "createdAt"=>nil, "updatedAt"=>nil, "deletedAt"=>nil, "AccountId"=>1}]}
|
1481
|
+
}
|
1482
|
+
```
|
1483
|
+
|
1484
|
+
### `.get_balance`
|
1485
|
+
|
1486
|
+
This function is called to get balance an account. You may or may not pass in a currency as its argument.
|
1487
|
+
|
1488
|
+
#### Sample get_balance call:
|
1489
|
+
|
1490
|
+
```ruby
|
1491
|
+
response = transfer.get_balance(currency)
|
1492
|
+
```
|
1493
|
+
#### which returns:
|
1494
|
+
|
1495
|
+
It returns this response in ruby hash. A sample response:
|
1496
|
+
|
1497
|
+
```ruby
|
1498
|
+
{
|
1499
|
+
"error"=>false, "returned_data"=>{"status"=>"success", "message"=>"WALLET-BALANCE", "data"=>{"Id"=>27622, "ShortName"=>"NGN", "WalletNumber"=>"3927000121168", "AvailableBalance"=>100, "LedgerBalance"=>100}}
|
1500
|
+
}
|
1501
|
+
```
|
1502
|
+
|
1503
|
+
### `.fetch`
|
1504
|
+
|
1505
|
+
This function is called to fetch a single transfer. It takes in transfer refernce as its argument.
|
1506
|
+
|
1507
|
+
#### Sample fetch call:
|
1508
|
+
|
1509
|
+
```ruby
|
1510
|
+
response = transfer.fetch("Bulk Transfer 2")
|
1511
|
+
```
|
1512
|
+
#### which returns:
|
1513
|
+
|
1514
|
+
It returns this response in ruby hash. A sample response:
|
1515
|
+
|
1516
|
+
```ruby
|
1517
|
+
{
|
1518
|
+
"error"=>false, "returned_data"=>{"status"=>"success", "message"=>"QUERIED-TRANSFERS", "data"=>{"page_info"=>{"total"=>0, "current_page"=>0, "total_pages"=>0}, "transfers"=>[]}}
|
1519
|
+
}
|
1520
|
+
```
|
1521
|
+
|
1522
|
+
### `.fetch_all_transfers`
|
1523
|
+
|
1524
|
+
This function is called to fetch all transfers.
|
1525
|
+
|
1526
|
+
#### Sample fetch all transfers call:
|
1527
|
+
|
1528
|
+
```ruby
|
1529
|
+
response = transfer.fetch_all_transfers
|
1530
|
+
```
|
1531
|
+
#### which returns:
|
1532
|
+
|
1533
|
+
It returns this response in ruby hash. A sample response:
|
1534
|
+
|
1535
|
+
```ruby
|
1536
|
+
{
|
1537
|
+
"error"=>false, "returned_data"=>{"status"=>"success", "message"=>"QUERIED-TRANSFERS", "data"=>{"page_info"=>{"total"=>97, "current_page"=>1, "total_pages"=>10}, "transfers"=>[{"id"=>4520, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2019-01-02T08:07:26.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-df53da98eb0d7475c9e33727dec09e78", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4103, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-14T16:38:23.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-3b3814d6e2bc0d7d6683354abcdd5b98", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4102, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-14T14:54:31.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-26efdf0a77145315ac7d62ee274371a5", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4101, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-14T11:00:29.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-1d7ad363292b0c3a18cbccff891bd332", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4074, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-13T21:24:50.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-96d44c562f077869953b63a0d86e8263", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4073, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-13T21:16:08.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-510222befb79c0ac9d6aa6cb0010547a", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4072, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-13T21:09:52.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-38e5c011326d88b67f2ae9fe39e94212", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4071, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-13T20:59:21.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-9dbe233dc15abf647412670d965d9fce", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4070, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-13T20:31:45.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-e2d49d7f68e48d80dfdab2871d14bda3", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}, {"id"=>4069, "account_number"=>"0690000044", "bank_code"=>"044", "fullname"=>"Mercedes Daniel", "date_created"=>"2018-12-13T20:22:50.000Z", "currency"=>"NGN", "debit_currency"=>nil, "amount"=>500, "fee"=>45, "status"=>"FAILED", "reference"=>"MC-5af02b704d1d66884f7e50fe7a81ba82", "meta"=>nil, "narration"=>"New transfer", "approver"=>nil, "complete_message"=>"DISBURSE FAILED: Insufficient funds", "requires_approval"=>0, "is_approved"=>1, "bank_name"=>"ACCESS BANK NIGERIA"}]}}
|
1538
|
+
}
|
1539
|
+
```
|
1540
|
+
|
1541
|
+
### Full Transfer Flow
|
1542
|
+
|
1543
|
+
```ruby
|
1544
|
+
require 'rave_ruby'
|
1545
|
+
|
1546
|
+
# This is a rave object which is expecting public and secret keys
|
1547
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
1548
|
+
|
1549
|
+
# This is used to initiate single transfer
|
1550
|
+
|
1551
|
+
payload = {
|
1552
|
+
"account_bank" => "044",
|
1553
|
+
"account_number" => "0690000044",
|
1554
|
+
"amount" => 500,
|
1555
|
+
"narration" => "New transfer",
|
1556
|
+
"currency" => "NGN",
|
1557
|
+
}
|
1558
|
+
|
1559
|
+
transfer = Transfer.new(rave)
|
1560
|
+
|
1561
|
+
response = transfer.initiate_transfer(payload)
|
1562
|
+
print response
|
1563
|
+
|
1564
|
+
|
1565
|
+
# # This is used to send bulk transfer
|
1566
|
+
|
1567
|
+
# payload = {
|
1568
|
+
# "title" => "test",
|
1569
|
+
# "bulk_data" => [
|
1570
|
+
# {
|
1571
|
+
# "account_bank" => "044",
|
1572
|
+
# "account_number" => "0690000044",
|
1573
|
+
# "amount" => 500,
|
1574
|
+
# "narration" => "Bulk Transfer 1",
|
1575
|
+
# "currency" => "NGN",
|
1576
|
+
# "reference" => "MC-bulk-reference-1"
|
1577
|
+
# },
|
1578
|
+
# {
|
1579
|
+
# "account_bank" => "044",
|
1580
|
+
# "account_number" => "0690000034",
|
1581
|
+
# "amount" => 500,
|
1582
|
+
# "narration" => "Bulk Transfer 2",
|
1583
|
+
# "currency" => "NGN",
|
1584
|
+
# "reference" => "MC-bulk-reference-1"
|
1585
|
+
# }
|
1586
|
+
# ]
|
1587
|
+
# }
|
1588
|
+
|
1589
|
+
|
1590
|
+
# transfer = Transfer.new(rave)
|
1591
|
+
|
1592
|
+
# response = transfer.bulk_transfer(payload)
|
1593
|
+
# print response
|
1594
|
+
|
1595
|
+
# This is used to get the transfer fee by taking in the currency
|
1596
|
+
response = transfer.get_fee("NGN")
|
1597
|
+
print response
|
1598
|
+
|
1599
|
+
# This is used to get the balance by taking in the currency
|
1600
|
+
response = transfer.get_balance("NGN")
|
1601
|
+
print response
|
1602
|
+
|
1603
|
+
# This is used to fetch a single transfer by passing in the transaction reference
|
1604
|
+
response = transfer.fetch("Bulk Transfer 2")
|
1605
|
+
print response
|
1606
|
+
|
1607
|
+
# This is used to fetch all transfer
|
1608
|
+
response = transfer.fetch_all_transfers
|
1609
|
+
print response
|
1610
|
+
```
|
1611
|
+
|
1612
|
+
## `UgandaMobileMoney.new(rave)`
|
1613
|
+
|
1614
|
+
To perform uganda mobile money transactions, instantiate the uganda mobile money object and pass rave object as its argument.
|
1615
|
+
|
1616
|
+
Its functions includes:
|
1617
|
+
|
1618
|
+
- `.initiate_charge`
|
1619
|
+
- `.verify_charge`
|
1620
|
+
|
1621
|
+
### `.initiate_charge(payload)`
|
1622
|
+
|
1623
|
+
This function is called to initiate uganda mobile money transaction. The payload should be a ruby hash with uganda mobile money details. Its parameters should include the following:
|
1624
|
+
|
1625
|
+
- `amount`,
|
1626
|
+
|
1627
|
+
- `email`,
|
1628
|
+
|
1629
|
+
- `phonenumber`,
|
1630
|
+
|
1631
|
+
- `network`,
|
1632
|
+
|
1633
|
+
You can also add your custom transaction reference `(txRef)`, if not, one would be automatically generated for you in which we used the ruby `securerandom` module for generating this in the `Util` module.
|
1634
|
+
|
1635
|
+
#### Sample uganda mobile money charge call:
|
1636
|
+
|
1637
|
+
```ruby
|
1638
|
+
response = charge_uganda_mobile_money.initiate_charge(payload)
|
1639
|
+
```
|
1640
|
+
#### which returns:
|
1641
|
+
|
1642
|
+
It returns this response in ruby hash. A sample response:
|
1643
|
+
|
1644
|
+
```ruby
|
1645
|
+
|
1646
|
+
{
|
1647
|
+
"error"=>false, "status"=>"success-pending-validation", "validation_required"=>true, "txRef"=>"MC-c716f37ff7c0f719c5976aaf239e11e1", "flwRef"=>"flwm3s4m0c1546503628014", "amount"=>30, "currency"=>"UGX", "validateInstruction"=>nil, "authModelUsed"=>"MOBILEMONEY", "paymentType"=>"mobilemoneygh"
|
1648
|
+
}
|
1649
|
+
|
1650
|
+
```
|
1651
|
+
|
1652
|
+
### `.verify_charge(txRef)`
|
1653
|
+
|
1654
|
+
You can call the `verify_charge` function to check if your transaction was completed successfully. To do this, you have to pass the transaction reference generated at the point of making your charge call. This is the txRef in the response parameter returned in any of the `initiate_charge` call.
|
1655
|
+
|
1656
|
+
#### Sample verify_charge call:
|
1657
|
+
|
1658
|
+
```ruby
|
1659
|
+
response = charge_uganda_mobile_money.verify_charge(response["txRef"])
|
1660
|
+
```
|
1661
|
+
|
1662
|
+
#### which returns:
|
1663
|
+
|
1664
|
+
It returns this response in ruby hash with the `txRef`, `flwRef` and `transaction_complete` which indicates the transaction is successfully completed.
|
1665
|
+
|
1666
|
+
Full sample response returned if a transaction is successfully verified:
|
1667
|
+
|
1668
|
+
```ruby
|
1669
|
+
{
|
1670
|
+
"error"=>false, "transaction_complete"=>false, "data"=>{"txid"=>378423, "txref"=>"MC-c716f37ff7c0f719c5976aaf239e11e1", "flwref"=>"flwm3s4m0c1546503628014", "devicefingerprint"=>"N/A", "cycle"=>"one-time", "amount"=>30, "currency"=>"UGX", "chargedamount"=>30, "appfee"=>0.8, "merchantfee"=>0, "merchantbearsfee"=>1, "chargecode"=>"02", "chargemessage"=>"Pending Payment Validation", "authmodel"=>"MOBILEMONEY", "ip"=>"::ffff:10.65.63.158", "narration"=>"Simply Recharge", "status"=>"success-pending-validation", "vbvcode"=>"N/A", "vbvmessage"=>"N/A", "authurl"=>"NO-URL", "acctcode"=>nil, "acctmessage"=>nil, "paymenttype"=>"mobilemoneygh", "paymentid"=>"N/A", "fraudstatus"=>"ok", "chargetype"=>"normal", "createdday"=>4, "createddayname"=>"THURSDAY", "createdweek"=>1, "createdmonth"=>0, "createdmonthname"=>"JANUARY",
|
1671
|
+
"createdquarter"=>1, "createdyear"=>2019, "createdyearisleap"=>false, "createddayispublicholiday"=>0, "createdhour"=>8, "createdminute"=>20, "createdpmam"=>"am", "created"=>"2019-01-03T08:20:27.000Z", "customerid"=>66732, "custphone"=>"054709929300", "custnetworkprovider"=>"UNKNOWN PROVIDER", "custname"=>"Edward Kisane", "custemail"=>"tester@flutter.co", "custemailprovider"=>"COMPANY EMAIL", "custcreated"=>"2018-12-03T11:33:23.000Z", "accountid"=>6076, "acctbusinessname"=>"Simply Recharge", "acctcontactperson"=>"Jolaoso Yusuf", "acctcountry"=>"NG", "acctbearsfeeattransactiontime"=>1, "acctparent"=>1, "acctvpcmerchant"=>"N/A", "acctalias"=>nil, "acctisliveapproved"=>0, "orderref"=>"URF_MMGH_1546503627253_1491735", "paymentplan"=>nil, "paymentpage"=>nil, "raveref"=>nil, "meta"=>[]}
|
1672
|
+
}
|
1673
|
+
```
|
1674
|
+
|
1675
|
+
If the `chargecode` returned is `02`, it means the transaction is still pending validation else if it returns `00`, it means the transaction is successfully completed.
|
1676
|
+
|
1677
|
+
#### Full Uganda Mobile Money Transaction Flow:
|
1678
|
+
|
1679
|
+
```ruby
|
1680
|
+
|
1681
|
+
require 'rave_ruby'
|
1682
|
+
|
1683
|
+
|
1684
|
+
# This is a rave object which is expecting public and secret keys
|
1685
|
+
rave = RaveRuby.new("FLWPUBK-xxxxxxxxxxxxxxxxxxxxx-X", "FLWSECK-xxxxxxxxxxxxxxxxxxxx-X")
|
1686
|
+
|
1687
|
+
|
1688
|
+
# This is used to perform mobile money charge
|
1689
|
+
|
1690
|
+
payload = {
|
1691
|
+
"amount" => "30",
|
1692
|
+
"phonenumber" => "054709929300",
|
1693
|
+
"firstname" => "Edward",
|
1694
|
+
"lastname" => "Kisane",
|
1695
|
+
"network" => "UGX",
|
1696
|
+
"email" => "tester@flutter.co",
|
1697
|
+
"IP" => '103.238.105.185',
|
1698
|
+
"redirect_url" => "https://webhook.site/6eb017d1-c605-4faa-b543-949712931895",
|
1699
|
+
}
|
1700
|
+
|
1701
|
+
# To initiate uganda mobile money transaction
|
1702
|
+
charge_uganda_mobile_money = UgandaMobileMoney.new(rave)
|
1703
|
+
|
1704
|
+
response = charge_uganda_mobile_money.initiate_charge(payload)
|
1705
|
+
|
1706
|
+
print response
|
1707
|
+
|
1708
|
+
# To verify the mobile money transaction
|
1709
|
+
response = charge_uganda_mobile_money.verify_charge(response["txRef"])
|
1710
|
+
|
1711
|
+
print response
|
1712
|
+
|
1713
|
+
```
|
1714
|
+
|
1715
|
+
## `Ussd.new(rave)`
|
1716
|
+
|
1717
|
+
`NOTE:` This option is currently unavailable.
|
1718
|
+
|
1719
|
+
## `ListBanks.new(rave)`
|
1720
|
+
|
1721
|
+
This function is called to fetch and return a list of banks currently supported by rave.
|
1722
|
+
|
1723
|
+
## Development
|
1724
|
+
|
1725
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
1726
|
+
|
1727
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
1728
|
+
|
1729
|
+
## Contributors
|
1730
|
+
|
1731
|
+
- [Ifunanya Ikemma](https://github.com/iphytech)
|
1732
|
+
|
1733
|
+
## Contributing
|
1734
|
+
|
1735
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/MaestroJolly/rave_ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
1736
|
+
|
1737
|
+
## License
|
1738
|
+
|
1739
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
1740
|
+
|
1741
|
+
## Code of Conduct
|
1742
|
+
|
1743
|
+
Everyone interacting in the RaveRuby project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/MaestroJolly/rave_ruby/blob/master/CODE_OF_CONDUCT.md).
|