API Documentation

Develop the Future of Financial Services with our API that rules them all

About Moneywave

Moneywave is a payment system that allows you to securely charge cards and pay accounts. Here you’ll find detailed information about our APIs – what they’re for, how to use them and when to use them. If you have any questions or comments, feel free to drop us a message at getstarted@flutterwavego.com

Getting started

Base URL: https://moneywave.herokuapp.com/

Payments in test environment

Please note that that when working in TEST environment and you need to do an account based transaction, you will need to use one of our Test Account numbers. However, because Moneywave uses 3DSecure for authentications, you have to use a live card while you are in TEST environment so you can have an idea of how it will work when you go LIVE. For those of you that will be testing on an API level, we suggest that you do your tests with a small amount of money because you will not be able send the money to a real bank account number.

Test account details:

Bank Code: 044
Bank Accounts: 0690000004, 0690000005

Bank Code: 058
Bank Account: 0921318712

Moneywave uses 3DSecure for authenticating Mastercards and Visa Cards. We return a response code "02" and a response html as well as an auth url parameter when the charge call is initiated. For validation, you are supposed to either load the response html in an iFrame / Browser or Redirect your users to the auth url to validate the transaction. When this has been done, we will redirect to the response url you supplied in the first call and then pass our response as a query parameter.

Moneywave uses PIN for authenticating Verve Cards. You need to include the pin parameter to your request payload and then validate the transaction using a One Time password that will be sent to the cardholders phone.

Step 1. Create an account

First, you’ll need to create an account with us. To do that, you need to go to https://moneywave.flutterwave.com to create your account. Once successfully created you will get an apiKey and secret with credentials for your sandbox and production environments. These credentials will be availble under account settings, when you are logged in to the portal. To get your LIVE credentials, you need to Toggle the TEST LIVE button and fill up the GO LIVE form.

Step 2. Get a list of all banks A lot of the time, when using the moneywave API, you’ll be required to enter a 3 - character bank code used to identify a bank. You can get this list of banks by calling the /banks endpoint. We’ll really recommend that you send a post request to this end point and save the response in a variable before you call any other endpoint when using Moneywave. A sample request could look something like this [POST] /banks

A sample response looks something like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
              {
                "status": "success",
                "message": "Banks fetched",
                "data": {
                  "100": "SunTrust Bank",
                  "214": "First City Monument Bank",
                  "215": "Unity Bank",
                  ......
                  "403": "SafeTrust Mortgage Bank",
                  "501": "Fortis Microfinance Bank",
                  "044": "Access Bank",
                  "068": "Standard Chartered Bank"
                }
              }
            

Step 3. Create your access token Once you have a merchant account, you need to call /v1/merchant/verify to obtain an access token. The token represents you as a merchant and grants you access to every other endpoint. Please note that the tokens expire after 2hrs.

The parameters you might need are

Field Name

  • apiKey
  • secret

Field Type

  • String
  • String

Description

  • the apiKey of the merchant
  • the secret of the merchant

A sample request could look something like this [POST] /v1/merchant/verify

1
2
3
4
              {
              "apiKey": String,
              "secret": String
              }
            

A sample response looks something like this

1
2
3
4
              {
                status: "success",
                token: "" // a valid merchant token
              }
            

Step 4. Authenticate your request Now you have your access token, all that’s left is to authenticate your API requests. To do that you need to ensure that for all your authorisation requests, you’re passing your access token in the request header.

The parameters you might need are

Field Name

  • Authorization

Field Type

  • String

Description

  • this is the token you must have gotten from the /v1/merchant/verify endpoint
Points to remember when using our APIs
  • Always ensure you do all your testing on https://moneywave.herokuapp.com, as all requests to the Live base url - https://live.moneywaveapi.co/ will be charged to your account.
  • If you are getting ready to launch into production, please send us an email at customersuccess@flutterwave.com.
  • All our API responses are formatted using JSON and are served over HTTPS to ensure data privacy. Please note that HTTP is not supported
  • Every request you pass to us must include an access_token that has a request data included in the body.
  • A success status on our response does not always mean that the payment was successful, it most probably simply means that we were able to make an attempt in processing the payment. This means that you as a customer have to ensure that you check the content of the data returned for the proper response.
