<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[kennedy Daniel's blog]]></title><description><![CDATA[kennedy Daniel's blog]]></description><link>https://kennoxx.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 10:27:55 GMT</lastBuildDate><atom:link href="https://kennoxx.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to deposit money to your wallet and use the money to pay bills with flutterwave in a Node.js application]]></title><description><![CDATA[Prerequisites

Good understanding of JavaScript

MongoDB

Node.js

How to use Postman

Flutterwave account

Basic react.js


Flutterwave:
Flutterwave is a financial technology company. It provides a platform that enables businesses and individuals to...]]></description><link>https://kennoxx.hashnode.dev/how-to-deposit-money-to-your-wallet-and-use-the-money-to-pay-bills-with-flutterwave-in-a-nodejs-application</link><guid isPermaLink="true">https://kennoxx.hashnode.dev/how-to-deposit-money-to-your-wallet-and-use-the-money-to-pay-bills-with-flutterwave-in-a-nodejs-application</guid><category><![CDATA[flutterwave]]></category><category><![CDATA[fintech]]></category><category><![CDATA[Mobile Wallet]]></category><dc:creator><![CDATA[kennedy Daniel]]></dc:creator><pubDate>Tue, 26 Sep 2023 09:33:42 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p>Good understanding of JavaScript</p>
</li>
<li><p>MongoDB</p>
</li>
<li><p>Node.js</p>
</li>
<li><p>How to use Postman</p>
</li>
<li><p>Flutterwave account</p>
</li>
<li><p>Basic react.js</p>
</li>
</ul>
<h2 id="heading-flutterwave">Flutterwave:</h2>
<p>Flutterwave is a financial technology company. It provides a platform that enables businesses and individuals to make and accept payments. Flutterwave offers a wide range of payment solutions, including online card payments, mobile money, bank transfers, and more.</p>
<p>We are going to use Flutterwave APIs to build a bill-paying application.</p>
<h3 id="heading-getting-started">Getting Started</h3>
<p>Open your terminal or command prompt and navigate to the directory where you want to create your project. Then, run the following command to create a new directory for your project:</p>
<pre><code class="lang-javascript">mkdir wallet-demo-<span class="hljs-keyword">with</span>-flutterwave-backend
cd wallet-demo-<span class="hljs-keyword">with</span>-flutterwave-backend
</code></pre>
<p>Inside your project directory, you need to initialize a Node.js project using the following command:</p>
<pre><code class="lang-javascript">npm init
</code></pre>
<p>This command will guide you through setting up your project by asking a series of questions. You can press Enter to accept the default values or provide your own.</p>
<h3 id="heading-installing-some-packages">Installing some packages</h3>
<p>Make sure you are in the wallet-demo-with-flutterwave-backend directory. To install some packages write the following command:</p>
<pre><code class="lang-javascript">npm i axios bcryptjs dotenv express jsonwebtoken cors mongoose nodemon
</code></pre>
<p><code>nodemon</code> is a utility that monitors changes in your Node.js application's source files and automatically restarts the application when changes are detected.</p>
<p>Create a folder in the root directory called <code>src</code>, in the <code>src</code> folder, create 5 folders named config, controllers, models, routes, and middleware. Also, create the index.js and .env files in the root directory.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692743571907/f6fe125f-d972-4968-a7e8-475a3bf0735b.png" alt /></p>
<h3 id="heading-connecting-database-and-creating-nodejs-server">Connecting Database and Creating Node.js Server</h3>
<p>In the .env file</p>
<pre><code class="lang-javascript">PORT = <span class="hljs-number">3000</span>
MONGO = <span class="hljs-comment">// Mongodb uri</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> env = <span class="hljs-built_in">require</span>(<span class="hljs-string">"dotenv"</span>);

<span class="hljs-built_in">require</span>(<span class="hljs-string">"./src/config/database"</span>).connect();
<span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> app = express()

app.use(express.json());

env.config()


