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:
amount
Wallet
in question. dc
Wallet
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
. wallet
Wallet
on which the Transaction
took place. In particular, this field will give us access to the balance before and after the Transaction
. status
Successful
or Failure
.String
, but objects. For example, the Failure object has isCancelled
field, which indicates that the transaction failed because it has was cancelled. parent
Transfer
, Deposit
, QuasiTransfer
etc. details
dc
, status
et parent
fields status
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, myValue3
const 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>"
});