Getting started with the API

Examples are often the easiest way to explain. Feel free to head over to the next section though if you'd rather dive straight in!

Today, we are going to build a basic transfer workflow consisting of a deposit account, virtual nuban and an Interbank transfer. In this guide, we will perform the following steps to build our workflow:

  1. Setup Webhook
  2. Create a customer
  3. Create a bank account for the customer
  4. Transfer Funds to your Deposit Account
  5. Create Counterparty
  6. Create Interbank Transfer

First, you'll need to log into the Anchor Dashboard and copy your api-key. A sandbox key is infix with _test_ and a live key is infix with _prod_.

Setup Webhooks

You can configure webhook endpoints via APIs or Dashboard in your organisation to be notified about events from.

Some resources happen from external sources and it might take a while for them to be processed successfully. The only way to know when some resource has been done and created is through webhooks.

Create Customer

Once you have a valid key, you'll create a customer. Customers represent Individuals or businesses that you may create financial products for. Each Customer represents a legal entity and has information describing the customer. In this example I'll use myself - an individual owner.

curl --location --request POST 'https://api.sandbox.getanchor.co/api/v1/customers/' \
--header 'Content-Type: application/json' \
--header 'x-anchor-key: "YOUR API KEY"' \
--data-raw '{
    "data": {
        "type": "IndividualCustomer",
        "attributes": {
            "fullName": {
                "firstName": "Demond",
                "lastName": "Rutherford",
                "middleName": "Schuster"
            },
            "email": "[email protected]",
            "phoneNumber": "07061106107",
            "address": {
                "addressLine_1": "140 Percy Estates",
                "addressLine_2": "0186 Delfina Field",
                "city": "West Claudie",
                "state": "Ogun",
                "postalCode": "123456",
                "country": "NG"
            },
             "identificationLevel2": {
                "dateOfBirth": "1993-08-23",
                "gender": "Male",
                "bvn": "22222222222",
                "selfieImage": null
            },
             "identificationLevel3": {
                "documentType": "DRIVERS_LICENSE",
                "identityNumber": "ADK03784AA02",
                "expiryDate": "2022-09-23"
            },
            "isSoleProprietor": true,
            "description": "Catering services",
            "doingBusinessAs": "Neon Catering services"
        }
    }
}'
{
    "data": [
        {
            "id": "1658345328830-anc_ind_cst",
            "type": "IndividualCustomer",
            "attributes": {
                "createdAt": "2022-07-21T07:55:27",
                "address": {
                    "addressLine_1": "9772 Antonina Meadows",
                    "addressLine_2": "5365 Lelah Falls",
                    "country": "NG",
                    "city": "South Anitabury",
                    "postalCode": "123456",
                    "state": "Ogun"
                },
                "doingBusinessAs": "Neon Catering services",
                "soleProprietor": true,
                "fullName": {
                    "firstName": "Darius",
                    "lastName": "Cassin / Neon Catering services",
                    "middleName": "Graham",
                    "maidenName": null
                },
                "description": "Catering services",
                "email": "[email protected]",
                "verification": {
                    "level": "Tier 2",
                    "status": "approved",
                    "details": [
                        {
                            "status": "approved",
                            "type": "BVN",
                            "validatedItems": []
                        }
                    ]
                }
            }
        },

Create a Deposit Account

Next, you are going to create a depositAccount that will be attached to the customer. You'll receive a customerId from the create customer response that will be used to create deposit accounts.

curl --location --request POST 'https:api.sandbox.getanchor.co/api/v1/accounts' \
--header 'Content-Type: application/json' \
--header 'x-anchor-key: <YOUR API KEY>' \
--data-raw '{
    "data": {
        "type": "DepositAccount",
        "attributes": {
            "productName": "SAVINGS"
        },
        "relationships": {
            "customer": {
                "data": {
                    "id": "1648209373471-1ind_16503605370680",
                    "type": "IndividualCustomer"
                }
            }
        }
    }
}

You’ll get a 202 Status Code. We’re working to create your deposit account. In the webhook event response to create account you'll receive a **accountNumber**. These will be used to externally identify your account for transfers. Now, you have a deposit account that you can move money in an out of!

Every account is created with an accountNumber, also by default a virtual account number called Virtual Nuban is automatically created for you when you create a deposit account. However, you can also create multiple virtual account numbers that are associated with this account. You can view them as pointers to that deposit account - however, they are all valid account numbers that you can make bank transfers to. You can create and remove them without interfering with the underlying deposit account.

Transfer Funds to your Deposit Account

For technical reasons we’ve masked the accountNumber of your deposit account. You can fetch your virtual account number pointing to your deposit account by using

curl --location --request GET 'https:api.sandbox.getanchor.co/api/v1/virtual-nubans/:virtualNubanId' \
--header 'x-anchor-key: <YOUR API KEY>'
{
    "data": {
        "id": "16536414521610-anc_va",
        "type": "VirtualNuban",
        "attributes": {
            "createdAt": "2022-05-27T08:50:52",
            "bank": {
                "id": "1652805219127221-anc_bk",
                "name": "PROVIDUS BANK",
                "nipCode": "000023"
            },
            "accountName": "ANCHOR(Kathryn Bins)",
            "permanent": true,
            "currency": "NGN",
            "accountNumber": "9988727880",
            "status": "ACTIVE"
        },
        "relationships": {
            "settlementAccount": {
                "data": {
                    "id": "16534929448762-anc_acc",
                    "type": "DepositAccount"
                }
            }
        }
    }
}

Once you’ve retrieved the accountNumber of the virtualNuban. Now make a transfer to your bank account.

You should now have a balance on your account. To confirm the balance on your account, feel free to send a GET request using your accountId as shown below.

curl --location --request GET 'https:api.sandbox.getanchor.co/api/v1/accounts/balance/:accountId' \
--header 'x-anchor-key: <YOUR API KEY>'
{
    "data": {
        "availableBalance": 1000.0000,
        "ledgerBalance": 1000.0000
    }
}

Create Counterparty

Let's create a counterparty we can transfer to with this 3 steps:

  1. Verify Account Number
  2. Create counterparty

You need to collect the customer's account details and confirm that it’s valid before adding as a counterparty. This is to ensure you don’t send money to the wrong or invalid account.

When creating a counterparty, you need the bank of the counterparty. To get a list of supported banks you can transfer money to, send a GET request to List Banks.

curl --location --request GET 'https:api.sandbox.getanchor.co/api/v1/banks' \
--header 'x-anchor-key: <YOUR API KEY>'
{
    "data": [
        {
            "id": "16528052138160-anc_bk",
            "type": "Bank",
            "attributes": {
                "bankCode": "090365",
                "name": "CORESTEP MICROFINANCE BANK"
            }
        }

Next is to verify the account number by sending another GET request with the bankCode of the recipient destination bank you got from the List Banks and the recipient account number

curl --location --request GET 'https:api.sandbox.getanchor.co/api/v1/payments/verify-account/:bankCode/:accountNumber' \
--header 'x-anchor-key: <YOUR API KEY>'
{
    "data": {
        "id": "0",
        "type": "AccountDetail",
        "attributes": {
            "bank": {
                "id": "165280521817693-anc_bk",
                "name": "ZENITH BANK",
                "bankCode": "000007"
            },
            "accountName": "OLAMODE ADE SOBOKUNLE",
            "accountNumber": "0068970263"
        }
    }
}

To create a counterparty, account name(as returned from the verify account number), account number and bank code

curl --location --request POST 'https:api.sandbox.getanchor.co/api/v1/counterparties' \
--header 'x-anchor-key: <YOUR API KEY>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "data": {
        "type": "CounterParty",
        "attributes": {
            "accountName": "OLAMODE ADE SOBOKUNLE",
            "accountNumber": "0068970263",
            "bankCode": "000007"
    }
}'
{
            "id": "16541590000180-anc_cp",
            "type": "CounterParty",
            "attributes": {
                "createdAt": "2022-06-02T08:50:44",
                "bank": {
                    "id": "165280521817693-anc_bk",
                    "name": "FIDELITY BANK",
                    "bankCode": "000007"
                },
                "accountName": "OLAMODE ADE SOBOKUNLE",
                "accountNumber": "0068970263"
            }
        }

Now that you created a counterparty - you can send money to it!

Create Bank Transfer

Let's send NGN100 to our counterparty through a NIPTransfer request. A NIPTransfer is a bank transfer from your account to an external account. Insert the `counterpartyId from the last request and the **accountId`** of the account you created earlier.

curl --location --request POST 'https:api.sandbox.getanchor.co/api/v1/transfers' \
--header 'Content-Type: application/json' \
--header 'x-anchor-key: <YOUR API KEY>' \
--data-raw '{
    "data": {
        "type": "NIPTransfer",
        "attributes": {
            "amount": 10000,
            "currency": "NGN",
            "reason": "Olamide 3 again",
            "reference": "232hfndnbi2r72rgf29ufgb"
        },
        "relationships": {
            "account": {
                "data": {
                    "id": "16517725619924-anc_acc",
                    "type": "DepositAccount"
                }
            },
            "counterParty": {
                "data": {
                    "id": "16518495829780-anc_cp",
                    "type": "CounterParty"
                }
            }
        }
    }
}'
"id": "1659336551142270-anc_trsf",
            "type": "NIP_TRANSFER",
            "attributes": {
                "createdAt": "2022-08-01T06:49:11",
                "reason": "Olamide 3 again",
                "amount": 525000,
                "currency": "NGN",
                "reference": "232hfndnbi2r72rgf29ufgb"
                "status": "COMPLETED"
            },
            "relationships": {
                "counterParty": {
                    "data": {
                        "id": "16541598435180-anc_cp",
                        "type": "CounterParty"
                    }
                },
                "account": {
                    "data": {
                        "id": "16528784749272-anc_acc",
                        "type": "DepositAccount"
                    }
                },
                "customer": {
                    "data": {
                        "id": "16528620603600-anc_bus_cst",
                        "type": "BusinessCustomer"
                    }
                }
            }
        },