<span class="hljs-keyword">const</span> { PORT } = process.env;
<span class="hljs-keyword">const</span> port = process.env.PORT || PORT;

<span class="hljs-comment">// server listening</span>
app.listen(port, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server running on port <span class="hljs-subst">${port}</span>`</span>);
});
</code></pre>
<p>in the database file:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);

<span class="hljs-keyword">const</span> { MONGO } = process.env;

<span class="hljs-built_in">exports</span>.connect = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">//connecting database</span>
  mongoose
    .connect(MONGO, {
      <span class="hljs-attr">useNewUrlParser</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">useUnifiedTopology</span>: <span class="hljs-literal">true</span>,
    })
    .then(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"connected to database"</span>);
    })
    .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"connection failed"</span>);
      <span class="hljs-built_in">console</span>.error(error);
    });
};
</code></pre>
<p>Let's start our server by editing the script on the package.json.</p>
<pre><code class="lang-javascript">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"start"</span>: <span class="hljs-string">"node index.js"</span>,
    <span class="hljs-string">"dev"</span>: <span class="hljs-string">"nodemon index.js"</span>,
    <span class="hljs-string">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>
  },
</code></pre>
<p>In the terminal type <code>npm run dev</code> then our server starts running and shows <em>connected to database</em>.</p>
<h3 id="heading-creating-the-user-database">Creating the User Database</h3>
<p>We will create a user database that stores user information like <code>email</code> and hash_password, <code>first_name</code> and <code>last_name</code></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);


<span class="hljs-keyword">const</span> userSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">first_name</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">default</span>: <span class="hljs-literal">null</span> },
    <span class="hljs-attr">last_name</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">default</span>: <span class="hljs-literal">null</span> },
    <span class="hljs-attr">email</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>, <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span> },
    <span class="hljs-attr">hash_password</span>: { <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span> },
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
  }
);

userSchema.methods = {
<span class="hljs-comment">//create a function that will take password as a parameter</span>
  <span class="hljs-attr">authenticate</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">password</span>) </span>{
<span class="hljs-comment">//compare the password with the hash_password</span>
    <span class="hljs-keyword">return</span> bcrypt.compare(password, <span class="hljs-built_in">this</span>.hash_password);
  },
};


<span class="hljs-built_in">module</span>.exports = mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
</code></pre>
<p>Let's create a file in the controller folder called user, to handle the logging-in and authentication.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/user"</span>);
<span class="hljs-keyword">const</span> bcrypt = <span class="hljs-built_in">require</span>(<span class="hljs-string">"bcryptjs"</span>);
<span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">"jsonwebtoken"</span>);


<span class="hljs-built_in">exports</span>.signup = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-comment">// check if user already exists</span>
  User.findOne({ <span class="hljs-attr">email</span>: req.body.email }).exec(<span class="hljs-keyword">async</span> (err, user) =&gt; {
    <span class="hljs-keyword">if</span> (user) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">msg</span>: <span class="hljs-string">"user already exist"</span> });
    <span class="hljs-built_in">console</span>.log(req)
    <span class="hljs-comment">//get the user data from req.body</span>
    <span class="hljs-keyword">const</span> { first_name, last_name, email, password } = req.body;
    <span class="hljs-comment">//hash the password</span>
    <span class="hljs-keyword">const</span> hash_password = <span class="hljs-keyword">await</span> bcrypt.hash(password, <span class="hljs-number">10</span>);
    <span class="hljs-comment">// create new user</span>
    <span class="hljs-keyword">const</span> _user = <span class="hljs-keyword">new</span> User({
      first_name,
      last_name,
      email,
      hash_password,
    });

    _user.save(<span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ err });
      <span class="hljs-keyword">if</span> (data)
        <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">201</span>).json({ <span class="hljs-attr">user</span>: <span class="hljs-string">"user created successsfully"</span> });
    });
  });
};
</code></pre>
<p>Code to login in user:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">exports</span>.signin = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
<span class="hljs-comment">//check if the email gotten from the user is the same with the eamil in the database</span>
  User.findOne({ <span class="hljs-attr">email</span>: req.body.email }).exec(<span class="hljs-keyword">async</span> (err, user) =&gt; {
    <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ err });
    <span class="hljs-keyword">if</span> (user) {
      <span class="hljs-built_in">console</span>.log(user)
<span class="hljs-comment">//pass the password to the authentication function that we created in the model page</span>
      <span class="hljs-keyword">const</span> promise = <span class="hljs-keyword">await</span> user.authenticate(req.body.password);

      <span class="hljs-keyword">if</span> (promise) {
        <span class="hljs-keyword">const</span> token = jwt.sign(
          { <span class="hljs-attr">_id</span>: user._id },
          process.env.TOKEN,
          {}
        );
        <span class="hljs-keyword">const</span> { _id, first_name, last_name, email, } = user;
        res.status(<span class="hljs-number">200</span>).json({
          token,
          <span class="hljs-attr">user</span>: { _id, first_name, last_name, email, },
        });
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">msg</span>: <span class="hljs-string">"invalid password"</span> });
      }
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">msg</span>: <span class="hljs-string">"something went wrong"</span> });
    }
  });
};
</code></pre>
<p>Add the <code>TOKEN</code> to your env file</p>
<p>Go to the route folder and create a file <code>user.js</code> , paste the code below in file,</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> { signup, signin  } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controllers/user"</span>);
<span class="hljs-keyword">const</span> router = express.Router();


router.post(<span class="hljs-string">"/register"</span> ,signup) ;
router.post(<span class="hljs-string">"/signin"</span>, signin);

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<p>Go to your index.js file and import the user.js route</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> userRoute = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./src/routes/user'</span>)

app.use(<span class="hljs-string">'/api'</span>, userRoute)
</code></pre>
<p>Go to Postman and try the sign in and register</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692801950846/167b1c38-8d30-443d-b5d8-1751c531f645.png" alt /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692802116967/2ac9869e-138a-43e0-8d57-f81f70462413.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-middleware-for-protected-routes">Middleware for Protected Routes</h3>
<p>After sign in a token is always generated... if a user is not signed in we need middleware to protect the route.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">"jsonwebtoken"</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>)

<span class="hljs-built_in">exports</span>.requireSignin = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (req.headers.authorization) {
    <span class="hljs-keyword">const</span> token = req.headers.authorization.split(<span class="hljs-string">" "</span>)[<span class="hljs-number">1</span>];
    <span class="hljs-keyword">const</span> user = jwt.verify(token, process.env.TOKEN_KEY);
    req.user = user;
  } <span class="hljs-keyword">else</span> {
    res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">msg</span>: <span class="hljs-string">"not authorized"</span> });
  }

  next();
};
</code></pre>
<p>in the route folder create a file for transactions and wallet. this 2 route are going to be protected.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> {
  transactionResponce,
  getTranSAction,
} = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controllers/transactions"</span>);
<span class="hljs-keyword">const</span> { requireSignin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../middleware"</span>);
<span class="hljs-keyword">const</span> router = express.Router();

router.get(<span class="hljs-string">"/response"</span>, transactionResponce);
router.get(<span class="hljs-string">"/gettransaction"</span>, requireSignin, getTranSAction);

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<p>getTransaction is a protected endpoint because only the user should be able to see his/her transactions. same with getWallet endpoint.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">"express"</span>);
<span class="hljs-keyword">const</span> { getWallet, updateWallet  } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../controllers/wallet"</span>);
<span class="hljs-keyword">const</span> router = express.Router();
<span class="hljs-keyword">const</span> { requireSignin } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../middleware/index"</span>);


router.get(<span class="hljs-string">"/wallet/balance"</span> ,requireSignin, getWallet) ;



<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<h3 id="heading-deposit-money-to-your-flutterwave-wallet">Deposit money to your Flutterwave wallet.</h3>
<p>Go to <a target="_blank" href="http://developer.flutterwave.com">Flutterwave documentation</a> to get your API keys</p>
<p>We are going to use react.js as the frontend js framework for this project. After installing react and setting it up, install Flutterwave in your react app <code>npm i flutterwave-react-v3</code>, then create a component.</p>
<p>create a transaction.js file in the model folder.</p>
<p><code>model/transaction.js</code></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> { Schema, model } = <span class="hljs-built_in">require</span>(<span class="hljs-string">"mongoose"</span>);

<span class="hljs-keyword">const</span> transactionSchema = Schema(
  {
    <span class="hljs-attr">userId</span>: {
      <span class="hljs-attr">type</span>: Schema.Types.ObjectId,
      <span class="hljs-attr">ref</span>: <span class="hljs-string">"user"</span>,
    },
    <span class="hljs-attr">transactionId</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">Number</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
    },
    <span class="hljs-attr">email</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"email is required"</span>],
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
    },
    <span class="hljs-attr">phone</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
    },
    <span class="hljs-attr">amount</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">Number</span>,
      <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"amount is required"</span>],
    },
    <span class="hljs-attr">currency</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"currency is required"</span>],
      <span class="hljs-attr">enum</span>: [<span class="hljs-string">"NGN"</span>],
    },
    <span class="hljs-attr">paymentStatus</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">enum</span>: [<span class="hljs-string">"successful"</span>, <span class="hljs-string">"pending"</span>, <span class="hljs-string">"failed"</span>],
      <span class="hljs-attr">default</span>: <span class="hljs-string">"pending"</span>,
    },
    <span class="hljs-attr">paymentGateway</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: [<span class="hljs-literal">true</span>, <span class="hljs-string">"payment gateway is required"</span>],
      <span class="hljs-attr">enum</span>: [<span class="hljs-string">"flutterwave"</span>], 
    },
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
  }
);

<span class="hljs-keyword">const</span> Transaction = model(<span class="hljs-string">"Transaction"</span>, transactionSchema);
<span class="hljs-built_in">module</span>.exports = Transaction;
</code></pre>
<p>controllers/transaction.js</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/user"</span>);
<span class="hljs-keyword">const</span> WalletTransaction = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/wallet_transaction"</span>);
<span class="hljs-keyword">const</span> Wallet = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/wallet"</span>);
<span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);
<span class="hljs-keyword">const</span> Transaction = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/transaction"</span>);


<span class="hljs-built_in">exports</span>.transactionResponce = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">const</span> { tx_ref } = req.query;
  <span class="hljs-built_in">console</span>.log(tx_ref);

  <span class="hljs-comment">// URL with transaction ID of which will be used to confirm transaction status</span>
  <span class="hljs-keyword">const</span> url = <span class="hljs-string">`https://api.flutterwave.com/v3/transactions/verify_by_reference?tx_ref=<span class="hljs-subst">${tx_ref}</span>`</span>;

  <span class="hljs-comment">// Network call to confirm transaction status</span>
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios({
    url,
    <span class="hljs-attr">method</span>: <span class="hljs-string">"get"</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
      <span class="hljs-attr">Accept</span>: <span class="hljs-string">"application/json"</span>,
      <span class="hljs-attr">Authorization</span>: <span class="hljs-string">`<span class="hljs-subst">${process.env.FLUTTERWAVE_V3_SECRET_KEY_TWO}</span>`</span>,
    },
  });

  <span class="hljs-keyword">const</span> { status, currency, id, amount, customer } = response.data.data;
  <span class="hljs-comment">// console.log(response.data.data);</span>

  <span class="hljs-comment">// check if transaction id already exist</span>

  <span class="hljs-keyword">const</span> transactionExist = <span class="hljs-keyword">await</span> Transaction.findOne({ <span class="hljs-attr">transactionId</span>: id });

  <span class="hljs-keyword">if</span> (transactionExist) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">409</span>).send(<span class="hljs-string">"Transaction Already Exist"</span>);
  }
  <span class="hljs-comment">// check if customer exist in our database</span>
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">email</span>: customer.email });
  <span class="hljs-built_in">console</span>.log(amount); 
  <span class="hljs-built_in">console</span>.log(customer.email);
};
</code></pre>
<p>In the above code snippet, we want to get the <code>tx_ref</code> from our query after a successful transaction and pass it to the flutterwave URL to get the status, currency, id, amount and customer. If the transaction exists then the user will be notified.</p>
<p>We check if the customer exists in our database via the customer's email.</p>
<h2 id="heading-check-if-the-user-has-a-wallet">Check if the user has a Wallet</h2>
<p>Next, we check if the user has a wallet if the user has we create a transaction and save it to the database, if the user does not have a wallet we create a wallet.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/user"</span>);
<span class="hljs-keyword">const</span> WalletTransaction = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/wallet_transaction"</span>);
<span class="hljs-keyword">const</span> Wallet = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/wallet"</span>);
<span class="hljs-keyword">const</span> axios = <span class="hljs-built_in">require</span>(<span class="hljs-string">"axios"</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">"path"</span>);
<span class="hljs-keyword">const</span> Transaction = <span class="hljs-built_in">require</span>(<span class="hljs-string">"../model/transaction"</span>);

<span class="hljs-keyword">const</span> validateUserWallet = <span class="hljs-keyword">async</span> (userId) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// check if user have a wallet, else create wallet</span>
    <span class="hljs-keyword">const</span> userWallet = <span class="hljs-keyword">await</span> Wallet.findOne({ userId });

    <span class="hljs-keyword">if</span> (!userWallet) {
      <span class="hljs-comment">// create wallet</span>
      <span class="hljs-keyword">const</span> wallet = <span class="hljs-keyword">await</span> Wallet.create({
        userId,
      });
      <span class="hljs-keyword">return</span> wallet;
    }
    <span class="hljs-keyword">return</span> userWallet;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.log(error);
  }
};

