Skip to content

Commit fd27b3e

Browse files
committed
Update to the Node v3 Library for February
1 parent 8280c19 commit fd27b3e

File tree

11 files changed

+237
-39
lines changed

11 files changed

+237
-39
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## 1.1.8 | 2024-02-19
4+
This release, we've addressed several Hotfixes and added support for the new NIBBS BVN verification flow. Check out the details below:
5+
6+
### Version Changes.
7+
- [ADDED] NIBBS BVN verification flow.
8+
- [ADDED] unit tests for the new BVN verification flow, transaction fees, and Card Collection into subaccounts.
9+
- [ADDED] 'subaccounts' as an optional body parameter for card charge and PWBT (Pay with Bank Transfer).
10+
- [FIXED] "URL Not Found" Error returned from Validate Bill Service method.
11+
- [FIXED] "Invalid currency provided" Error returned from the Transaction fees method.
12+
313
## 1.1.7 | 2024-01-25
414
In this release, we've enhanced payment methods and addressed various housekeeping issues to ensure a smoother experience. Check out the details below:
515

lib/rave.misc.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const balances_currency = require('../services/misc/rave.balances-currency');
22
const get_bal = require('../services/misc/rave.balances');
3-
const bankBVN = require('../services/misc/rave.bvn');
3+
const initBVN = require('../services/misc/rave.initiate.bvn');
4+
const verifBVN = require('../services/misc/rave.verify.bvn')
45
const resolve_act = require('../services/misc/rave.resolve.account');
56

