Do you manage money on behalf of other people ? or other companies ? Would you like each of your clients to have their own account with their own transaction history ? Or would you like a strict separation between your money on the one hand, and your customers' money on the other ? Would you like to be able to provide each customer with a statement of the transactions that have taken place concerning him or her over a given period ? 1 month, 1 week or 1 day for example ?
With FPay, you can create Wallet. Each Wallet is like an account that you can fund and use. Money transfers between Wallet you own are free of charge. If you have several Wallet, you can specify which one to use for each transaction. For example, when you add money to your FPay account with a Deposit or FundRequest, you can choose which Wallet to deposit it in.
This is the ideal way to express the following: Customer number 12 has just added money to his Wallet. If you prefer, you can add money to your own Wallet and then transfer it to the customer's wallet, taking a commission if necessary.
For example, you initiate a Deposit to receive ₣10,000 for a customer. You decide to deposit this money on your main wallet. Then you transfer ₣9,950 to the Wallet of the customer in question, keeping your ₣50 commission in the process.
Similarly, when you withdraw money with a Transfer or QuasiTransfer, you can specify which Wallet the money will be taken from.
This is the ideal way to express the following: Customer number 19 has just withdrawn money from his Wallet. If you prefer, you can withdraw money from your own Wallet and then make a transfer from your customer's Wallet to yours, taking a commission if necessary.
For example, you initiate a Transfer to send 10,000₣ to someone on behalf of your client. You may decide to withdraw this money from your main wallet to transfer it and then withdraw 10,050 ₣ from the Wallet of the your client in question, keeping your 50₣ commission in the process.
At the end of the month, you can list all Transactions on a given Wallet to present a summary.
money-in-only, read/money-in, or read-write/no-money-out as explained on the Authentication page.AuthAccess object as explained on the Authentication page.AuthAccess object, the value of the field named secretKey must be kept absolutely secret and used only on your servers. This implies that you should never use the value of this field as a variable or constant in the source code of a mobile application, a web application or in the source code of any application whose binary may be public and visible to all. There are many tools to access strings in the source code from a binary around here.const fPay = sdk.FPayClient(sdk.Auth({token: '<token>', secretKey: '<secretKey>' }));const walletPromise =
fPay.wallet.create({
name: "Magasin Yopougon"
});
const walletPromise =
fPay.wallet.create({
name: "Magasin Cocody"
});
const walletPromise =
fPay.wallet.create({
name: "Magasin San-Pedro"
});const walletPromise =
fPay.wallet.create({
name: "Compte Entreprise #1"
});
const walletPromise =
fPay.wallet.create({
name: "Compte Entreprise #2"
});
const walletPromise =
fPay.wallet.create({
name: "Compte Entreprise #3"
});Whenever money is added to your account, the funds collected will be deposited in your main Wallet by default. Because you can create several additional Wallet , you can also choose where the funds arrives once the user has paid.
So, you can have one Wallet for your savings, or one Wallet per store if you have several stores, and choose where the funds received will go.
To specify the destination of the funds, you need the MARS of the Wallet, available vie the mars.alpha field.
For example, if the Wallet's MARS is "CI FPay W09POT", then you would enter the following code:
const depositPromise =
fPay.deposit.initiate({
destination: "CI FPay W09POT",
source: {
_type: "Single",
account: {
country: "CI",
identifier: "+2250100000000",
providerKey: "MoovMoney"
}
},
amount: {
currency: "XOF",
value: "10_000"
}
});You can move money between any Wallet you own. You can withdraw money from your Wallet and deposit it in your user's Wallet, and vice versa. These account movements can even correspond to users you have paying each other.
Also, if in the course of your business you need to receive deposits from your users, you can store these deposits in their respective Wallets. Later, you can deduct from this deposit the amounts corresponding to offences they have committed by making a Transfer to your Wallet or, if no offence has been committed, you can initiate a refund to their mobile money wallets directly from their Wallet : the possibilities are endless and your choice will depend on your activity.
Let's say you own a Wallet whose MARS is "CI FPay MPO099R" and another Wallet whose MARS is "CI FPay MOY67RT". To transfer money from the first Wallet to the second, you need to do the following code:
const transferPromise =
fPay.transfer.initiate({
amount: "10_000 XOF",
source: "CI FPay MPO099R",
destination: "CI FPay MOY67RT"
});For all outgoing payments, the funds sent will be taken from your main Wallet by default. If the cash outflow is for a specific customer, because you have the option of telling FPay the Wallet from which the money is to be taken for this cash outflow, you can specify the Wallet of the customer concerned by this cash outflow, regardless of whether this cash outflow is made via a Transfer object or a QuasiTransfer object.
To specify the source of the funds, you need the MARS of the Wallet, available vie the mars.alpha field.
For example, if the Wallet's MARS is "CI FPay W09POT", then you would enter the following code:
const transferPromise =
fPay.transfer.initiate({
amount: {
currency: "XOF",
value: "10_000"
},
source: "CI FPay W09POT",
destination: {
_type: "Single",
account: {
country: "CI",
identifier: "+2250100000000",
providerKey: "MoovMoney"
}
}
});const quasiTransferPromise =
fPay.quasiTransfer.initiate({
amount: {
currency: "XOF",
value: "10_000"
},
source: "CI FPay W09POT"
});Let's suppose it's October 27th (10/27) and we want to draw up a statement for a customer showing the Transaction that have taken place in his Wallet since the 1st of the month to date. The result could look like the following figure :
| DATE | DETAILS | DEBIT | CREDIT | BALANCE BEFORE | BALANCE AFTER |
|---|---|---|---|---|---|
| 10/04 | Deposit from 07 00 00 00 00 | + ₣ 13,000 | ₣ 150,000 | ₣ 163,000 | |
| 10/05 | Deposit from 07 00 00 00 00 | + ₣ 7,000 | ₣ 163,000 | ₣ 170,000 | |
| 10/06 | Management fees | - ₣ 500 | ₣ 170,000 | ₣ 169,500 | |
| 10/07 | Withdrawal to 05 00 00 00 00 | - ₣ 10,000 | ₣ 169,500 | ₣ 159,500 | |
| 10/20 | Loyalty Bonus | + ₣ 1,000 | ₣ 159,500 | ₣ 160,500 |
Let's see how to build this previous table for each of your customers
Transaction objectEverytime there is a change in the balance of a Wallet, a Transaction object is created to materialize this movement of money. Whether this change in balance is due to a Transfer, a Deposit or any other object, a Transaction object will be created. So, to create the above table, here are the Transaction object fields that will be useful to us:
amountWallet in question.dcWallet in question."Debit" or "Credit"."Debit", then the amount that is always positive has been removed from the Wallet."Credit", then the amount that is always positive has been added to the Wallet.walletWallet on which the Transaction took place. In particular, this field will give us access to the balance before and after the Transaction.statusSuccessful or Failure.String, but objects. For example, the Failure object has isCancelled field, which indicates that the transaction failed because it has was cancelled.parentTransfer, Deposit, QuasiTransfer etc.detailsdc, status et parentfieldsstatus field has the value Successful OR Failure), you can rest assured that there are functions to enable you to use these values optimally.isSuccessful() function, an isFailure() function, other functions and the fold function .Now that we've set the scene, we will :
Transaction in the current month for the user's Wallet. Let's assume that the user's wallet id is 123456789.Transaction the information required to build the table.Transaction in the current monthconst transactionsCollectionPromise =
fPay.transaction.list({
filter: "status = 'Successful'"
+ " AND createdTime in CurrentMonth"
+ " AND wallet.id = '123456789'",
sortBy: "createdTime:ASC"
});// Access items in the returned collection, page per page
let transactionsCollection = await transactionsCollectionPromise;
let allTransactions = transactionsCollection.toArray();
while(transactionsCollection.hasNextPage()){
transactionsCollection =
await fPay.transaction.fetchPage(transactionsCollection.pagination.nextPage);
const transactions = transactionsCollection.toArray();
allTransactions = allTransactions.concat(transactions);
}Transaction the information required to build the tablelet debitTransactionsAmount = [];
let creditTransactionsAmount= [];
for (const transaction of allTransactions) {
const date = new Date(transaction.createdTime.iso8601);
const dayOfMonth = date.getDate();
const month = date.getMonth();
const details = transaction.h1.fr;
const beforeBalance = transaction.wallet.before.balance.available;
const afterBalance = transaction.wallet.after.balance.available;
let debitAmount = null;
if(transaction.dc.isDebit()){
// amount is always positive so we have to negate the value for debit
debitAmount = -transaction.amount.value;
debitTransactionsAmount.push(debitAmount);
}
let creditAmount = null;
if(transaction.dc.isCredit()){
creditAmount = transaction.amount.value;
creditTransactionsAmount.push(creditAmount);
}
// Here we have extracted the most of required values, you can
// do the stuff with them inside the loop
}
const firstTransaction: Transaction = allTransactions[0];
const lastTransaction: Transaction = allTransactions[allTransactions.length-1];
// Finally the values for summary
const initialBalance = firstTransaction.wallet.before.balance.available
const endBalance = lastTransaction.wallet.after.balance.available
const totalDebits = debitTransactionsAmount.reduce((sum, el) => sum + el, 0);
const totalCredits = creditTransactionsAmount.reduce((sum, el) => sum + el, 0);
// Congratulation 🎉🥳👏
// At this point, you can create a beautiful PDF or HTML Table for your user 🥂👏🍾When creating the Wallet object, you can attach your own internal ID. In this way, When retrieving the Wallet object, you will be able to use your own id instead of the one generated by FPay. The ID you submit must be unique for each object type.
One of the advantages of submitting your own unique identifier is that you can carry outidempotent queries. In fact, if your submitted foreignId is unique, then you're protected against duplications due to networks, for example, and you'll be able to control retries without worrying about repeating the same operation several times.
const walletPromise =
fPay.wallet.create({
foreignId: "<my internal id>"
});With the previous code, you now have the right to do the following code to retrieve Wallet object.
const walletPromise = fPay.wallet.get("<my internal id>");When creating Wallet object, you can add your own data to tag the object you've created.
For example, you can add the following data:
{"myKey": 19, "myOtherKey": "myOtherValue"}<xml><myKey>myValue</myKey></xml>myValue1, myValue2, myValue3const walletPromise =
fPay.wallet.create({
foreignData: "<xml><myKey>myValue</myKey></xml>"
});const walletPromise = fPay.wallet.get("<wallet.id | foreignId>");walletPromise.then(wallet => {
// Inspect the 'foreignData' field of the Wallet ...
const xmlData = wallet.foreignData;
// xmlData = "<xml><myKey>myValue</myKey></xml>"
});