Our error codes
  • We use standard error codes in our responses for successes and failures. If you encounter any issues feel free to contact us or check out our Error messages FAQ page for more information

Features

1. Transfers from card (Mastercard, Visa, Verve) / account to account The chief premise of this solution is that you can charge any card in the world / select accounts and pay into any bank account in supporting countries. To successfully transfer money from a card / account to an account, you need to call v1/transfer and supply all the necessary parameters

The parameters you might need are

Field Name

  • firstname
  • lastname
  • phonenumber
  • email
  • recipient
  • recipient_id
  • recipient_bank
  • recipient_account_number
  • recipients
  • card_no
  • cvv
  • pin
  • expiry_year
  • expiry_month
  • apiKey
  • amount
  • fee
  • redirecturl
  • medium
  • chargeCurrency
  • disburseCurrency
  • charge_with
  • card_last4
  • card_token
  • sender_account_number
  • sender_bank
  • passcode
  • card_id
  • cycle
  • startDate
  • endDate

Field Type

  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • Number
  • Number
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String

Description

  • the firstname of the sender
  • the lastname of the sender
  • the phone number of the sender, must be international format starting with +
  • the email of the sender
  • (optional) recipient type: account, wallet, beneficiary, bulk-account
  • (optional) recipient type id
  • bank to send money to
  • account number of the recipient in the recipient bank
  • (optional) array of recipients
  • card number to charge
  • cvv of the card to charge
  • (optional) Card PIN required when charging Verve Cards
  • expiry year of the card to charge
  • expiry month of the card to charge
  • your merchant apiKey displayed to you after registering as a merchant.
  • this is the amount to send to the beneficiary
  • the amount the merchant wants to add as his commission
  • the url to redirect to after transaction has been successfully validated
  • this can either be web or mobile or depending on request medium
  • (optional) - this is the currency in which card will be charged
  • (optional) - this is the currency in which account will be credited
  • (optional) - charge method : card, account, token or tokenized_card
  • (optional)* - card last 4 digits, required in charge with token
  • (optional)* - card token, required in charge with tokenized card
  • (optional)* - charge source, required in charge with account
  • (optional)* - charge source bank, required in charge with account
  • (optional)* - Account Security PIN required for account charge
  • (optional)* - card ID required when charging with token
  • (optional)* - sheduled / recurring transfer cycle
  • (optional)* - sheduled / recurring start date
  • (optional)* - sheduled / recurring end date
Please remember that to make a successful transfer, you need to have first gotten a token from /v1/merchant/verify endpoint.

A sample request could look something like this
[POST] /v1/transfer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
              {
              "firstname": String,
              "lastname": String,
              "phonenumber": String,
              "email": String,
              "recipient_bank": String,
              "recipient_account_number": String,
              "card_no": String,
              "cvv": String,
              "expiry_year": String,
              "expiry_month": String,
              "apiKey": String,
              "amount": Number,
              "fee": Number,
              "redirecturl": String,
              "medium": String
              }
            
A sample response could look something like this
1
2
3
4
5
6
7
              {
                status: "success",
                data: {
                  transfer: {}, //transfer object
                  responsehtml: "" //
                }
              }
            
Our response for a failed transaction could look something like this
1
2
3
4
5
6
7
8
9
10
11
12
              {
                status: "error",
                code: "INVALID_FIRSTNAME | INVALID_CARD | INVALID_LASTNAME",
                message: ""
              }

              OR

              HTTPS/1.1 401 Unauthorized
              {
                status: "error"
              }
            