<span class="hljs-keyword">const</span> createWalletTransaction = <span class="hljs-keyword">async</span> (userId, status, currency, amount) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// create wallet transaction</span>
    <span class="hljs-keyword">const</span> walletTransaction = <span class="hljs-keyword">await</span> WalletTransaction.create({
      amount,
      userId,
      <span class="hljs-attr">isInflow</span>: <span class="hljs-literal">true</span>,
      currency,
      status,
    });
    <span class="hljs-keyword">return</span> walletTransaction;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.log(error);
  }
};

<span class="hljs-keyword">const</span> createTransaction = <span class="hljs-keyword">async</span> (
  userId,
  id,
  status,
  currency,
  amount,
  customer
) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// create transaction</span>
    <span class="hljs-keyword">const</span> transaction = <span class="hljs-keyword">await</span> Transaction.create({
      userId,
      <span class="hljs-attr">transactionId</span>: id,
      <span class="hljs-attr">name</span>: customer.name,
      <span class="hljs-attr">email</span>: customer.email,
      <span class="hljs-attr">phone</span>: customer.phone_number,
      amount,
      currency,
      <span class="hljs-attr">paymentStatus</span>: status,
      <span class="hljs-attr">paymentGateway</span>: <span class="hljs-string">"flutterwave"</span>,
    });
    <span class="hljs-keyword">return</span> transaction;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-comment">// console.log(error);</span>
  }
};

