Repository: Chimoney/chimoney-community-projects (language: python)

Issue:
Create a JS SDK for the Chimoney API
Create a JS SDK for ChiConnect, the new Chimoney API

- Should be installable from a package manager like NPM
- Should have some tests
- Should implement the endpoints outlined at [chimoney.readme.io/reference/introduction](chimoney.readme.io/reference/introduction)

### Resources
- About ChiConnect [chimoney.io/chiconnect](chimoney.io/chiconnect)
- Reference [chimoney.readme.io/reference/introduction](chimoney.readme.io/reference/introduction)
- Swagger Docs [api.chimoney.io/api-docs](api.chimoney.io/api-docs)



# Start here [api.chimoney.io](https://api.chimoney.io/)
Create a JS SDK for the Chimoney API
Create a JS SDK for ChiConnect, the new Chimoney API

- Should be installable from a package manager like NPM
- Should have some tests
- Should implement the endpoints outlined at [chimoney.readme.io/reference/introduction](chimoney.readme.io/reference/introduction)

### Resources
- About ChiConnect [chimoney.io/chiconnect](chimoney.io/chiconnect)
- Reference [chimoney.readme.io/reference/introduction](chimoney.readme.io/reference/introduction)
- Swagger Docs [api.chimoney.io/api-docs](api.chimoney.io/api-docs)



# Start here [api.chimoney.io](https://api.chimoney.io/)


Discussion / hints:
Hi! Can I work on this issue?

Yes @VoidCupboard. I’ll assign to you 
Thanks!
Hey, I'd love to work on this
So go ahead @Ayo-Awe . What we’d like to see at the end is a package on npm potential called chimoney.js with description, “node sdk for Chimoney’s api by the community. Maintained by @Ayo-Awe”
Alright, I'll get working on it right away
Wait I'm already working on this and I am mostly done with it (only I need to add tests)
@VoidCupboard yes. Let’s have multiple implementations. Both submissions will be valid and people can pick what they prefer to use
Ohk, thanks for the confirmation @uchibeke ^-^
Hi! Can I work on this issue?

Yes @VoidCupboard. I’ll assign to you 
Thanks!
Hey, I'd love to work on this
So go ahead @Ayo-Awe . What we’d like to see at the end is a package on npm potential called chimoney.js with description, “node sdk for Chimoney’s api by the community. Maintained by @Ayo-Awe”
Alright, I'll get working on it right away
Wait I'm already working on this and I am mostly done with it (only I need to add tests)
@VoidCupboard yes. Let’s have multiple implementations. Both submissions will be valid and people can pick what they prefer to use
Ohk, thanks for the confirmation @uchibeke ^-^

Fix patch:
diff --git a/submissions/chimoney-js/index.js b/submissions/chimoney-js/index.js
index bfc1f833..cbb405b7 100644
--- a/submissions/chimoney-js/index.js
+++ b/submissions/chimoney-js/index.js
@@ -2,18 +2,26 @@ const { AuthKeyError, TypeError } = require("./Errors");
 const account = require("./modules/Account");
 const info = require("./modules/Info");
 const payouts = require("./modules/Payouts");
+const wallet = require("./modules/Wallet");
+const redeem = require("./modules/Redeem");
+const mobileMoney = require("./modules/MobileMoney");
+const subAccount = require("./modules/SubAccount");
 
+/**
+ * This function sets up the chimoneyjs modules using an optional key
+ * @param {string?} apiKey Chi Money API key
+ * @returns The chimoneyjs Modules
+ */
 module.exports = function (apiKey) {
-  // apikey must exist
-  if (!apiKey) throw new AuthKeyError("apikey is required");
+  if (apiKey) {
+    // apikey must be a string
+    if (typeof apiKey !== "string")
+      throw new TypeError("apikey must be of type string");
 
-  // apikey must be a string
-  if (typeof apiKey !== "string")
-    throw new TypeError("apikey must be of type string");
-
-  // Set CHIMONEY_API_KEY environment variable
-  process.env.CHIMONEY_API_KEY = apiKey;
+    // Set CHIMONEY_API_KEY environment variable
+    process.env.CHIMONEY_API_KEY = apiKey;
+  }
 
   // Return modules
-  return { account, info, payouts };
+  return { account, info, payouts, wallet, subAccount, redeem, mobileMoney };
 };
