Prepaid cards
A prepaid card is requested with its own endpoints, because it works differently from a normal card:
- The card is not ready at once. So the request does not return a card. It returns a
prepaidRequestIdandstatus: "PENDING". The card is created in the background, usually in 2-3 minutes, and you ask for the status of the request until it is finished.
Endpoints
| Card | For | Endpoint | Product |
|---|---|---|---|
| Virtual | Individual | POST /individual/accounts/{id}/cards/prepaid/virtual | R008 |
| Physical | Individual | POST /individual/accounts/{id}/cards/prepaid/physical | R007 |
| Virtual | B2B cardholder | POST /business/cardholders/{id}/cards/prepaid/virtual | R008 |
| Physical | B2B cardholder | POST /business/cardholders/{id}/cards/prepaid/physical | R007 |
{id} is the individual's _id, or the B2B cardholder's _id. If it does not belong to your partner, the answer is 404.
The product is fixed for each endpoint. You can leave productCode out; if you send it, it must match the table. For a B2B cardholder, the product must also be assigned to the company (see GET /business/accounts/{b2bAccountId}/products).
Prepaid virtual card
The body is optional. Every field has a default.
| Field | Required | Meaning |
|---|---|---|
productCode | no | Only R008. This is the default. |
currencyCode | no | Only EUR. This is the default. |
nickname | no | A name for the card, shown in your own screens. |
Smallest request (empty body):
{}
Request with a nickname:
{
"nickname": "Online shopping"
}
Prepaid physical card
A physical card is shipped and costs money, so it needs more information.
| Field | Required | Meaning |
|---|---|---|
deliveryMethod | yes | How the card is sent (carrier). An object; only _id is required. See below. |
phoneNumber | yes | Contact phone for the delivery. |
country | yes | Country used for the fee when there is no deliveryAddressId. See below. |
embossName1 | yes | First line printed on the card (up to 22 characters). |
embossName2 | no | Second line printed on the card (up to 19 characters). |
deliveryAddressId | no | Where the card is sent. A saved address of the cardholder. See below. |
debitAccountNumber | no | The main account (IBAN) the fees are charged from. See below. |
nickname | no | A name for the card. |
productCode | no | Only R007. This is the default. |
The delivery fee is not taken only from deliveryMethod. Both of these matter:
| Input | Role for the fee |
|---|---|
deliveryMethod._id | Chooses the carrier (DHL or Poczta Post). That picks which fee rule is used (express vs normal). For some DHL cases a price from that method’s record is also added. |
| Delivery country | Chooses EEA vs non-EEA pricing. Taken from the saved address when deliveryAddressId is sent; otherwise from the country field. |
So: deliveryMethod = how it is sent; country / address = where, and that where affects the price.
deliveryMethod: how the card is sent
- Ask which methods exist for a country:
GET /fees/delivery-methods?country=BG(two-letter country code). That list only shows which carriers/methods are available for that country — it is not the final charged fee by itself. - Take the
_idof the method you want and send it:
"deliveryMethod": { "_id": "dhl-air-1" }
Only _id is required. The carrier is read from the start of the _id (dhl-… is DHL, pp_poczta-… is Poczta Post). deliveryType, pinDeliveryType, methodFields and price are optional; any price you send is not used as the charged fee — the server calculates the fee again.
deliveryAddressId: where the card is sent
- Left out: the card goes to the cardholder's registered address. Most requests do this. The fee then uses the
countryfield. - Sent: the card goes to that saved address, and that address’s country is used for the fee. The
countryfield is then ignored for pricing.
country
Required. Used for the delivery fee when you do not send deliveryAddressId. Send the country of the registered address (ISO 3166-1 alpha-3, for example BGR).
debitAccountNumber: who pays the fees
The card issuing fee and the delivery fee are charged from a main account of the cardholder (for a B2B cardholder, an account of the company).
- Sent: that account is used. It must belong to the cardholder (or the company), otherwise the request is refused with
400. - Left out: the default main account is used.
Example: smallest valid request
{
"deliveryMethod": { "_id": "dhl-air-1" },
"phoneNumber": "+359888123456",
"country": "BGR",
"embossName1": "ANA IVANOVA"
}
The card goes to the registered address, and the fees are charged from the default main account.
Example: full request
{
"productCode": "R007",
"nickname": "Travel card",
"deliveryMethod": { "_id": "pp_poczta-6836df4c98653594cae54d72" },
"phoneNumber": "+359888123456",
"country": "BGR",
"deliveryAddressId": "onboarding:6836df4c98653594cae54d99",
"embossName1": "ANA IVANOVA",
"embossName2": "ACME LTD",
"debitAccountNumber": "BG09TRUD40059780001111"
}
The answer
Both kinds of card answer the same way, with HTTP 200:
{
"message": "Prepaid physical card requested. The card will be created in a few minutes (2-3 minutes).",
"data": {
"prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
"cardKind": "physical",
"cardholderId": "6836df4c98653594cae54d72",
"productCode": "R007",
"currency": "EUR",
"status": "PENDING"
}
}
status: "PENDING" means the request was accepted. It does not mean the card exists yet. Keep the prepaidRequestId: you use it to check the status.
Fees of a physical card
The fees are handled in two steps, so the cardholder cannot spend the money while the card is being prepared:
- When you call the endpoint, the card issuing fee and the delivery fee are blocked on the main account. If the account does not have enough money, the request is refused with
400and nothing is blocked. - When the card is created, the blocked fees are charged. If the card cannot be created, the fees are unblocked.
To show the price before you request the card, use POST /fees/issuing-fee and POST /fees/delivery-fee. For a prepaid card use ProductType R007 and CustomerType Consumer Prepaid (individual) or Business Prepaid (B2B cardholder).
Check the status of a request
The request answers right away, but the card is created later. To know where the request is, ask for its status:
| Endpoint | What it returns |
|---|---|
GET /individual/accounts/{id}/cards/prepaid/{requestId} | One request of an individual |
GET /individual/accounts/{id}/cards/prepaid | All the requests of an individual, newest first (up to 100) |
GET /business/cardholders/{id}/cards/prepaid/{requestId} | One request of a B2B cardholder |
GET /business/cardholders/{id}/cards/prepaid | All the requests of a B2B cardholder, newest first (up to 100) |
GET /cards/prepaid | All the requests of all your cardholders (individuals and B2B), newest first |
GET /cards/prepaid needs no cardholder id. Each item has a cardholderId, and you can use page and limit.
{requestId} is the prepaidRequestId from the answer. A request that does not exist, or belongs to another cardholder, is a 404.
Statuses
A request has one of three statuses. SUCCESS and FAILED are final.
status | isFinished | What it means |
|---|---|---|
PENDING | false | The card is not ready yet. The request is being processed, usually for 2-3 minutes. |
SUCCESS | true | The card is ready. cardKey is the key of the card. |
FAILED | true | The request could not be completed. Contact PayNovus support (see below). |
Ask again every few seconds/minutes, and stop when isFinished is true.
In progress:
{
"data": {
"prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
"cardKind": "physical",
"cardholderId": "6836df4c98653594cae54d72",
"productCode": "R007",
"currency": "EUR",
"status": "PENDING",
"isFinished": false,
"statusMessage": "The card is being created. This usually takes 2-3 minutes.",
"cardKey": null,
"feesReleased": false,
"createdAt": "2026-10-08T10:15:00.000Z",
"statusUpdatedAt": "2026-10-08T10:17:10.000Z"
}
}
Finished: status is SUCCESS, isFinished is true, and cardKey has the key of the new card. Use it with the /cards/{cardKey} endpoints.
Failed:
{
"data": {
"prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
"cardKind": "physical",
"status": "FAILED",
"isFinished": true,
"statusMessage": "The request could not be completed. For more information, please contact PayNovus support and give the prepaidRequestId.",
"cardKey": null,
"feesReleased": true
}
}
A failed request does not say why. For more information, contact PayNovus support and give the prepaidRequestId. A failed request is not retried by itself.
For a physical card, feesReleased: true means the fees that were blocked for the card were unblocked.
You can also find the finished card in the card list of the cardholder: GET /individual/accounts/{id}/cards or GET /business/cardholders/{id}/cards.
You are not notified when the card is ready. Ask for the status of the request.
Load a prepaid card
A prepaid card spends only the money loaded on it. You load it from a main account of the card's owner:
- a card of an individual is loaded from the individual's own accounts;
- a card of a B2B cardholder is loaded from the company's accounts.
The money never moves between two owners.
| Endpoint | What it does |
|---|---|
GET /cards/{cardKey}/prepaid/load-options | The card and its balance, and the accounts it can be loaded from |
POST /cards/{cardKey}/prepaid/loads | Loads the card |
GET /cards/{cardKey}/prepaid/loads/{loadId} | One load: ask for it until it is finished |
GET /cards/{cardKey}/prepaid/loads | The loads of the card, newest first |
- Ask for the load options. Each item of
sourceAccountsis an account the card can be loaded from, with itsavailableBalance. The default account is first. - Load the card with the
idof the account assourceAccountId:
{
"sourceAccountId": "6836df4c98653594cae54d80",
"amount": "25.00",
"idempotencyKey": "3f6c2a1e-9b7d-4c1a-8e2f-5d4b3a2c1e0f"
}
amount has at most two decimals. idempotencyKey is required: make a new one (e.g. a UUID) for each load. If you send a key you already used, the answer is 409 with code: "LOAD_ALREADY_EXISTS" and nothing is paid again. The key is checked against your own loads only.
- Ask for the load until it is finished. The answer of step 2 is
201with the load:
status | What it means |
|---|---|
SUBMITTED | The bank accepted the payment and is booking it, usually in a few seconds. |
SUCCESS | The money is on the card. Final. |
FAILED | The payment was not made. No money moved. Final. |
UNCONFIRMED | The bank did not answer, so the money may or may not have moved. PayNovus checks it. Do not load the card again. |
While a load of the card is not finished, a new load of the same card is refused with 409.
Balance of prepaid cards
GET /cards/prepaid/balances?cardKeys=a,b,c returns the money on each card, up to 50 cards per request:
{
"data": [
{ "cardKey": "1000234567", "found": true, "currency": "EUR", "availableBalance": 25.5 },
{ "cardKey": "1000234568", "found": false, "currency": null, "availableBalance": null, "message": "Card not found" }
]
}
found: false means the card does not exist, is not a prepaid card, or is not one of yours. availableBalance: null means the balance could not be read right now; it is not zero.
Common errors
| Status | Why |
|---|---|
| 400 | The product is not allowed (wrong code, or not assigned to the company). |
| 400 | Not enough money on the main account for the card fees (physical card). |
| 400 | The prepaid physical card limit is reached. This limit is separate from the limit of normal physical cards. |
| 400 | deliveryMethod is not valid, the delivery address is not valid, or debitAccountNumber is not an account of the cardholder. |
| 400 | A required field is missing (phoneNumber, country, embossName1, deliveryMethod). |
| 404 | The individual or cardholder does not belong to your partner. |
| 409 | Load: you already used the idempotencyKey, a load of the card is not finished yet, or the card can not be loaded right now. |
| 422 | Load: not enough money in the source account. Nothing was paid. |
See the full request and answer shapes in the API reference: Individual accounts → and Business accounts (B2B) →.