<span class="hljs-keyword">const</span> updateWallet = <span class="hljs-keyword">async</span> (userId, amount) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// update wallet</span>
    <span class="hljs-keyword">const</span> wallet = <span class="hljs-keyword">await</span> Wallet.findOneAndUpdate(
      { userId },
      { <span class="hljs-attr">$inc</span>: { <span class="hljs-attr">balance</span>: amount } },
      { <span class="hljs-attr">new</span>: <span class="hljs-literal">true</span> }
    );
    <span class="hljs-keyword">return</span> wallet;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-comment">// console.log(error);</span>
  }
};

<span class="hljs-built_in">exports</span>.transactionResponce = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">const</span> { transaction_id, tx_ref } = req.query;
  <span class="hljs-built_in">console</span>.log(tx_ref);

  <span class="hljs-comment">// URL with transaction ID of which will be used to confirm transaction status</span>
  <span class="hljs-keyword">const</span> url = <span class="hljs-string">`https://api.flutterwave.com/v3/transactions/verify_by_reference?tx_ref=<span class="hljs-subst">${tx_ref}</span>`</span>;

  <span class="hljs-comment">// Network call to confirm transaction status</span>
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios({
    url,
    <span class="hljs-attr">method</span>: <span class="hljs-string">"get"</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
      <span class="hljs-attr">Accept</span>: <span class="hljs-string">"application/json"</span>,
      <span class="hljs-attr">Authorization</span>: <span class="hljs-string">`<span class="hljs-subst">${process.env.FLUTTERWAVE_V3_SECRET_KEY_TWO}</span>`</span>,
    },
  });

  <span class="hljs-keyword">const</span> { status, currency, id, amount, customer } = response.data.data;

  <span class="hljs-comment">// check if transaction id already exist</span>
  <span class="hljs-keyword">const</span> transactionExist = <span class="hljs-keyword">await</span> Transaction.findOne({ <span class="hljs-attr">transactionId</span>: id });

  <span class="hljs-keyword">if</span> (transactionExist) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">409</span>).send(<span class="hljs-string">"Transaction Already Exist"</span>);
  }
  <span class="hljs-comment">// check if customer exist in our database</span>
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">email</span>: customer.email });
  <span class="hljs-built_in">console</span>.log(amount); 
  <span class="hljs-built_in">console</span>.log(customer.email);

  <span class="hljs-comment">// check if user have a wallet, else create wallet</span>
  <span class="hljs-keyword">const</span> wallet = <span class="hljs-keyword">await</span> validateUserWallet(user._id);

  <span class="hljs-comment">// create wallet transaction</span>
  <span class="hljs-keyword">await</span> createWalletTransaction(user._id, status, currency, amount);

  <span class="hljs-comment">// create transaction</span>
  <span class="hljs-keyword">await</span> createTransaction(user._id, id, status, currency, amount, customer);

  <span class="hljs-keyword">await</span> updateWallet(user._id, amount);
  <span class="hljs-keyword">if</span> (wallet) {
    res.sendFile(path.join(__dirname + <span class="hljs-string">"/index.html"</span>));
  }



};

  <span class="hljs-built_in">exports</span>.getTranSAction = <span class="hljs-keyword">async</span> (req,res) =&gt; {
    <span class="hljs-keyword">const</span> bills = <span class="hljs-keyword">await</span> Transaction.find({<span class="hljs-attr">userId</span>:req.user._id});

    res.status(<span class="hljs-number">200</span>).json({
      <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
      bills,
    });
  }