Validation for Verve cards to account Verve Cards will be charged using PIN, the bank determines if they want an extra level of validation, if they do, response code will be 02, and that means you have to validate the transation.
A sample request could look something like this [POST] /v1/transfer/charge/auth/card
1
2
3
4
              {
                "transactionRef": "", //Flutterwave reference from /v1/transfer call
                "otp": "",
              }
            
A sample response could look something like this
1
2
3
4
5
              {
                status: "success",
                data: {
                } //this is the transfer object
              }
            
Validation for account to account Our Live bank accounts require validation to be charged, this could come as a OTP or ACCOUNT_CREDIT. Response code will be 02 will mean you have to validate the transation.
A sample request could look something like this [POST] /v1/transfer/charge/auth/account
1
2
3
4
5
              {
                "transactionRef": "", //Flutterwave reference from /v1/transfer call
                "authType": "", //OTP or ACCOUNT_CREDIT
                "authValue": "",
              }
            
A sample response could look something like this
1
2
3
4
5
              {
                status: "success",
                data: {
                } //this is the transfer object
              }
            
2. Transfers from card to wallet The chief premise of this solution is that you can charge any card in the world and deposit the funds to your wallet in that currency. To successfully transfer money from a card to your wallet, you need to call v1/transfer and supply all the necessary parameters

The parameters you might need are

Field Name

  • firstname
  • lastname
  • phonenumber
  • email
  • recipient
  • card_no
  • cvv
  • expiry_year
  • expiry_month
  • apiKey
  • amount
  • fee
  • redirecturl
  • medium
  • chargeCurrency
  • disburseCurrency
  • charge_with
  • card_last4
  • sender_account_number
  • sender_bank

Field Type

  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • Number
  • Number
  • String
  • String
  • String
  • String
  • String
  • String
  • String
  • String

Description

  • the firstname of the sender
  • the lastname of the sender
  • the phone number of the sender, must be international format starting with +
  • the email of the sender
  • recipient should be set to "wallet"
  • card number to charge
  • cvv of the card to charge
  • expiry year of the card to charge
  • expiry month of the card to charge
  • your merchant apiKey displayed to you after registering as a merchant.
  • this is the amount to send to the beneficiary
  • the amount the merchant wants to add as his commission
  • the url to redirect to after transaction has been successfully validated
  • this can either be web or mobile or depending on request medium
  • (optional) - this is the currency in which card will be charged
  • (optional) - this is the currency in which account will be credited
  • (optional) - charge method : card, account or token
  • (optional)* - card last 4 digits, required in charge with token
  • (optional)* - charge source, required in charge with account
  • (optional)* - charge source bank, required in charge with account
Please remember that to make a successful transfer, you need to have first gotten a token from /v1/merchant/verify endpoint.

A sample request could look something like this
[POST] /v1/transfer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
              {
              "firstname": String,
              "lastname": String,
              "phonenumber": String,
              "email": String,
              "recipient": String,
              "card_no": String,
              "cvv": String,
              "expiry_year": String,
              "expiry_month": String,
              "apiKey": String,
              "amount": Number,
              "fee": Number,
              "redirecturl": String,
              "medium": String,
              }
            
A sample response could look something like this
1
2
3
4
5
6
7
              {
                status: "success",
                data: {
                  transfer: {}, //transfer object
                  responsehtml: "" //
                }
              }
            
Our response for a failed transaction could look something like this
1
2
3
4
5
6
7
8
9
10
11
12
              {
                status: "error",
                code: "INVALID_FIRSTNAME | INVALID_CARD | INVALID_LASTNAME",
                message: ""
              }

              OR

              HTTPS/1.1 401 Unauthorized
              {
                status: "error"
              }
            
3. Get total charge to card Every transfer from a card attracts certain fees for the service. As a merchant, you can also choose to add your own fee you want to charge your customer for the service. To get the total amount we’ll charge (all fees+transfer amount), you need to call the /v1/get-charge endpoint.

The parameters you might need are