diff --git a/submissions/chimoney-js/modules/MobileMoney.js b/submissions/chimoney-js/modules/MobileMoney.js
new file mode 100644
index 00000000..02545d04
--- /dev/null
+++ b/submissions/chimoney-js/modules/MobileMoney.js
@@ -0,0 +1,88 @@
+const { ValueError, TypeError } = require("../Errors");
+const {
+  handleRequest,
+  HTTPMETHODS,
+  formatJoiErrors,
+} = require("../utils/helpers");
+const Joi = require("joi");
+
+/**
+ * This function returns an array of all mobile money(momo) transactions
+ * @param {string} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function getAllTransactions(subAccount = null) {
+  const payload = {};
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/collections/mobile-money/all",
+  });
+}
+
+/**
+ * This function enables a user to make payment with mobile money (momo)
+ * @param {{amount:number, currency:string, phone_number:string, fullname:string, country:string, tx_ref:string}} paymentDetails An object with the appropriate payment details
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function makePayment(paymentDetails, subAccount = null) {
+  // Define validation schema
+  const schema = Joi.object({
+    amount: Joi.number().required(),
+    currency: Joi.string().required(),
+    phone_number: Joi.string().required(),
+    fullname: Joi.string().required(),
+    country: Joi.string().required(),
+    email: Joi.string().required(),
+    tx_ref: Joi.string().required(),
+  }).exist();
+
+  // Validate input
+  const { value, error } = schema.validate(paymentDetails, {
+    abortEarly: false,
+  });
+
+  if (error) throw new ValueError("invalid input(s)", formatJoiErrors(error));
+
+  const payload = { ...value };
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/collections/mobile-money/collect",
+  });
+}
+
+/**
+ * This function enables the user to verify mobile money payments
+ * @param {string} id The transaction id
+ * @param {string} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function verifyPayment(id, subAccount = null) {
+  if (!id) throw new ValueError("id is required");
+
+  if (typeof id !== "string") throw new TypeError("id must be of type string");
+
+  const payload = { id };
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/collections/mobile-money/verify",
+  });
+}
+
+module.exports = {
+  getAllTransactions,
+  makePayment,
+  verifyPayment,
+};
diff --git a/submissions/chimoney-js/modules/Payouts.js b/submissions/chimoney-js/modules/Payouts.js
index 69406b0f..cfe336ef 100644
--- a/submissions/chimoney-js/modules/Payouts.js
+++ b/submissions/chimoney-js/modules/Payouts.js
@@ -215,23 +215,26 @@ async function status(chiRef, subAccount = null) {
  * 		}
  * 	]
  *
+ * @param {boolean?} turnOffNotification if true, it turns off email notification
  * @param {string?} subAccount The subAccount of the transaction
  * @returns The response from the Chi Money API
  */
 async function initiateChimoney(
   chimoneys = [],
+  turnOffNotification = false,
   crypto_payments,
   subAccount = null
 ) {
   // Define validation schema
   const schema = Joi.object({
+    turnOffNotification: Joi.boolean().default(false),
     crypto_payments: Joi.array().optional().default([]),
     chimoneys: Joi.array().required(),
   });
 
   // Validate input
   const { value, error } = schema.validate(
-    { crypto_payments, chimoneys },
+    { turnOffNotification, crypto_payments, chimoneys },
     { abortEarly: false }
   );
 
diff --git a/submissions/chimoney-js/modules/Redeem.js b/submissions/chimoney-js/modules/Redeem.js
new file mode 100644
index 00000000..7fb25238
--- /dev/null
+++ b/submissions/chimoney-js/modules/Redeem.js
@@ -0,0 +1,195 @@
+const Joi = require("joi");
+const { ValueError, TypeError } = require("../Errors");
+const {
+  formatJoiErrors,
+  handleRequest,
+  HTTPMETHODS,
+} = require("../utils/helpers");
+
+/**
+ * This function allows you to redeem airtime transactions
+ * @param {string} chiRef The Chi reference
+ * @param {string} phoneNumber Phone number
+ * @param {string} countryToSend Country to send to
+ * @param {object?} meta Any data to be sent along the request
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function airtime(
+  chiRef,
+  phoneNumber,
+  countryToSend,
+  meta,
+  subAccount = null
+) {
+  // Define validation schema
+  const schema = Joi.object({
+    chiRef: Joi.string().required(),
+    phoneNumber: Joi.number().required(),
+    countryToSend: Joi.string().required(),
+    meta: Joi.object().default({}),
+  });
+
+  // Validate input
+  const { value, error } = schema.validate(
+    { chiRef, phoneNumber, countryToSend, meta },
+    { abortEarly: false }
+  );
+
+  if (error) throw new ValueError("invalid input(s)", formatJoiErrors(error));
+
+  const payload = { ...value };
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/redeem/airtime",
+  });
+}
+
+/**
+ * This function allows you to redeem any transaction (chimoney, momo, airtime)
+ * @param {string} chiRef The Chi reference
+ * @param {array<object>} redeemData Any array of objects containing data needed to redeem the transaction. see example below
+ * @example
+ * const redeemData = [
+ * 		{
+ * 			countryCode: "NG",
+ * 			productId: 1,
+ * 			valueInLocalCurrency: 1000
+ * 		}
+ * ]
+ * @param {object} [meta={}] Any data to be sent along with the request. defaults to an empty object
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function any(chiRef, redeemData, meta, subAccount = null) {
+  // Define validation schema
+  const schema = Joi.object({
+    chiRef: Joi.string().required(),
+    redeemData: Joi.array().required(),
+    meta: Joi.object().default({}),
+  });
+
+  // Validate input
+  const { value, error } = schema.validate(
+    { chiRef, redeemData, meta },
+    { abortEarly: false }
+  );
+
+  if (error) throw new ValueError("input error(s)", formatJoiErrors(error));
+
+  const payload = { ...value };
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/redeem/any",
+  });
+}
+/**
+ * This function allows you to redeem chimoney
+ * @param {array<object>} chimoneys An array of objects containing the redeem details
+ * @example
+ * const chimoneys = [
+ * 		{
+ * 			"field": "data"
+ * 		}
+ * ]
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function chimoney(chimoneys, subAccount = null) {
+  if (!chimoneys) throw new ValueError("chimoneys is required");
+
+  if (!Array.isArray(chimoneys))
+    throw new TypeError("chimoneys must be an array of objects");
+
+  const payload = { chimoneys };
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/redeem/chimoney",
+  });
+}
+
+/**
+ * This function allows you to redeem giftcard
+ * @param {string} chiRef The Chi reference
+ * @param {object} redeemOptions The data needed to redeem the transaction
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function giftCard(chiRef, redeemOptions, subAccount = null) {
+  // Define validation schema
+  const schema = Joi.object({
+    chiRef: Joi.string().required(),
+    redeemOptions: Joi.object().required(),
+  });
+
+  // Validate input
+  const { value, error } = schema.validate(
+    { chiRef, redeemOptions },
+    { abortEarly: false }
+  );
+
+  if (error) throw new ValueError("input error(s)", formatJoiErrors(error));
+
+  const payload = { ...value };
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/redeem/gift-card",
+  });
+}
+
+/**
+ * This function allows you to redeem mobile money (momo)
+ * @param {string} chiRef The Chi reference
+ * @param {object} redeemOptions The data needed to redeem the transaction
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function mobileMoney(chiRef, redeemOptions, subAccount = null) {
+  // Define validation schema
+  const schema = Joi.object({
+    chiRef: Joi.string().required(),
+    redeemOptions: Joi.object().required(),
+  });
+
+  // Validate input
+  const { value, error } = schema.validate(
+    { chiRef, redeemOptions },
+    { abortEarly: false }
+  );
+
+  if (error) throw new ValueError("input error(s)", formatJoiErrors(error));
+
+  const payload = { ...value };
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/redeem/mobile-money",
+  });
+}
+
+module.exports = {
+  airtime,
+  mobileMoney,
+  giftCard,
+  any,
+  chimoney,
+};
diff --git a/submissions/chimoney-js/modules/SubAccount.js b/submissions/chimoney-js/modules/SubAccount.js
new file mode 100644
index 00000000..c7e70203
--- /dev/null
+++ b/submissions/chimoney-js/modules/SubAccount.js
@@ -0,0 +1,93 @@
+const Joi = require("joi");
+const { ValueError, TypeError } = require("../Errors");
+const {
+  formatJoiErrors,
+  handleRequest,
+  HTTPMETHODS,
+} = require("../utils/helpers");
+
+/**
+ * This function creates a new subAccount with the provided name and email
+ * @param {string} name Name to give the new subAccount
+ * @param {string} email Email
+ * @returns The response from the Chi Money API
+ */
+async function create(name, email) {
+  // Define validation schema
+  const schema = Joi.object({
+    name: Joi.string().required(),
+    email: Joi.string().required(),
+  });
+
+  // Validate input
+  const { value, error } = schema.validate(
+    { name, email },
+    { abortEarly: false }
+  );
+
+  if (error) throw new ValueError("invalid input(s)", formatJoiErrors(error));
+
+  const payload = { ...value };
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/sub-account/create",
+  });
+}
+
+/**
+ * This function deletes the subAccount with the given id
+ * @param {string} id The id of the subAccount
+ * @returns The response from the Chi Money API
+ */
+async function deleteAccount(id) {
+  if (!id) throw new ValueError("id is required");
+
+  if (typeof id !== "string") throw new TypeError("id must be of type string");
+
+  params = { id };
+
+  return handleRequest({
+    method: HTTPMETHODS.DELETE,
+    params,
+    path: "/v0.2/sub-account/delete",
+  });
+}
+
+/**
+ * This function gets the details of the subAccount with the associated id
+ * @param {string} id The id of the subAccount
+ * @returns The response from the Chi Money API
+ */
+async function getDetails(id) {
+  if (!id) throw new ValueError("id is required");
+
+  if (typeof id !== "string") throw new TypeError("id must be of type string");
+
+  params = { id };
+
+  return handleRequest({
+    method: HTTPMETHODS.GET,
+    params,
+    path: "/v0.2/sub-account/get",
+  });
+}
+
+/**
+ * This function returns all the subAccounts associated with a user
+ * @returns The response from the Chi Money API
+ */
+async function getAll() {
+  return handleRequest({
+    method: HTTPMETHODS.GET,
+    path: "/v0.2/sub-account/list",
+  });
+}
+
+module.exports = {
+  getAll,
+  getDetails,
+  deleteAccount,
+  create,
+};
diff --git a/submissions/chimoney-js/modules/Wallet.js b/submissions/chimoney-js/modules/Wallet.js
new file mode 100644
index 00000000..6f7cd5b7
--- /dev/null
+++ b/submissions/chimoney-js/modules/Wallet.js
@@ -0,0 +1,87 @@
+const { ValueError, TypeError } = require("../Errors");
+const {
+  handleRequest,
+  HTTPMETHODS,
+  formatJoiErrors,
+} = require("../utils/helpers");
+const Joi = require("joi");
+
+/**
+ * This function gets all the wallets associated with a user
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function list(subAccount = null) {
+  const payload = {};
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    path: "/v0.2/wallets/list",
+    payload,
+  });
+}
+
+/**
+ * This function gets the details associated with a single user wallet
+ * @param {string} id The wallet id
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function details(id, subAccount = null) {
+  if (!id) throw new ValueError("id is required");
+
+  if (typeof id !== "string") throw new TypeError("id must be of type string");
+
+  const payload = {};
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/wallets/lookup",
+  });
+}
+
+/**
+ * This function lets you transfer funds to receiver
+ * @param {string} receiver The receiver id
+ * @param {string} wallet The wallet type
+ * @param {number} amount The amount of funds to be transferred in dollars
+ * @param {string?} subAccount The subAccount of the transaction
+ * @returns The response from the Chi Money API
+ */
+async function transfer(receiver, wallet, amount, subAccount) {
+  // Define validation schema
+  const schema = Joi.object({
+    receiver: Joi.string().required(),
+    wallet: Joi.string().required(),
+    amount: Joi.number().required(),
+  });
+
+  // Validate input
+  const { value, error } = schema.validate(
+    {
+      receiver,
+      wallet,
+      amount,
+    },
+    { abortEarly: false }
+  );
+
+  if (error) throw new ValueError("invalid input(s)", formatJoiErrors(error));
+
+  const payload = { ...value };
+
+  if (subAccount) payload.subAccount = subAccount;
+
+  return handleRequest({
+    method: HTTPMETHODS.POST,
+    payload,
+    path: "/v0.2/wallets/transfer",
+  });
+}
+
+module.exports = { list, transfer, details };
diff --git a/submissions/chimoney-js/package-lock.json b/submissions/chimoney-js/package-lock.json
index 400eca3b..3264fbb6 100644
--- a/submissions/chimoney-js/package-lock.json
+++ b/submissions/chimoney-js/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "chimoney.js",
-  "version": "1.0.0",
+  "version": "1.2.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "chimoney.js",
-      "version": "1.0.0",
+      "version": "1.2.0",
       "license": "MIT",
       "dependencies": {
         "axios": "^1.1.2",
diff --git a/submissions/chimoney-js/package.json b/submissions/chimoney-js/package.json
index 2e0994b8..c3d3e2e9 100644
--- a/submissions/chimoney-js/package.json
+++ b/submissions/chimoney-js/package.json
@@ -1,8 +1,8 @@
 {
   "name": "chimoneyjs",
-  "version": "1.0.0",
+  "version": "1.2.0",
   "description": "node sdk for Chimoney api by the community. Maintained by Awe Ayomidipupo\"",
-  "main": "index.js",
+  "main": "index",
   "scripts": {
     "test": "jest"
   },
diff --git a/submissions/chimoney-js/readme.md b/submissions/chimoney-js/readme.md
index 69bcdcbf..8540f863 100644
--- a/submissions/chimoney-js/readme.md
+++ b/submissions/chimoney-js/readme.md
@@ -2,19 +2,24 @@
 
 Chimoneyjs is a js wrapper for <a href="https://chimoney.io"> Chimoney </a>
 
-    - Account
-    - Info
-    - Payout
-    - Mobile Money
-    - Wallet
-    - Sub-Account
-    - Redeem
+- [Account](#using-the-account-api)
+- [Info](#using-the-info-api)
+- [Payout](#using-the-payouts-api)
+- [Mobile Money](#using-the-mobilemoney-api)
+- [Wallet](#using-the-wallet-api)
+- [Sub-Account](#using-the-subaccount-api)
+- [Redeem](#using-the-redeem-api)
 
 ## Getting Started
 
 - Register with <a href="https://chimoney.io"> Chimoney </a>
 - Request for API KEY from support
-- set Your "CHIMONEY_AUTH_KEY" environment variable
+- set Your "CHIMONEY_API_KEY" environment variable
+  You can use a .env file as shown below to set your API key
+
+  ```env
+  CHIMONEY_API_KEY = "YOUR API KEY"
+  ```
 
 ## Installing
 
@@ -22,46 +27,630 @@ Chimoneyjs is a js wrapper for <a href="https://chimoney.io"> Chimoney </a>
 
 ## Usage
 
-#### Importing the package
+#### Using chimoneyjs
+
+There are two ways of setting your API key.
+
+- You can export it as an environment variable as mentioned above (recommended)
+- You can pass it as an argument when initialising chimoney
 
 ```js
-// Initialise chimoney with your API key
-const chimoney = require("chimoneyjs")(YOURAPIKEY);
+// Initialise chimoney without api key (recommended)
+const chimoney = require("chimoneyjs")();
+
+// Initialise chimoney with api key
+require("dotenv").config();
+const chimoney = require("chimoneyjs")(process.env.API_KEY);
 ```
 
+The issue with the latter is that you'd have to initialise your api key whenever you import the package. For this reason we recommend exporting your apiKey as an environment variables
+
 #### Full Example
 
 ```js
-require("dotenv").config();
-const chimoney = require("chimoneyjs")(process.env.MYAPIKEY);
+const { account, wallet } = require("chimoneyjs")();
+
+account
+  .getAllTransactions()
+  .then((response) => console.log(response)) // model of response {status:"success", data:...}
+  .catch((err) => console.log(err));
 ```
 
-#### Using the Account API
+## API
+
+Every function returns the response body as received from the Chi Money API. Ideally each response is an object with **status** and **data** properties. **status** always has a value of "success". For more information about the responses visit [ChiMoneyAPI](https://chimoney.readme.io/reference/) documentation
 
 ```js
-require("dotenv").config();
-const { account } = require("chimoneyjs")(process.env.MYAPIKEY);
-```
-
-## TODO
-
-- [ ] Add all Endpoints
-
-  - [x] Account
-  - [x] Info
-  - [x] Payout
-  - [ ] Mobile Money
-  - [ ] Wallet
-  - [ ] Sub Account
-  - [ ] Redeem
-
-- [ ] Write Unit Tests
-  - [x] Account
-  - [x] Info
-  - [x] Payout
-  - [ ] Mobile Money
-  - [ ] Wallet
-  - [ ] Sub Account
-  - [ ] Redeem
-- [ ] Publish library on npm
-- [ ] Documentation
+// sample response
+{
+  status: "success",
+  data: {
+        amountInUSD: "20",
+        destinationCurrency: "NGN",
+        amountInDestinationCurrency: 11000,
+        validUntil: "2022-10-18T22:46:20.616Z"
+      }
+}
+```
+
+### Using the Account API
+
+```js
+const { account } = require("chimoneyjs")();
+```
+
+#### **getTransactionsByIssueID(issueID, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-accounts-issue-id-transactions)
+
+This function gets all transactions by IssueID
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| issueID    | <code>string</code> |                   | The issueID of the transaction    |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### **getAllTransactions(subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-accounts-transactions)
+
+This functions returns a list of transactions by account
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### **accountTransfer(receiver, amount, wallet, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-accounts-transfer)
+
+This transaction transfers funds from wallet to receiver
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| receiver   | <code>string</code> |                   | The receiver of the funds         |
+| amount     | <code>number</code> |                   | The amount of funds               |
+| wallet     | <code>string</code> |                   | The wallet to be transfered from  |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### **deleteUnpaidTransaction(chiRef, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/delete_v0-2-accounts-delete-unpaid-transaction)
+
+This function deletes an unpaid transaction
+
+_Returns_: The response from the ChiMoney API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| chiRef     | <code>string</code> |                   | The ID of the transaction         |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### **getTransactionByID(transctionId, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-accounts-transaction)
+
+This function gets a transaction by ID
+
+_Returns_: The response from the Chi Money API
+
+| Param        | Type                | Default           | Description                       |
+| ------------ | ------------------- | ----------------- | --------------------------------- |
+| transctionId | <code>string</code> |                   | The ID of the transaction         |
+| subAccount   | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+### Using the Info API
+
+```js
+const { info } = require("chimoneyjs")();
+```
+
+#### **airtimeCountries()**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/get_v0-2-info-airtime-countries)
+
+This function returns a list of countries that support airtime
+
+_Returns_: The response from Chi Money API
+
+#### **assets()**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/get_v0-2-info-assets)
+
+This function returns a list of supported assets
+
+_Returns_: The response from the Chi Money API
+
+#### **banks(country)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/get_v0-2-info-country-banks)
+
+_Returns_: The response from Chi Money API
+
+| Param   | Type                | Default                     | Description                               |
+| ------- | ------------------- | --------------------------- | ----------------------------------------- |
+| country | <code>string</code> | <code>&quot;NG&quot;</code> | The country code, default is Nigeria(NG). |
+
+#### **localAmountInUSD(originCurrency, amountInOriginCurrency)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/get_v0-2-info-local-amount-in-usd)
+
+This function returns the equivalent of local currency in USD
+
+_Returns_: The response from the Chi Money API
+
+| Param                  | Type                | Description                       |
+| ---------------------- | ------------------- | --------------------------------- |
+| originCurrency         | <code>string</code> | The source currency               |
+| amountInOriginCurrency | <code>number</code> | The amount in the origin currency |
+
+#### **mobileMoneyCodes()**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/get_v0-2-info-mobile-money-codes)
+
+This function returns a list of supported mobile money codes
+
+_Returns_: The response from the Chi Money API
+
+#### **usdInLocalAmount(destinationCurrency, amountInUSD)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/get_v0-2-info-usd-amount-in-local)
+
+This function returns the equivalent of USD in the destination currency.
+
+_Returns_: The response from the Chi Money API
+
+| Param               | Type                | Description              |
+| ------------------- | ------------------- | ------------------------ |
+| destinationCurrency | <code>string</code> | The destination currency |
+| amountInUSD         | <code>number</code> | The amount in USD        |
+
+#### Using the MobileMoney API
+
+```js
+const { mobileMoney } = require("chimoneyjs")();
+```
+
+#### **getAllTransactions(subAccount**)
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-collections-mobile-money-all)
+
+This function returns an array of all mobile money(momo) transactions
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### **makePayment(paymentDetails, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-collections-mobile-money-collect)
+
+This function enables a user to make payment with mobile money (momo)
+
+_Returns_: The response from the Chi Money API
+
+| Param          | Type                | Default           | Description                                    |
+| -------------- | ------------------- | ----------------- | ---------------------------------------------- |
+| paymentDetails | <code>Object</code> |                   | An object with the appropriate payment details |
+| subAccount     | <code>string</code> | <code>null</code> | The subAccount of the transaction              |
+
+#### **verifyPayment(id, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-collections-mobile-money-verify)
+
+This function enables the user to verify mobile money payments
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| id         | <code>string</code> |                   | The transaction id                |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### Using the Payouts API
+
+```js
+const { payouts } = require("chimoneyjs")();
+```
+
+#### **airtime(airtimes, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-payouts-airtime)
+
+This function handles the Chi Money airtime API.
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                              | Default           | Description                                       |
+| ---------- | --------------------------------- | ----------------- | ------------------------------------------------- |
+| airtimes   | <code>Array.&lt;object&gt;</code> |                   | An array of object containing the airtime details |
+| subAccount | <code>string</code>               | <code>null</code> | The subAccount of the transaction                 |
+
+**Example**
+
+```js
+const airtimes = [
+  {
+    countryToSend: "Nigeria",
+    phoneNumber: "+2348123456789",
+    valueInUSD: 3,
+  },
+];
+```
+
+#### **bank(banks, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-payouts-bank)
+
+This function handles the bank API
+
+_Returns_: The response from Chi Money API
+
+| Param      | Type                              | Default           | Description                                     |
+| ---------- | --------------------------------- | ----------------- | ----------------------------------------------- |
+| banks      | <code>Array.&lt;object&gt;</code> |                   | An array of objects containing the bank details |
+| subAccount | <code>string</code>               | <code>null</code> | The subAccount of the transaction               |
+
+**Example**
+
+```js
+const banks = [
+  {
+    countryToSend: "Nigeria",
+    account_bank: "044",
+    account_number: "0690000031",
+    valueInUSD: 1,
+    reference: "1234567890",
+  },
+];
+```
+
+#### **chimoney(chimoneys, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-payouts-chimoney)
+
+This functions handles the chimoney API
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                              | Default           | Description                                          |
+| ---------- | --------------------------------- | ----------------- | ---------------------------------------------------- |
+| chimoneys  | <code>Array.&lt;object&gt;</code> |                   | An array of objects containing the chimoney details. |
+| subAccount | <code>string</code>               | <code>null</code> | The subAccount of the transaction                    |
+
+**Example**
+
+```js
+const chimoneys = [
+  {
+    valueInUSD: 1,
+    email: "text@example.com",
+    twitter: "@tester",
+  },
+];
+```
+
+#### **mobileMoney(momos, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-payouts-mobile-money)
+
+This function handles mobile money API
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                              | Default           | Description                                             |
+| ---------- | --------------------------------- | ----------------- | ------------------------------------------------------- |
+| momos      | <code>Array.&lt;object&gt;</code> |                   | An array of objects containing the mobile money details |
+| subAccount | <code>string</code>               | <code>null</code> | The subAccount of the transaction                       |
+
+**Example**
+
+```js
+const momos = [
+  {
+    countryToSend: "Nigeria",
+    phoneNumber: "+2348123456789",
+    valueInUSD: 1,
+    reference: "1234567890",
+  },
+];
+```
+
+#### **giftCard(giftCards, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-payouts-gift-card)
+
+This function handles the gift card API
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                              | Default           | Description                                          |
+| ---------- | --------------------------------- | ----------------- | ---------------------------------------------------- |
+| giftCards  | <code>Array.&lt;object&gt;</code> |                   | An array of objects containing the gift card details |
+| subAccount | <code>string</code>               | <code>null</code> | The subAccount of the transaction                    |
+
+**Example**
+
+```js
+const giftCards = [
+  {
+    email: "test@example.com",
+    valueInUSD: 1,
+    redeemData: {
+      productId: "3",
+      countryCode: "NG",
+      valueInLocalCurrency: 1000,
+    },
+  },
+];
+```
+
+#### **status(chiRef, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-payouts-status)
+
+This function handles the status API
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| chiRef     | <code>string</code> |                   | The Chi Money reference           |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### **initiateChimoney(chimoneys, crypto_payments, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-payouts-initiate-chimoney)
+
+This function handles the initiate chimoney API
+
+_Returns_: The response from the Chi Money API
+
+| Param               | Type                              | Default            | Description                                                |
+| ------------------- | --------------------------------- | ------------------ | ---------------------------------------------------------- |
+| chimoneys           | <code>Array.&lt;object&gt;</code> |                    | An array of objects containing the chimoney details        |
+| turnOffNotification | <code>boolean</code>              | <code>false</code> | If set to true turns of email notification for this payout |
+| crypto_payments     | <code>Array.&lt;object&gt;</code> |                    | An array of objects containing the crypto payment details  |
+| subAccount          | <code>string</code>               | <code>null</code>  | The subAccount of the transaction                          |
+
+**Example**
+
+```js
+const chimoneys = [
+  {
+    valueInUSD: 1,
+    email: "text@example.com",
+    twitter: "@tester",
+  },
+];
+```
+
+**Example**
+
+```js
+const crypto_payments = [
+  {
+    xrpl: {
+      address: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
+      issuer: "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
+      currency: "XRP",
+    },
+  },
+];
+```
+
+#### Using the Redeem API
+
+```js
+const { redeem } = require("chimoneyjs")();
+```
+
+#### **airtime(chiRef, phoneNumber, countryToSend, meta, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-redeem-airtime)
+
+This function allows you to redeem airtime transactions
+
+_Returns_: The response from the Chi Money API
+
+| Param         | Type                | Default           | Description                           |
+| ------------- | ------------------- | ----------------- | ------------------------------------- |
+| chiRef        | <code>string</code> |                   | The Chi reference                     |
+| phoneNumber   | <code>string</code> |                   | Phone number                          |
+| countryToSend | <code>string</code> |                   | Country to send to                    |
+| meta          | <code>object</code> |                   | Any data to be sent along the request |
+| subAccount    | <code>string</code> | <code>null</code> | The subAccount of the transaction     |
+
+#### **any(chiRef, redeemData, [meta], subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-redeem-any)
+
+This function allows you to redeem any transaction (chimoney, momo, airtime)
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                              | Default           | Description                                                                              |
+| ---------- | --------------------------------- | ----------------- | ---------------------------------------------------------------------------------------- |
+| chiRef     | <code>string</code>               |                   | The Chi reference                                                                        |
+| redeemData | <code>array.&lt;object&gt;</code> |                   | Any array of objects containing data needed to redeem the transaction. see example below |
+| [meta]     | <code>object</code>               | <code>{}</code>   | Any data to be sent along with the request. defaults to an empty object                  |
+| subAccount | <code>string</code>               | <code>null</code> | The subAccount of the transaction                                                        |
+
+**Example**
+
+```js
+const redeemData = [
+  {
+    countryCode: "NG",
+    productId: 1,
+    valueInLocalCurrency: 1000,
+  },
+];
+```
+
+#### **chimoney(chimoneys, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-redeem-chimoney)
+
+This function allows you to redeem chimoney
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                              | Default           | Description                                       |
+| ---------- | --------------------------------- | ----------------- | ------------------------------------------------- |
+| chimoneys  | <code>array.&lt;object&gt;</code> |                   | An array of objects containing the redeem details |
+| subAccount | <code>string</code>               | <code>null</code> | The subAccount of the transaction                 |
+
+**Example**
+
+```js
+const chimoneys = [
+  {
+    field: "data",
+  },
+];
+```
+
+#### **giftCard(chiRef, redeemOptions, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-redeem-gift-card)
+
+This function allows you to redeem giftcard
+
+_Returns_: The response from the Chi Money API
+
+| Param         | Type                | Default           | Description                               |
+| ------------- | ------------------- | ----------------- | ----------------------------------------- |
+| chiRef        | <code>string</code> |                   | The Chi reference                         |
+| redeemOptions | <code>object</code> |                   | The data needed to redeem the transaction |
+| subAccount    | <code>string</code> | <code>null</code> | The subAccount of the transaction         |
+
+#### **mobileMoney(chiRef, redeemOptions, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-redeem-mobile-money)
+
+This function allows you to redeem mobile money (momo)
+
+_Returns_: The response from the Chi Money API
+
+| Param         | Type                | Default           | Description                               |
+| ------------- | ------------------- | ----------------- | ----------------------------------------- |
+| chiRef        | <code>string</code> |                   | The Chi reference                         |
+| redeemOptions | <code>object</code> |                   | The data needed to redeem the transaction |
+| subAccount    | <code>string</code> | <code>null</code> | The subAccount of the transaction         |
+
+#### Using the SubAccount API
+
+```js
+const { subAccount } = require("chimoneyjs")();
+```
+
+#### **create(name, email)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-sub-account-create)
+
+This function creates a new subAccount with the provided name and email
+
+_Returns_: The response from the Chi Money API
+
+| Param | Type                | Description                     |
+| ----- | ------------------- | ------------------------------- |
+| name  | <code>string</code> | Name to give the new subAccount |
+| email | <code>string</code> | Email                           |
+
+<a name="deleteAccount"></a>
+
+#### **deleteAccount(id)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/delete_v0-2-sub-account-delete)
+
+This function deletes the subAccount with the given id
+
+_Returns_: The response from the Chi Money API
+
+| Param | Type                | Description              |
+| ----- | ------------------- | ------------------------ |
+| id    | <code>string</code> | The id of the subAccount |
+
+#### **getDetails(id)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/get_v0-2-sub-account-get)
+
+This function gets the details of the subAccount with the associated id
+
+_Returns_: The response from the Chi Money API
+
+| Param | Type                | Description              |
+| ----- | ------------------- | ------------------------ |
+| id    | <code>string</code> | The id of the subAccount |
+
+#### **getAll()**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/get_v0-2-sub-account-list)
+
+This function returns all the subAccounts associated with a user
+
+_Returns_: The response from the Chi Money API
+
+#### Using the Wallet API
+
+```js
+const { wallet } = require("chimoneyjs")();
+```
+
+#### **list(subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-wallets-list)
+
+This function gets all the wallets associated with a user
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### **details(id, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-wallets-lookup)
+
+This function gets the details associated with a single user wallet
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Default           | Description                       |
+| ---------- | ------------------- | ----------------- | --------------------------------- |
+| id         | <code>string</code> |                   | The wallet id                     |
+| subAccount | <code>string</code> | <code>null</code> | The subAccount of the transaction |
+
+#### **transfer(receiver, wallet, amount, subAccount)**
+
+For more information visit [Chi Money API](https://chimoney.readme.io/reference/post_v0-2-wallets-transfer)
+
+This function lets you transfer funds to receiver
+
+_Returns_: The response from the Chi Money API
+
+| Param      | Type                | Description                                      |
+| ---------- | ------------------- | ------------------------------------------------ |
+| receiver   | <code>string</code> | The receiver id                                  |
+| wallet     | <code>string</code> | The wallet type                                  |
+| amount     | <code>number</code> | The amount of funds to be transferred in dollars |
+| subAccount | <code>string</code> | The subAccount of the transaction                |
+
+### **Errors**
+
+There are four main types of errors throw by the **chimoneyjs** package.
+
+- **ValueError**: Missing required function parameter(s)
+- **TypeError**: Parameter with a wrong type was passed into a function.
+- **ChiMoneyError**: Error with the request sent to the Chi Money API. This is as a result of invalid data being sent to the Chi Money server.
+- **AuthKeyError**: This occurs when the API wasn't set.


Test patch:
diff --git a/submissions/chimoney-js/tests/account.test.js b/submissions/chimoney-js/tests/account.test.js
index 90aab488..43c66ac9 100644
--- a/submissions/chimoney-js/tests/account.test.js
+++ b/submissions/chimoney-js/tests/account.test.js
@@ -6,7 +6,7 @@ const issuerId = "f7d68f1f-3637-47a7-8db5-d69091986b27";
 const unpaidTransactionChiRef = "bcb71e77-b33d-4fc2-879e-52adb61e65f0";
 const receiverId = "qkCUiLgevEhUYbGenSiZgVisjLc2";
 
-describe("Test Account module", () => {
+describe("Account", () => {
   test("getAllTransactions: should successfully return all transactions on account from Chi Money API", async () => {
     const response = await account.getAllTransactions();
 
diff --git a/submissions/chimoney-js/tests/info.test.js b/submissions/chimoney-js/tests/info.test.js
index 3684aa88..f1591882 100644
--- a/submissions/chimoney-js/tests/info.test.js
+++ b/submissions/chimoney-js/tests/info.test.js
@@ -3,7 +3,7 @@ const { ValueError } = require("../Errors");
 require("dotenv").config();
 const { info } = require("../index")(process.env.TEST_API_KEY);
 
-describe("Test Info module", () => {
+describe("Info", () => {
   test("assets: should successfully return assests from Chi Money API", async () => {
     const response = await info.assets();
 
diff --git a/submissions/chimoney-js/tests/mobileMoney.test.js b/submissions/chimoney-js/tests/mobileMoney.test.js
new file mode 100644
index 00000000..5a78f735
--- /dev/null
+++ b/submissions/chimoney-js/tests/mobileMoney.test.js
@@ -0,0 +1,53 @@
+const { ValueError, ChiMoneyError } = require("../Errors");
+
+require("dotenv").config();
+const { mobileMoney } = require("../index")();
+
+describe("MobileMoney", () => {
+  test("makePayment: should return throw value error", async () => {
+    try {
+      await mobileMoney.makePayment();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("makePayment: should return throw Chi Money error", async () => {
+    try {
+      await mobileMoney.makePayment({
+        amount: 2,
+        currency: "NGN",
+        fullname: "somegug",
+        email: "fake_email",
+        country: "NG",
+        phone_number: "fakenumber",
+        tx_ref: "fakeref",
+      });
+    } catch (error) {
+      expect(error).toBeInstanceOf(ChiMoneyError);
+    }
+  });
+
+  test("getAllTransactions: should get all transactions", async () => {
+    const response = await mobileMoney.getAllTransactions();
+
+    expect(response.status).toBe("success");
+    expect(response.data).toBeDefined();
+  });
+
+  test("verifyPayment: should throw value error", async () => {
+    try {
+      await mobileMoney.verifyPayment();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("verifyPayment: should throw Chi Money Error", async () => {
+    try {
+      await mobileMoney.verifyPayment("fakeid");
+    } catch (error) {
+      expect(error).toBeInstanceOf(ChiMoneyError);
+    }
+  });
+});
diff --git a/submissions/chimoney-js/tests/payouts.test.js b/submissions/chimoney-js/tests/payouts.test.js
index 6b266dd7..d88586c4 100644
--- a/submissions/chimoney-js/tests/payouts.test.js
+++ b/submissions/chimoney-js/tests/payouts.test.js
@@ -2,7 +2,7 @@ const { ValueError, ChiMoneyError } = require("../Errors");
 require("dotenv").config();
 const { payouts } = require("../index")(process.env.TEST_API_KEY);
 
-describe("Test Payouts module", () => {
+describe("Payouts", () => {
   test("airtime: should return error from Chi Money", async () => {
     try {
       await payouts.airtime();
diff --git a/submissions/chimoney-js/tests/redeem.test.js b/submissions/chimoney-js/tests/redeem.test.js
new file mode 100644
index 00000000..ec373ee4
--- /dev/null
+++ b/submissions/chimoney-js/tests/redeem.test.js
@@ -0,0 +1,84 @@
+const { ValueError, ChiMoneyError, TypeError } = require("../Errors");
+const { redeem } = require("../index")();
+
+describe("Redeem", () => {
+  test("airtime: should return throw value error", async () => {
+    try {
+      await redeem.airtime();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("airtime: should return throw Chi Money error", async () => {
+    try {
+      await redeem.airtime("testprevious", "test", "test");
+    } catch (error) {
+      expect(error).toBeInstanceOf(ChiMoneyError);
+    }
+  });
+
+  test("any: should throw Chi Money Error", async () => {
+    try {
+      await redeem.any("test", []);
+    } catch (error) {
+      expect(error).toBeInstanceOf(ChiMoneyError);
+    }
+  });
+
+  test("any: should throw value error", async () => {
+    try {
+      await redeem.any();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("chimoney: should throw Chi Money Error", async () => {
+    try {
+      await redeem.chimoney([]);
+    } catch (error) {
+      expect(error).toBeInstanceOf(ChiMoneyError);
+    }
+  });
+
+  test("chimoney: should throw value error", async () => {
+    try {
+      await redeem.chimoney();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("mobileMoney: should throw Chi Money Error", async () => {
+    try {
+      await redeem.mobileMoney("testref", {});
+    } catch (error) {
+      expect(error).toBeInstanceOf(ChiMoneyError);
+    }
+  });
+
+  test("mobileMoney: should throw value error", async () => {
+    try {
+      await redeem.mobileMoney();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("giftCard: should throw Chi Money Error", async () => {
+    try {
+      await redeem.giftCard("testref", {});
+    } catch (error) {
+      expect(error).toBeInstanceOf(ChiMoneyError);
+    }
+  });
+
+  test("mobileMoney: should throw value error", async () => {
+    try {
+      await redeem.giftCard();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+});
diff --git a/submissions/chimoney-js/tests/subAccount.test.js b/submissions/chimoney-js/tests/subAccount.test.js
new file mode 100644
index 00000000..96b33279
--- /dev/null
+++ b/submissions/chimoney-js/tests/subAccount.test.js
@@ -0,0 +1,55 @@
+const { ValueError } = require("../Errors");
+const { subAccount } = require("../index")();
+const testEmail = "test@example.com"; // Place your test email here
+const testId = "yourtestid"; // Place your test id here
+const testDeleteId = "yourdeletetestid"; // Test id of subAccount to be deleted
+
+describe("SubAccount", () => {
+  test("create: should successfully create a new subAccount", async () => {
+    const response = await subAccount.create("mysub", testEmail);
+    expect(response.data).toBeDefined();
+    expect(response.status).toBe("success");
+  });
+
+  test("create: should throw value error", async () => {
+    try {
+      await subAccount.create();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("getAll: should successfully return data from Chi Money API", async () => {
+    const response = await subAccount.getAll();
+    expect(response.data).toBeDefined();
+    expect(response.status).toBe("success");
+  });
+
+  test("getDetails: should successfully get details of single subAccount from Chi Money", async () => {
+    const response = await subAccount.getDetails(testId);
+    expect(response.data).toBeDefined();
+    expect(response.status).toBe("success");
+  });
+
+  test("getDetails: should throw value error for invalid inputs", async () => {
+    try {
+      await subAccount.getDetails();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("deleteAccount: should successfully delete SubAccount of single subAccount from Chi Money", async () => {
+    const response = await subAccount.deleteAccount(testDeleteId);
+    expect(response.data).toBeDefined();
+    expect(response.status).toBe("success");
+  });
+
+  test("deleteAccount: should throw value error for invalid inputs", async () => {
+    try {
+      await subAccount.deleteAccount();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+});
diff --git a/submissions/chimoney-js/tests/wallet.test.js b/submissions/chimoney-js/tests/wallet.test.js
new file mode 100644
index 00000000..55f35d64
--- /dev/null
+++ b/submissions/chimoney-js/tests/wallet.test.js
@@ -0,0 +1,41 @@
+const { ValueError, ChiMoneyError, TypeError } = require("../Errors");
+require("dotenv").config();
+const { wallet } = require("../index")();
+const testWalletId = "yourtestwalletid"; // Place your test wallet id here
+const testReceiver = "yourtestreceiverid"; // Place your test receiver id here
+
+describe("Wallet", () => {
+  test("list: should successfully return data from Chi Money API", async () => {
+    const response = await wallet.list();
+    expect(response.data).toBeDefined();
+    expect(response.status).toBe("success");
+  });
+
+  test("details: should successfully return data from Chi Money API", async () => {
+    const response = await wallet.details(testWalletId);
+    expect(response.data).toBeDefined();
+    expect(response.status).toBe("success");
+  });
+
+  test("details: should throw value error", async () => {
+    try {
+      await wallet.details();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+
+  test("transfer: should successfully transfer funds to receiver using Chi Money API", async () => {
+    const response = await wallet.transfer(testReceiver, "chi", 2);
+    expect(response.data).toBeDefined();
+    expect(response.status).toBe("success");
+  });
+
+  test("transfer: should throw value error for invalid inputs", async () => {
+    try {
+      await wallet.transfer();
+    } catch (error) {
+      expect(error).toBeInstanceOf(ValueError);
+    }
+  });
+});