</code></pre>
<p>In the snippet above we also upadated the wallet, to add to add to the amount in the wallet whenever there is a deposit</p>
<p>then we get transactions of a particular user from the database.</p>
<h2 id="heading-paying-bills-from-the-wallet">Paying Bills From The wallet</h2>
<p>get categories from flutterwave bill paying api, For more information visit the documentation <a target="_blank" href="https://developer.flutterwave.com/docs/making-payments/bill-payments/">https://developer.flutterwave.com/docs/making-payments/bill-payments/</a></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Get categories for different bills </span>

<span class="hljs-built_in">exports</span>.getDataCats = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">var</span> config = {
    <span class="hljs-attr">method</span>: <span class="hljs-string">"GET"</span>,
    <span class="hljs-attr">url</span>: <span class="hljs-string">`https://api.flutterwave.com/v3/bill-categories?data_bundle=1`</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-attr">Authorization</span>: <span class="hljs-string">`<span class="hljs-subst">${process.env.FLUTTERWAVE_V3_SECRET_KEY}</span>`</span>,
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
    },
  };

  axios(config).then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{

    <span class="hljs-keyword">const</span> getdataSuccess = {
      <span class="hljs-attr">type</span>: response.data,
    };
     res.status(<span class="hljs-number">200</span>) .json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"success"</span>, getdataSuccess });
  });
};