Field

  • amount
  • fee

Field

  • Number
  • Number

Description

  • the amount you want us to send to the recipient
  • the fee you want to add ad your commission as a merchant
A sample request could look something like this [POST] /v1/get-charge
1
2
3
4
              {
              "amount": Number,
              "fee": Number
              }
            
A sample response could look something like this
1
2
3
4
5
6
7
8
              {
                status: "success",
                data: {
                  amountToSend: , //the total amount we will send to the recipient
                  amountChargeable: , // the total amount we will charge the card
                  merchantCommission: // your commission
                }
              }
            
4. Transfers from wallet to account (Single) To successfully transfer money from a funded wallet to an account, you need to call v1/disburse and supply all the necessary parameters

The parameters you might need are

Field Name

  • lock
  • amount
  • bankcode
  • accountNumber
  • currency
  • senderName

Field Type

  • String
  • Number
  • String
  • String
  • String
  • String

Description

  • the password of your wallet
  • the amount to send to the beneficiary
  • the bankcode of the bank to send money to
  • the account number of the recipient
  • the currency to send money in
  • the name of the sender
Please remember that to make a successful transfer, you need to have first gotten a token from /v1/merchant/verify endpoint.

A sample request could look something like this
[POST] /v1/disburse
1
2
3
4
5
6
              {
              "lock": String,
              "amount": Number,
              "bankcode": String,
              "accountNumber": String,
              "currency": String,
              "senderName": String,
              "ref": String
              }
            
A sample response could look something like this
1
2
3
4
5
6
              {
                "status": "success",
                "data": {
                  "data": {
                    "responsecode": "00",
                    "responsemessage": "Approved Or Completed Successfully",
                    "uniquereference": "TMW000000317"
                  },
                  "status": "success"
                }
              }
            
Our response for a failed transaction could look something like this
1
2
3
4
5
6
7
8
9
10
11
12
              {
                status: "error",
                code: "",
                message: ""
              }

              OR

              HTTPS/1.1 401 Unauthorized
              {
                status: "error"
              }
            
5. Transfers from wallet to account (Bulk) To successfully transfer money from a funded wallet to more than one account at a time, you need to call v1/disburse/bulk and supply all the necessary parameters. The ref for the individual disburse transactions must be unique and the ref for the whole disburse transaction must be unique for each disburse trasnaction.

The parameters you might need are
Please remember that to make a successful transfer, you need to have first gotten a token from /v1/merchant/verify endpoint.

A sample request could look something like this
[POST] /v1/disburse/bulk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
              {
                "lock":"539935",
                "recipients": [
                  {
                    "amount":100,
                    "bankcode":"044",
                    "accountNumber":"0690000005",
                    "ref":"7"
                  },
                  {
                    "amount":200,
                    "bankcode":"044",
                    "accountNumber":"0690000006",
                    "ref":"8"
                  }
                ],
                "currency": "NGN",
                "senderName": "THRIVE",
                "ref":"46"
              }
            
A sample response could look something like this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
              {
                "status": "success",
                "failed": 0,
                "passed": 2,
                "data": [
                  {
                    "accountNumber": "0690000005",
                    "data": {
                      "responsecode": "00",
                      "responsemessage": "Approved Or Completed Successfully",
                      "uniquereference": "TMW000000311"
                    }
                  },
                  {
                    "accountNumber": "0690000006",
                    "data": {
                      "responsecode": "00",
                      "responsemessage": "Approved Or Completed Successfully",
                      "uniquereference": "TMW000000312"
                    }
                  }
                ]
              }
            
Our response for a failed transaction could look something like this
1
2
3
4
5
6
7
8
9
10
11
12
              {
                status: "error",
                code: "",
                message: ""
              }

              OR

              HTTPS/1.1 401 Unauthorized
              {
                status: "error"
              }
            

Resources

