Logo Blue Finalse
Console 
  Français   English


C#


  • GETTING STARTED
  • Authentication
  • Hello World
  • Pricing
  • Rate Limit
  • USE CASES
  • FPay UI Integration
  • Custom UI Integration
  • Interoperability  New
  • Payment links and QRCodes
  • Third Parties Money  New
  • Audit & Dashboard  New
  • REFERENCES
  • Attempt
  • AuthAccess
  • Deposit
  • FundRequest
  • QuasiTransfer
  • Transaction
  • Transfer
  • Wallet
Logo Blue FinalseLogo Blue Finalse
Javascript
Console 
  Français   English
  • GETTING STARTED
  • Authentication
  • Hello World
  • Pricing
  • Rate Limit
  • USE CASES
  • FPay UI Integration
  • Custom UI Integration
  • Interoperability  New
  • Payment links and QRCodes
  • Third Parties Money  New
  • Audit & Dashboard  New
  • REFERENCES
  • Attempt
  • AuthAccess
  • Deposit
  • FundRequest
  • QuasiTransfer
  • Transaction
  • Transfer
  • Wallet

Do you manage money on behalf of third parties ?

Context  

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 ?

In Details  

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.

Information
If you manage money on behalf of a third party, and the third party wishes to have control over their money, you can ask your customer to create their FPay account and provide you with API keys with reduced permissions such as money-in-only,  read/money-in,  or read-write/no-money-out as explained on  the Authentication page.

Pre Requisites  

Javascript
This SDK requires
Node >=9.5

Authentication
We assume that you have of course opened your FPay account and that you are in possession of your  token and your secretKey  obtained during the creation of the AuthAccess object as explained  on the Authentication page.

Initialization  

Important
In 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.
  • NPM
  • Yarn
npm install @finalse/sdk-node
yarn add @finalse/sdk-node
const fPay = sdk.FPayClient(sdk.Auth({token: '<token>', secretKey: '<secretKey>' }));

Implementation  

Creating Wallets  

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"
    });

Money in to a Wallet  

Destination  

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.

How it works ?

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"
        }
    });

Transferring Money between Wallets  

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.

How it works ?

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"
    });

Money out from a Wallet  

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.

How it works ?

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:

Transfer
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"
            }
        }
    });
QuasiTransfer
const quasiTransferPromise = 
    fPay.quasiTransfer.initiate({
        amount: {
            currency: "XOF",
            value: "10_000"
        },
        source: "CI FPay W09POT"
    });

Drawing up a statement of transactions  

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 :

DATEDETAILSDEBITCREDITBALANCE BEFOREBALANCE AFTER
10/04Deposit from 07 00 00 00 00+ ₣ 13,000₣ 150,000₣ 163,000
10/05Deposit from 07 00 00 00 00+ ₣ 7,000₣ 163,000₣ 170,000
10/06Management fees- ₣ 500₣ 170,000₣ 169,500
10/07Withdrawal to 05 00 00 00 00- ₣ 10,000₣ 169,500₣ 159,500
10/20Loyalty Bonus+ ₣ 1,000₣ 159,500₣ 160,500
Balance at 10/01
+ ₣ 150,000
Total Credit
+ ₣ 21,000
Total Debit
- ₣ 10,500

Balance at 10/27
+ ₣ 160,500

Let's see how to build this previous table for each of your customers

A word about the Transaction object

Everytime 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
    With an always positive value, this field represents the amount that has been added to or withdrawn from the Wallet in question.
  •   dc
    Abbreviation for debit or credit, this field indicates whether the previous amount has been added to or withdrawn from the Wallet in question.
    The 2 possible values for this field are "Debit" or "Credit".
    If the value is "Debit", then the amount that is always positive has been removed from the Wallet.
    If the value is "Credit", then the amount that is always positive has been added to the Wallet.
  •   wallet
    This field is an indicator of the status of the target Wallet on which the Transaction took place. In particular, this field will give us access to the balance before and after the Transaction.
  •   status
    This field indicates whether the transaction was successful or failed. The 2 possible values for this field are Successful or Failure.
    Please note that these are not String, but objects. For example, the Failure object has isCancelled field, which indicates that the transaction failed because it has was cancelled.
  •   parent
    This field indicates the parent object whose execution led to the creation of this Transaction. This parent object can therefore be a Transfer, Deposit, QuasiTransfer etc.
  •   details
    This field, if available, will access the transaction id generated by the operator if this transaction concerns an operation between FPay and the outside world (Mtn Money, Orange Money or Moov Money).
Regarding the dc, status et parentfields
The values of these fields have been modelled as ADTs (Algebraic Data Type)  , concept derived from type theory and  functional programming . Because our SDKs have been designed to simplify use, whenever you have a type whose value is defined by an "OR" (for example, the  status field has the value Successful OR Failure), you can rest assured that there are functions to enable you to use these values optimally.
In the case of the status field, for example, you'll have an isSuccessful() function, an isFailure() function, other functions and the fold function .

Implementation

Now that we've set the scene, we will :

  •  List all successful Transaction in the current month for the user's Wallet. Let's assume that the user's wallet id is 123456789.
  •   Extract for each Transaction the information required to build the table.

List all successful Transaction in the current month
const 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);
}
Extract for each Transaction the information required to build the table
let 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 🥂👏🍾

Going Further  

Foreign ID  

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.

For creation
const walletPromise = 
    fPay.wallet.create({
        foreignId: "<my internal id>"
    });
At retrieval

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>");

Foreign Data  

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
  •  Any string you like, as long as it doesn't exceed 255 characters.
This data will be present each time the object is retrieved.

On creation
const walletPromise = 
    fPay.wallet.create({
        foreignData: "<xml><myKey>myValue</myKey></xml>"
    });
When retrieving
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>" 
});
THIRD PARTIES MONEY
  • Context
  • In Details
  • Pre Requisites
  • Initialization
  • Implementation
    • Initialisation
    • Creating Wallets
    • Money in Wallet
    • Transferring Money between Wallets
    • Money out from Wallet
    • Transactions Statement
  • Going Further
    • Foreign ID
    • Foreign Data