<span class="hljs-built_in">exports</span>.getAirtimeCats = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">var</span> config = {
    <span class="hljs-attr">method</span>: <span class="hljs-string">"GET"</span>,
    <span class="hljs-attr">url</span>: <span class="hljs-string">`https://api.flutterwave.com/v3/bill-categories?airtime=1`</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-attr">Authorization</span>: <span class="hljs-string">`<span class="hljs-subst">${process.env.FLUTTERWAVE_V3_SECRET_KEY}</span>`</span>,
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
    },
  };

  axios(config).then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{

    <span class="hljs-keyword">const</span> getdataSuccess = {
      <span class="hljs-attr">type</span>: response.data,
    };
     res.status(<span class="hljs-number">200</span>) .json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"success, getdataSuccess });
  });
};

exports.getCableCats = async (req, res) =&gt; {
  var config = {
    method: "</span>GET<span class="hljs-string">",
    url: `https://api.flutterwave.com/v3/bill-categories?cable=1`,
    headers: {
      Authorization: `${process.env.FLUTTERWAVE_V3_SECRET_KEY}`,
      "</span>Content-Type<span class="hljs-string">": "</span>application/json<span class="hljs-string">",
    },
  };
  axios(config).then(function (response) {

    const getdataSuccess = {
      type: response.data,
    };
     res.status(200) .json({ message: "</span>success<span class="hljs-string">", getdataSuccess });

  });

};

