Banking API v.2
The BPC Sandbox (further "Sandbox") is a sandbox test environment that allows you to try API and evaluate payment functionality.
Please take into consideration that Sandbox doesn't affect your banking networks, i.e. payments with virtual cards issued with Sandbox and other transactions related to live data (real money) do not take place in the Sandbox environment.
A productive environment must be used to interact with live data.
Get Started
Use Sandbox to try basic card management functions, such as: registering cardholders, issuing cards, setting card limits, transferring funds, etc.
Before you start using Sandbox, you need to create a Sandbox account and obtain an API security Token.
An API security Token gives authorization access to Sandbox API.
Sandbox "Main" page contains account information for Sandbox API, such as:
- API URL - main URL to use in Sandbox API methods;
- Token - API security Token.
Add a custom HTTP header field "X-API-KEY" with API security Token to your HTTP requests, for example:
X-API-KEY: YWdyYWRvYm9pbm92Omh6bG1lTTg
API Reference
You can find a full technical API Reference here.
Postman collection example
You can download Postman collection of API requests to test some basic card management functions of Sandbox.
Postman collection API settings:
- Page "Authorization", field "Type" choose "API Key";
- Field "Key", choose "X-API-KEY";
- Field "Value", fill in your API security Token (can be found on Sandbox "Main" page).
Sandbox specifics and restrictions
Sandbox is a test environment, there are some features and limitations that may not be present in a production environment.
Sandbox returns a Request-id
header in the Response (contains unique identifier of your request, may help with technical support).
Limitations:
- Sandbox supports only
EUR
currency. - You can create as many customers as you want. But only one account per customer will be created in the Sandbox. This restriction is added to simplify the Sandbox logic. In a real project you will be able to create as many accounts per cardholder as required.
- You can issue up to 20 virtual cards for up to 20 cardholders, one card for each cardholder. When you register with Sandbox, a pool of 20 cards is prepared for issuing. Production environment does not have such restrictions.
Banking API v.2 Use Cases
Using the Sandbox API, you can perform various use cases: issuing and working with virtual cards, receiving detailed information on transactions and etc., as well as financial services (issuing, managing and distribution of payment cards) too.
To test Sandbox API functionality, we suggest the following use case: 1. Create two cardholders (this function automatically creates accounts for these cardholders). 1. Issue a virtual card for the cardholders; 1. Set the spending limits of the card; 1. Top-up one of the issued cards; 1. Check the account balance of the card; 1. Perform transfer(s) between cards of different cardholders; 1. Get a list of transfers, filtered by debited card, then by credited card; 1. Block a card.
Create a cardholder
Cardholder is main entity (individual or business) that cards can be issued to. Create a new Cardholder resource with POST /cardholders request
.
Cardholder is a top-level resource, so this must be the first step in the business use case. When creating a Cardholder, corresponding Primary (default) card account being created for this cardholder. Required parameters for creating a Cardholder: billingAddress (country, postalCode), firstName, lastName, phoneNumber. You may specify additional optional fields for a Cardholder, or you can try to update Cardholder resource with new data later. See documentation for detailed Cardholder resource schema (you will need "for updating" option).
Request
curl --location --request POST 'https://dev.bpcbt.com/v2/cardholders' \
--header 'X-API-KEY: YOUR_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{
"billingAddress": {
"city": "Budapest",
"country": "HU",
"line1": "Szabadsag ter",
"line2": "9",
"postalCode": "1850",
"state": "Budapest"
},
"email": "d@harrxample.com",
"phoneNumber": "123123123",
"firstName": "Harry",
"lastName": "Waters",
"dateOfBirth": "1998-03-24",
"verification": {
"idType": "passport",
"documentId": "1111111111"
},
"status": "active"
}'
Response
{
"id": "3269_1640686122656",
"billingAddress": {
"city": "Budapest",
"country": "HU",
"line1":"Szabadsag ter",
"line2":"9",
"postalCode": "1850",
"state":"Budapest"
},
"email": "harry@example.com",
"phoneNumber": "123123123",
"firstName": "Harry",
"lastName": "Waters",
"dateOfBirth": "1998-03-24",
"verification": {
"idType": "passport",
"documentId": "1111111111"
},
"status": "active"
}
You also may fetch created resource using GET cardholders/{id}
API request. Repeat this step to register another cardholder. When perform P2P transfers, both card accounts will be involved.
Issue virtual cards
When you are done with cardholders, you may start issuing virtual cards for the Cardholders. Create new virtual card and assign it to a Cardholder. Virtual cards are issued in "active" state, there is no need in special activation procedure.
Required parameters for issuing virtual cards:
Field | Description |
---|---|
productName | Card product name (The request must include:"Visa"). At the moment, Sandbox is configured to issue only "Visa Classic" virtual cards. In the future, the list of card products can be expanded. |
cardholder | Unique identifier of the cardholder object. Take the value from first step, when you create a cardholder. |
Request
curl --location --request POST 'https://dev.bpcbt.com/v2/cards' \
--header 'X-API-KEY: YOUR_TOKEN' \
--header 'content-type: application/json' \
--data productName=Visa \
--data cardholder=3269_1640686122656
Response
{
"id": "100000007847",
"status": "active",
"productName": "Visa Classic",
"cardholder": "3269_1640686122656",
"account": {
"accountNumber": "3556978700000000037",
"balance": 0,
"currency": "EUR"
},
"embossedName": "",
"expiryDate": "202512",
"numberMask": "414364******8601",
"creationDate": "2022-02-02T12:32:07",
"blockingDate": "",
"pinDenialCounter": "0",
"spendingLimits": [
{
"amount": 1234,
"interval": "daily"
},{
"amount": 123450,
"interval": "monthly"
}
]
}
Sandbox returns new virtual Card resource in the response body.
Repeat API request to create virtual card for another Cardholder. You need at least 2 card accounts to make transfers between them.
Spending limits
Virtual cards are issued with spending limits (day limit: 1,000.00 EUR and card purchase month limit: 10,000.00 EUR). You can change a spending limit on the cards. Spending limits define limits amount of spending over interval of time. Setting spending limits is a card resource updating request.
The following card parameters can be updated:
status
spendingLimits
pin
resetPinCounter
reissueCard
For card updating, only one card parameter can be updated with one request. Updating spending limits with only one request, the other field will not be updated, see the API Reference for details.
Please note that pin
and reissueCard
are not Card resource fields. They are only available in update request and you will never see them in Card resource itself.
- When you try to set new
pin
for the card, it should be encrypted (with public key) in update request, see details in the API Reference. - When you use
reissueCard
parameter, it acts as a command to reissue the card and must contain the reason why the card should be reissued. Valid values for this parameter are: lost, stolen, damaged, expired.
Also, there is some specificity when you change card status. These are described in "Card blocking" use case. To set card spending limits, specify spendingLimits
parameter in your update request.
You can set or change as many different limits in one request as you want. Some limits may be already set upon card creating - it depends on Sandbox settings.
Request
curl --location --request POST 'https://dev.bpcbt.com/v2/cards' \
--header 'X-API-KEY: YOUR_TOKEN' \
--header 'content-type: application/json' \
--data-raw '{
"spendingLimits": [
{
"amount": 123035,
"interval": "monthly"
},{
"amount": 12130,
"interval": "daily"
}
]
}'
Response
{
"id": "100000007847",
"status": "active",
"productName": " Classic",
"cardholder": "3269_1640686122656",
"account": {
"accountNumber": "3556978700000000037",
"balance": 0,
"currency": "EUR"
},
"embossedName": "",
"expiryDate": "202512",
"numberMask": "414364******8601",
"creationDate": "2022-02-02T12:32:07",
"blockingDate": "",
"pinDenialCounter": "0",
"spendingLimits": [
{
"amount": 12130,
"interval": "daily"
},{
"amount": 123035,
"interval": "monthly"
}
]
}
Top-up the card
To perform card-to-card transfers, you need to add funds to the card account. Card top-up is Sandbox-only operation which allows you add funds. You will need to specify destinationCard
destination card number, amount
amount (in smallest currency units) and currency
currency. Remember that full card number is only available via GET /cards/{id}
method, and the only currency available in Sandbox is EUR.
The following request will add 125 EUR to a card account:
Request
curl --location --request POST 'https://dev.bpcbt.com/v2/topups' \
--header 'X-API-KEY: YOUR_TOKEN' \
--header 'content-type: application/json' \
--data amount=12500 \
--data currency=EUR \
--data destinationCard=array \
--data cardNumber=4143640071118601
Response
{
"id": "662691",
"amount": 12500,
"currency": "EUR",
"destinationCard": {
"cardNumber": "4143640071118601"
},
"creationDate": "2022-02-04T13:14:27",
"status": "approved",
"statusMessage": "",
"rrn": "000000348182"
}
The response contains newly created Top-up, which represents financial transaction information.
Check card account balance
After successful top-up request you may check that card account balance has changed.
Use GET /cards/{id}
request to get card account balance.
Request
curl --location --request GET 'https://dev.bpcbt.com/v2/cards/100000000012' \
--header 'X-API-KEY: YOUR_TOKEN'
Response
{
"id": "100000007847",
"status": "blocked",
"productName": " Classic",
"cardholder": "3269_1640686122656",
"account": {
"accountNumber": "3556978700000000037",
"balance": 143800,
"currency": "EUR"
},
"embossedName": "",
"expiryDate": "202512",
"numberMask": "414364******8601",
"number": "4143640071118601",
"cvc": "245",
"creationDate": "2022-02-02T12:32:07",
"blockingDate": "2019-08-24T14:15:22",
"pinDenialCounter": "2",
"spendingLimits": [
{
"amount": 1234,
"interval": "daily"
},
{
"amount": 123450,
"interval": "monthly"
}
]
}
Issuing transactions (transfer between cards)
You can try card-to-card (P2P) funds transfer.
Basically, all you need is to specify source card, destination card, and amount.
To make a P2P transfer, you will need virtual card number (PAN). This information on previously issued virtual cards can be obtained using the GET cards/{id}
request.
The next example will transfer 12 EUR to another cardholder (we assume that source card is the one you replenished in previous step, and destination card is the card of second cardholder).
Request
curl --location --request POST 'https://dev.bpcbt.com/v2/transfers' \
--header 'X-API-KEY: YOUR_TOKEN' \
--header 'content-type: application/json' \
--data-raw '{
"amount": 1200,
"currency": "EUR",
"sourceCard": {
"cardNumber": "4143640071118601",
"expiryDate": "202502"
},
"destinationCard": {
"cardNumber": "4143640037674631"
}
}'
Response
{
"id": "407930",
"amount": 1200,
"currency": "EUR",
"sourceCard": {
"cardNumber": "4143640071118601",
"expiryDate": "202502"
},
"destinationCard": {
"cardNumber": "4143640037674631"
},
"creationDate": "2022-03-17T12:07:04",
"status": "approved",
"statusMessage": "",
"rrn": "000000407928"
}
The response contains newly created P2P transfer object, which represents financial transaction information. It is much like Top-up resource, except that source card parameter is added. Repeat this step few times, transferring funds from one account to another and vice versa. Try to transfer amount greater that source account balance to see operation status.
Get list of transfers
After you perform some P2P transfers between accounts, you can request the list of transfers by source or destination card. When requesting Transfer resource collection, you should use cardNumberFltr query parameter, which is required. Also you may include in query parameters another optional filters:
- periodStartFltr - starting date of the period to filter the retrieved transactions list (inclusive). Date format is "2022-03-29".
- periodEndFltr - end date of the period to filter the retrieved transactions list (inclusive).
- statusFltr - only return transactions that have the given status. Allowed values are "approved", "declined".
Request
curl --location --request GET 'https://dev.bpcbt.com/v2/transfers?periodStartFltr=2022-03-29&cardNumberFltr=4143640071118601' \
--header 'X-API-KEY: YOUR_TOKEN' \
Response
{
"transfers": [
{
"id": "407930",
"amount": 1200,
"currency": "EUR",
"sourceCard": {
"cardNumber": "4143640071118601",
"expiryDate": "202512"
},
"destinationCard": {
"cardNumber": "4143640037674631"
},
"creationDate": "2022-03-17T12:07:04",
"status": "approved",
"statusMessage": "",
"rrn": "000000407928"
}, {
"id": "407975",
"amount": 15600,
"currency": "EUR",
"sourceCard": {
"cardNumber": "4143640071118601",
"expiryDate": "202512"
},
"destinationCard": {
"cardNumber": "4143640037674631"
},
"creationDate": "2022-02-17T13:32:41",
"status": "declined",
"statusMessage": "Insufficient Funds ...",
"rrn": "000000403548"
}
]
}
When retrieving the list of transfers, each resource object is equal the one you saw when performed transfers.
Block card
Blocking a card is a Card resource update request.
Only one card parameter per request should be changed.
As for card status updating, there are some restrictions. When you change card status, not all combinations of current status and new status are possible:
- for active status, any new status is allowed (e.g. blocked, lost, stollen);
- for blocked status, any new status is allowed (e.g. active, lost, stollen);
- for lost and stollen, no status change is allowed. You will get an error if you try to change such status. Use reissueCard parameter instead.
Request
curl --location --request POST 'https://dev.bpcbt.com/v2/cards/100000007847' \
--header 'X-API-KEY: YOUR_TOKEN' \
--header 'content-type: application/json' \
--data-raw '{
"status": "blocked"
}'
Response
{
"id": "100000007847",
"status": "blocked",
"productName": " Classic",
"cardholder": "3269_1640686122656",
"account": {
"accountNumber": "3556978700000000037",
"balance": 12100,
"currency": " EUR"
},
"embossedName": "",
"expiryDate": "202512",
"numberMask": "414364******8601",
"creationDate": "2022-02-02T12:32:07",
"blockingDate": "2022-03-08T15:04:22",
"pinDenialCounter": "0",
"spendingLimits": [
{
"amount": 12130,
"interval": "daily"
},{
"amount": 123035,
"interval": "monthly"
}
]
}
After updating a Card resource you get a modified resource in the response. Now, when the card is blocked, try to make some transfers using this card and check the operation status.