1. Account number validation API Before doing a transfer or disbursement to a bank account, it’s good practice to validate the details of the destination bank account. Our API allows you to do just that by verifying the account number and returning the account name. To do that, you need to send a POST request to /v1/resolve/account, with the account number and bank code in the body of the request.

The parameters you might need are

Field Name

  • account_number
  • bank_code

Field Type

  • String
  • String

Description

  • the account number of the sender
  • the bank code of the account to resolve
A sample request could look something like this [POST] /v1/resolve/account
1
2
3
4
              {
              "account_number": String,
              "bank_code": String
              }
            
A sample response could look something like this
1
2
3
4
5
              {
                status: "success",
                data: {
                }
              }
            
2. Card Tokenization You can tokenize a card and use the token for initiate a card to account transfer request.

The parameters you might need are

Field Name

  • card_no
  • expiry_year
  • expiry_month
  • cvv

Field Type

  • String
  • String
  • String
  • String

Description

  • card number of debit card
  • expiry year of debit card
  • expiry month of debit card
  • cvv of debit card
A sample request could look something like this [POST] /v1/transfer/charge/tokenize/card
1
2
3
4
              {
              "card_no": String,
              "expiry_year": String,
              "expiry_month": String,
              "cvv": String
              }
            
A sample response could look something like this
1
2
3
4
5
              {
                "status": "success",
                "data": {
                  "cardToken": "be711fe2be4edb35cc554fc6428b1f64"
                }
              }
            
3. Failed transaction retrial API It might happen that a transaction fails in a unique way where the card is charged but the disbursement leg to the account fails.To retry these types of transactions, you need to send a POST request to /v1/transfer/disburse/retry, with the id of the successful charge, recipient_account_number and recipient_bank (bankcode) in the body of the request.

The parameters you might need are

Field Name

  • id
  • recipient_account_number
  • recipient_bank

Field Type

  • String
  • String
  • String

Description

  • id of a successfully charged transfer.
  • (optional) disburse destination account number
  • (optional) disburse destination bank
A sample request could look something like this [POST] /v1/transfer/disburse/retry
1
2
3
4
5
              {
                "id": String,
                "recipient_account_number": String,
                "recipient_bank": String
              }
            
A sample response could look something like this
1
2
3
4
5
6
              {
                "status": "success",
                "message": "Disburse Successful",
                "data": {
                }
              }
            
4. Previous transactions API (Card 2 Account) It’s inevitable that you’d eventually need to see your records of previous transactions whether successful or not. To gain access to this information, you need to send a POST request to /v1/transfer/:id, where the id placeholder is the ID of the transaction you’re trying to query.
A sample request could look something like this [POST] /v1/transfer/:id
A sample response could look something like this
1
2
3
4
5
              {
                status: "success",
                data: {
                } //this is the transfer object
              }
            
5. Previous transactions API (Wallet 2 Account) It’s inevitable that you’d eventually need to see your records of previous transactions whether successful or not. To gain access to this information, you need to send a POST request to /v1/disburse/status.
A sample request could look something like this [POST] /v1/disburse/status
1
2
3
              {
                "ref": "2"
              }
            
A sample response could look something like this
1
2
3
4
5
              {
                status: "success",
                data: {
                } //this is the transfer object
              }
            
6. Get Wallet Balance It’s inevitable that you’d want to know your wallet balance. To gain access to this information, you need to send a GET request to /v1/wallet.
A sample request could look something like this [GET] /v1/wallet
A sample response could look something like this
1
2
3
4
5
              {
                status: "success",
                data: {
                } //this is the transfer object
              }
            
Error codes FAQ
Below are some errors that you can encounter when calling the moneywave API.
1
2
3
4
5
6
7
8
9
10
11
12
              HTTPS/1.1 400 Bad Request {
                status: "error",
                code: "INVALID_ID", message: ""
              }

              HTTPS/1.1 401 Unauthorized {
                status: "error"
              }

              HTTPS/1.1 404 Not found {
                status: "error"
              }