exports.getPowerCats = async (req, res) =&gt; {
  var config = {
    method: "</span>GET<span class="hljs-string">",
    url: `https://api.flutterwave.com/v3/bill-categories?power=1`,
    headers: {
      Authorization: `${process.env.FLUTTERWAVE_V3_SECRET_KEY}`,
      "</span>Content-Type<span class="hljs-string">": "</span>application/json<span class="hljs-string">",
    },
  };
  axios(config).then(function (response) {

    const getdataSuccess = {
      type: response.data,
    };
     res.status(200) .json({ message: "</span>success<span class="hljs-string">", getdataSuccess });
  });

};</span>
</code></pre>
<p>To pay the bills and save it in the database</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">exports</span>.createBill = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">var</span> config = {
    <span class="hljs-attr">method</span>: <span class="hljs-string">"POST"</span>,
    <span class="hljs-attr">url</span>: <span class="hljs-string">`https://api.flutterwave.com/v3/bills`</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-attr">Authorization</span>: <span class="hljs-string">`<span class="hljs-subst">${process.env.FLUTTERWAVE_V3_SECRET_KEY}</span>`</span>,
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
    },
    <span class="hljs-attr">data</span>: {
      <span class="hljs-attr">country</span>: req.body.country,
      <span class="hljs-attr">customer</span>: req.body.customer,
      <span class="hljs-attr">amount</span>: req.body.amount,
      <span class="hljs-attr">type</span>: req.body.type,
      <span class="hljs-attr">reference</span>: <span class="hljs-built_in">Math</span>.random() * <span class="hljs-number">1000000000</span>,
    },

  };
  <span class="hljs-built_in">console</span>.log(req.user)

  axios(config)
    .then(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">response</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">JSON</span>.stringify(response.data));

      <span class="hljs-keyword">const</span> billsData = {
        <span class="hljs-attr">user</span>: req.user._id,
        <span class="hljs-attr">network</span>: response.data.data.network,
        <span class="hljs-attr">phone</span>: response.data.data.phone_number,
        <span class="hljs-attr">amount</span>: response.data.data.amount,
        <span class="hljs-attr">transactionId</span>: response.data.data.flw_ref
      };
      <span class="hljs-keyword">const</span> billsPayed = <span class="hljs-keyword">new</span> PayBills(billsData);
      billsPayed.save(<span class="hljs-function">(<span class="hljs-params">err, billsPayed</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (err) res.status(<span class="hljs-number">400</span>).json({ err });
        <span class="hljs-keyword">if</span> (billsPayed)
          res
            .status(<span class="hljs-number">200</span>)
            .json({ <span class="hljs-attr">message</span>: <span class="hljs-string">"success"</span>, billsPayed });
      });
    })

    .catch(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">error</span>) </span>{
      <span class="hljs-built_in">console</span>.log(error);
    });
};
</code></pre>
<p>Let's test the APIs with Postman, we register and then put the token on the bearer token tab under the authorization tab.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695642635985/61486c8e-1268-4404-b0a5-905600f2f6c5.png" alt class="image--center mx-auto" /></p>
<p>We have a successful payment.</p>
<h3 id="heading-update-wallet-amount-after-paying-a-bill">Update wallet amount after paying a bill.</h3>
<p>After paying a bill we update the amount in the user's wallet.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">exports</span>.updateWallet = <span class="hljs-keyword">async</span> (req, res) =&gt; {
    <span class="hljs-comment">//get the params using req.params and pass it it the flutterwave url </span>
  <span class="hljs-keyword">const</span> url = <span class="hljs-string">`https://api.flutterwave.com/v3/bills/<span class="hljs-subst">${req.params.transId}</span>`</span>;
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios({
    url,
    <span class="hljs-attr">method</span>: <span class="hljs-string">"get"</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"application/json"</span>,
      <span class="hljs-attr">Accept</span>: <span class="hljs-string">"application/json"</span>,
      <span class="hljs-attr">Authorization</span>: <span class="hljs-string">`<span class="hljs-subst">${process.env.FLUTTERWAVE_V3_SECRET_KEY}</span>`</span>,
    },
  });

  <span class="hljs-comment">// get the amount spent in paying a bill by the user from the response</span>
  <span class="hljs-keyword">const</span> {  amount } = response.data.data;
  <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// get the email of the user from params and find the user in the database</span>
    <span class="hljs-keyword">const</span> account = <span class="hljs-keyword">await</span> User.findOne({ <span class="hljs-attr">email</span>: req.params.user });
    <span class="hljs-keyword">const</span> user = account._id
    <span class="hljs-built_in">console</span>.log(user)
    <span class="hljs-comment">// find the a wallet and update it if the user is in the database</span>
      <span class="hljs-keyword">const</span> wallet = <span class="hljs-keyword">await</span> Wallet.findOneAndUpdate(
        { <span class="hljs-attr">userId</span>: user },
        <span class="hljs-comment">//subtract the amount payed from the amount in the users wallet</span>
        { <span class="hljs-attr">$inc</span>: { <span class="hljs-attr">balance</span>: -amount } },
        { <span class="hljs-attr">new</span>: <span class="hljs-literal">true</span> }
      );
      res.status(<span class="hljs-number">200</span>).json(wallet);
    <span class="hljs-comment">// }</span>


  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.log(error);
  }
};
</code></pre>
<p>Lets get the current amount in the database</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695645515365/48873310-6d9b-4155-9c20-100543390fe3.png" alt class="image--center mx-auto" /></p>
<p>Let's check the current amount after paying a bill</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695646108844/5067f1dc-5337-4f35-b317-7072142fa1ed.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-conclusion">Conclusion</h3>
<p>We learned how to authenticate, protect routes, deposit to our mobile wallet and pay bills from our mobile wallet.</p>
<h3 id="heading-reference">Reference</h3>
<p><a target="_blank" href="https://developer.flutterwave.com/">Flutterwave documentation</a></p>
<p><a target="_blank" href="https://blog.idrisolubisi.com/how-to-build-a-wallet-system-with-flutterwave-payment-integration-into-nodejs-application">Olanetsoft's Blog</a></p>
<p>Connect with me on <a target="_blank" href="https://twitter.com/Khennoxx?t=eOrLQ76Pq28JgRF3Cd4MZw&amp;s=09">Twitter</a>,</p>
]]></content:encoded></item></channel></rss>