📘

Amounts are always denominated in kobo.

When you send the request, if there are no errors, the response comes back with a pending status, while the transfer is being processed.

You'll receive a notification to your webhook URL as the NIP transfer goes through every step of the process and finally settles in the destination account. Note that NIP transfers processing usually take between a few seconds and a few minutes. Test transfers always return success, because there is no processing involved.

Congrats on your first outgoing transfer!

Listen for Transfer status

When a transfer is initiated, it could take a few seconds or minutes to process. Once completed, Anchor sends the final status of the transfer as a POST request to your webhook URL.

{
            "id": "1659336551187174-anc_et",
            "type": "nip.transfer.initiated",
            "attributes": {
                "createdAt": "2022-08-01T06:49:11"
            },
            "relationships": {
                "transfer": {
                    "data": {
                        "id": "165933655115970-anc_trsf",
                        "type": "NIP_TRANSFER"
                    }
                },
                "counterParty": {
                    "data": {
                        "id": "16541598435180-anc_cp",
                        "type": "CounterParty"
                    }
                },
                "account": {
                    "data": {
                        "id": "16528784749272-anc_acc",
                        "type": "DepositAccount"
                    }
                },
                "customer": {
                    "data": {
                        "id": "16528620603600-anc_bus_cst",
                        "type": "BusinessCustomer"
                    }
                }
            }
        },
{
            "id": "1659336568640175-anc_et",
            "type": "nip.transfer.successful",
            "attributes": {
                "createdAt": "2022-08-01T06:49:29"
            },
            "relationships": {
                "transfer": {
                    "data": {
                        "id": "165933655115970-anc_trsf",
                        "type": "NIP_TRANSFER"
                    }
                },
                "counterParty": {
                    "data": {
                        "id": "16541598435180-anc_cp",
                        "type": "CounterParty"
                    }
                },
                "account": {
                    "data": {
                        "id": "16528784749272-anc_acc",
                        "type": "DepositAccount"
                    }
                },
                "customer": {
                    "data": {
                        "id": "16528620603600-anc_bus_cst",
                        "type": "BusinessCustomer"
                    }
                }
            }
        }
{
            "id": "1659354409308223-anc_et",
            "type": "nip.transfer.failed",
            "attributes": {
                "createdAt": "2022-08-01T11:46:49"
            },
            "relationships": {
                "transfer": {
                    "data": {
                        "id": "165935440306699-anc_trsf",
                        "type": "NIP_TRANSFER"
                    }
                },
                "counterParty": {
                    "data": {
                        "id": "16541598435180-anc_cp",
                        "type": "CounterParty"
                    }
                },
                "account": {
                    "data": {
                        "id": "16528784749272-anc_acc",
                        "type": "DepositAccount"
                    }
                },
                "customer": {
                    "data": {
                        "id": "16528620603600-anc_bus_cst",
                        "type": "BusinessCustomer"
                    }
                }
            }
        },

The response for a transfer also contains a unique transferID to identify this transfer. You can use this resource object ID to call the Fetch Transfer endpoint to fetch status and details of the transfer anytime you want.