67
function Misc(RaveBase) {
@@ -13,8 +14,13 @@ function Misc(RaveBase) {
1314
};
1415

1516
this.bvn = function (data) {
16-
return bankBVN(data, RaveBase);
17+
return initBVN(data, RaveBase);
1718
};
19+
20+
this.verifybvn = function (data) {
21+
return verifBVN(data, RaveBase);
22+
}
23+
1824
this.verify_Account = function (data) {
1925
return resolve_act(data, RaveBase);
2026
};

services/bills/rave.validate-bill.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { validateSchema } = require('../schema/bill');
55
async function service(data, _rave) {
66
validator(validateSchema, data);
77
data.method = 'GET';
8+
data.excludeQuery = true;
89
const { body: response } = await _rave.request(
910
`v3/bill-items/${data.item_code}/validate?code=${data.code}&customer=${data.customer}`,
1011
data,
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
const { logger } = require('../../utils/logger');
22
const { validator } = require('../../utils/validator');
3-
const { validateBVNSchema } = require('../schema/auxillary');
3+
const { initiateBVNSchema } = require('../schema/auxillary');
44

55
async function service(data, _rave) {
6-
validator(validateBVNSchema, data);
7-
data.method = 'GET';
6+
validator(initiateBVNSchema, data);
87
const { body: response } = await _rave.request(
9-
`v3/kyc/bvns/${data.bvn}`,
8+
`v3/bvn/verifications`,
109
data,
1110
);
12-
logger(`Resolve BVN details`, _rave);
11+
logger(`Initiate BVN consent`, _rave);
1312
return response;
1413
}
1514

services/misc/rave.verify.bvn.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const { logger } = require('../../utils/logger');
2+
const { validator } = require('../../utils/validator');
3+
const { verifyBVNSchema } = require('../schema/auxillary');
4+
5+
async function service(data, _rave) {
6+
validator(verifyBVNSchema, data);
7+
data.method = 'GET';
8+
data.excludeQuery = true;
9+
const { body: response } = await _rave.request(
10+
`v3/bvn/verifications/${data.reference}`,
11+
data,
12+
);
13+
logger(`Verify BVN consent`, _rave);
14+
return response;
15+
}
16+
17+
module.exports = service;

services/schema/auxillary.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,15 @@ const validateSchema = joi.object({
139139
});
140140

141141
// validate a BVN
142-
const validateBVNSchema = joi.object({
142+
const initiateBVNSchema = joi.object({
143143
bvn: joi.string().length(11).required(),
144+
firstname: joi.string().max(100).required(),
145+
lastname: joi.string().max(100).required(),
146+
redirect_url: joi.string().uri(),
147+
});
148+
149+
const verifyBVNSchema = joi.object({
150+
reference: joi.string().trim().max(100).required(),
144151
});
145152

146153
module.exports = {
@@ -158,5 +165,6 @@ module.exports = {
158165
updateTokenSchema,
159166
withdrawalSchema,
160167
validateSchema,
161-
validateBVNSchema,
168+
initiateBVNSchema,
169+
verifyBVNSchema
162170
};

services/schema/create.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,14 @@ const cardChargeSchema = joi.object({
249249
}),
250250
payment_plan: joi.string(),
251251
meta: joi.object().pattern(/^[a-zA-Z0-9_]*$/, joi.any()),
252+
subaccounts: joi.array().items(
253+
joi.object({
254+
id: joi.string().trim().max(100).required(),
255+
transaction_split_ratio: joi.number().positive(),
256+
transaction_charge_type: joi.string().valid('flat', 'percentage', 'flat_subaccount'),
257+
transaction_charge: joi.number().positive(),
258+
})
259+
).min(1),
252260
});
253261

254262
// initiate collections for different payment methods
@@ -282,6 +290,14 @@ const chargeSchema = joi.object({
282290
billing_zip: joi.string(),
283291
meta: joi.object().pattern(/^[a-zA-Z0-9_]*$/, joi.any()),
284292
expires: joi.number().positive().max(31536000),
293+
subaccounts: joi.array().items(
294+
joi.object({
295+
id: joi.string().trim().max(100).required(),
296+
transaction_split_ratio: joi.number().positive(),
297+
transaction_charge_type: joi.string().valid('flat', 'percentage', 'flat_subaccount'),
298+
transaction_charge: joi.number().positive(),
299+
})
300+
).min(1),
285301
});
286302

287303
// create eNaira charge

services/transactions/rave.fee.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const { feeSchema } = require('../schema/auxillary');
55
async function service(data, _rave) {
66
validator(feeSchema, data);
77
data.method = 'GET';
8+
data.excludeQuery = true;
89
const { body: response } = await _rave.request(
910
`v3/transactions/fee?amount=${data.amount}&currency=${data.currency}`,
1011
data,

test/rave.charge.test.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -738,4 +738,92 @@ describe('#Rave charge', function () {
738738
expect(err.message).to.include('"currency" is required');
739739
}
740740
});
741+
742+
it('should return charge into collection subaccounts', async function () {
743+
this.timeout(10000);
744+
745+
const createCardChargeStub = sinon.stub(chargeInstance, 'card').resolves({
746+
status: 'success',
747+
message: 'Successful',
748+
data: {
749+
id: 4918672,
750+
tx_ref: 'MC-3243e000',
751+
flw_ref: 'FLW-MOCK-365702bdb12af7938bdd02860caf2bc2',
752+
device_fingerprint: 'N/A',
753+
amount: 100,
754+
charged_amount: 100,
755+
app_fee: 1.4,
756+
merchant_fee: 0,
757+
processor_response: 'Please enter the OTP sent to your mobile number 080****** and email te**@rave**.com',
758+
auth_model: 'NOAUTH',
759+
currency: 'NGN',
760+
ip: '54.75.161.64',
761+
narration: 'CARD Transaction ',
762+
status: 'successful',
763+
auth_url: 'https://ravesandboxapi.flutterwave.com/mockvbvpage?ref=FLW-MOCK-365702bdb12af7938bdd02860caf2bc2&code=00&message=Approved.%20Successful&receiptno=RN1708329200239',
764+
payment_type: 'card',
765+
plan: null,
766+
fraud_status: 'ok',
767+
charge_type: 'normal',
768+
created_at: '2024-02-19T07:53:20.000Z',
769+
account_id: 20937,
770+
customer: {
771+
id: 2356420,
772+
phone_number: null,
773+
name: 'Yolande Aglaé',
774+
email: 'user@example.com',
775+
created_at: '2024-02-19T07:53:20.000Z'
776+
},
777+
card: {
778+
first_6digits: '553188',
779+
last_4digits: '2950',
780+
issuer: 'MASTERCARD CREDIT',
781+
country: 'NG',
782+
type: 'MASTERCARD',
783+
expiry: '09/32'
784+
}
785+
}
786+
})
787+
788+
var payload = {
789+
card_number:"5531886652142950",
790+
cvv:"564",
791+
expiry_month:"09",
792+
expiry_year:"32",
793+
currency:"NGN",
794+
amount:"100",
795+
fullname:"Yolande Aglaé Colbert",
796+
email:"user@example.com",
797+
tx_ref:"MC-3243e000",
798+
redirect_url:"https://www,flutterwave.ng",
799+
enckey: process.env.ENCRYPTION_KEY,
800+
subaccounts: [
801+
{
802+
id: "RS_93667D2B73110DFFEF8449A8A0A32415",
803+
transaction_split_ratio: 2,
804+
transaction_charge_type: "flat",
805+
transaction_charge: 100,
806+
},
807+
{
808+
id: "RS_47CC41E35953182AC35E952D4F4CA713",
809+
transaction_split_ratio: 3,
810+
transaction_charge_type: "flat",
811+
transaction_charge: 100,
812+
},
813+
{
814+
id: "RS_EEF0D016C26BBF1543F09CEF6090AB49",
815+
transaction_split_ratio: 5,
816+
transaction_charge_type: "flat",
817+
transaction_charge: 100,
818+
},
819+
],
820+
};
821+
var resp = await chargeInstance.card(payload);
822+
expect(createCardChargeStub).to.have.been.calledOnce;
823+
expect(createCardChargeStub).to.have.been.calledOnceWith(payload);
824+
825+
expect(resp).to.have.property('status', 'success');
826+
827+
expect(resp.data).to.have.property('status', 'successful');
828+
});
741829
});

test/rave.misc.test.js

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -164,53 +164,71 @@ describe('#Rave Misc', function () {
164164
expect(resp.body.data[0]).to.have.property('ledger_balance');
165165
});
166166

167-
it('should verify BVN and return success message', async function () {
167+
it('should initiate BVN consent and return success message', async function () {
168168
this.timeout(10000);
169169

170-
const resolveBVNSuccessStub = sinon.stub(miscInstance, 'bvn').resolves({
170+
const resolveInitBVNSuccessStub = sinon.stub(miscInstance, 'bvn').resolves({
171171
body: {
172172
status: 'success',
173-
message: 'BVN details fetched',
173+
message: 'Bvn verification initiated',
174174
data: {
175-
bvn: '123456789',
176-
first_name: 'Wendy',
177-
middle_name: 'Chucky',
178-
last_name: 'Rhoades',
179-
date_of_birth: '01-01-1905',
180-
phone_number: '08012345678',
181-
registration_date: '01-01-1921',
182-
enrollment_bank: '044',
183-
enrollment_branch: 'Idejo',
184-
image_base_64: null,
185-
address: null,
186-
gender: 'Male',
187-
email: null,
188-
watch_listed: null,
189-
nationality: 'Nigerian',
190-
marital_status: null,
191-
state_of_residence: null,
192-
lga_of_residence: null,
193-
image: null,
194-
},
175+
url: 'https://nibss-bvn-consent-management.dev-flutterwave.com/cms/BvnConsent?session=MWNkNDI4ZWYtMjgwNy00ZjA1LWE5NzUtNzUyZGUyZDRjZWQz',
176+
reference: 'FLW71DC60942BAD76D2BD5B4E'
177+
}
195178
},
196179
});
197180

198181
var payload = {
199-
bvn: '12345678901',
182+
bvn: "12347832211",
183+
firstname: "Lyra",
184+
lastname: "Balacqua",
185+
redirect_url: "https://example-url.company.com"
200186
};
201187

202188
var resp = await miscInstance.bvn(payload);
203189

204-
expect(resolveBVNSuccessStub).to.have.been.calledOnce;
205-
expect(resolveBVNSuccessStub).to.have.been.calledOnceWith(payload);
190+
expect(resolveInitBVNSuccessStub).to.have.been.calledOnce;
191+
expect(resolveInitBVNSuccessStub).to.have.been.calledOnceWith(payload);
206192

207193
expect(resp.body).to.have.property('status', 'success');
194+
expect(resp.body).to.have.property('message', 'Bvn verification initiated');
208195
expect(resp.body).to.have.property('data');
209196

210-
expect(resp.body.data).to.have.property('bvn');
211-
expect(resp.body.data).to.have.property('first_name');
212-
expect(resp.body.data).to.have.property('date_of_birth');
213-
expect(resp.body.data).to.have.property('phone_number');
197+
expect(resp.body.data).to.have.property('reference');
198+
expect(resp.body.data).to.have.property('url');
199+
});
200+
201+
it('should verify BVN consent and return success message', async function () {
202+
this.timeout(10000);
203+
204+
const resolveVerifyBVNSuccessStub = sinon.stub(miscInstance, 'verifybvn').resolves({
205+
body: {
206+
status: 'success',
207+
message: 'Bvn details fetched',
208+
data: {
209+
first_name: 'Lyra',
210+
last_name: 'Balacqua',
211+
status: 'INITIATED',
212+
reference: 'FLW71DC60942BAD76D2BD5B4E',
213+
callback_url: null,
214+
bvn_data: null,
215+
created_at: '2024-02-16T08:28:10.000Z'
216+
}
217+
},
218+
});
219+
220+
var payload = {
221+
reference: "FLW71DC60942BAD76D2BD5B4E"
222+
};
223+
224+
var resp = await miscInstance.verifybvn(payload);
225+
226+
expect(resolveVerifyBVNSuccessStub).to.have.been.calledOnce;
227+
expect(resolveVerifyBVNSuccessStub).to.have.been.calledOnceWith(payload);
228+
229+
expect(resp.body).to.have.property('status', 'success');
230+
expect(resp.body).to.have.property('message', 'Bvn details fetched');
231+
expect(resp.body).to.have.property('data');
214232
});
215233

216234
it('should verify resolve bank account details', async function () {

0 commit comments

Comments
 (0)