Offers & installment plans
This specification describes how to show a financing offer and an installment calculator in your app.
Note
You need this only if you use:
In all other integrations, myFlowpay shows the offer and the calculator, and you do not need to implement anything.
sequenceDiagram
autonumber
participant App as Your app
participant Backend as Your backend
participant FP as Flowpay Partner API
Backend->>FP: Request offer
FP-->>Backend: Offer
Backend-->>App: Offer
loop Customer changes product, amount or deferral
alt JavaScript SDK
App->>App: Calculate installment plan
else Partner API
App->>Backend: Customer's choice
Backend->>FP: Calculate installment plans
FP-->>Backend: Plans
Backend-->>App: Plans
end
end
App->>Backend: Customer's choice
Backend->>FP: Submit application
1. Get the offer
POST /partner-api/v1/customers/{id}/offer-request – Request recent financing offer
The response contains one item in products for each product the customer can get. The response is empty (204) when the customer has no offer, for example because they are not eligible or already have an active application.
All fields are described in the API reference. For your UI:
balloon–true: installments cover the fee only and the whole amount is paid with the last installment.false: the amount is split evenly across installments, and every installment has the same fee.postponeEnabled,prolongationEnabled– the product allows deferral, see Deferral.interestRateMultiplier,postponeFeeMultiplier,prolongationFeeMultiplier– inputs for the calculator. Pass them on unchanged.
Other offer calls
- Recalculate the offer after new data:
POST /partner-api/v1/customers/{id}/offer-request-async– Request financing offer recalculation. Wait for thecustomer-scoringwebhook withresultOFFER, then request the offer again. - Get an offer by its identifier, for example
flowpayOfferIdfrom Bulk offers:GET /partner-api/v1/offers/{id}– Get offer.
2. Calculate the installment plan
Let the customer choose a product, an amount and a deferral, and show the installment plan for the choice. Calculate it with the JavaScript SDK or with the Partner API. Both give the same result.
| JavaScript SDK | Partner API | |
|---|---|---|
| Runs in | Your web app or Node.js backend | Flowpay, called from your backend |
| Speed | Instant | One API call per calculation |
| Use for | Web apps | Mobile apps, backends not in JavaScript |
Note
The calculated plan is only indicative and nothing is saved. Final terms are set when the application is approved.
Option A – JavaScript SDK
import { calculateInstallmentPlan, getCalculatorParams, ProductType } from "@flowpay-io/offer";
const product = offer.products.find((p) => p.product === ProductType.M6)!;
// deferMonths: value of your "defer by N months" control, from 0 to getMaxDeferLength(product)
const { postponeLength, prolongation } = getCalculatorParams(product, deferMonths);
const plan = calculateInstallmentPlan(offer, ProductType.M6, 150000, new Date(), postponeLength, prolongation);
if (plan === null) {
// amount or deferral is not allowed for this product
} else {
plan.feeMonthly; // 1500
plan.amountTotal; // 159000
plan.installments; // [{ index, principal, fee, dueDate }, ...]
}
offer is the response from step 1, unchanged. With a promo code, pass the preview response instead, see Promo codes. All functions are described in the package README.
Option B – Partner API
POST /partner-api/v2/installment-plans/calculate – Calculate installment plans
Call it from your backend, it needs your access token. The call does not load your customer's offer stored at Flowpay, so it stays fast enough for interactive use. It calculates only from the data you send.
All fields are described in the API reference. In short:
- Send all products of the offer to get a plan for each of them in one call.
- Copy the product fields from the offer. Only
productis renamed toproductType. - Set the customer's choice in
principal,postponeLengthandprolongation, see Deferral. - With a promo code, also send
baseRatePerc, see Promo codes.
Request
curl -X POST "https://api.test.flowpay.io/partner-api/v2/installment-plans/calculate?view=summary" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"principal": 150000,
"startDate": "2026-11-02",
"products": [
{
"productType": "M3",
"currency": "CZK",
"ratePerc": 1,
"balloon": true,
"installmentCount": 3,
"minAmount": 100000,
"maxAmount": 400000,
"prolongationEnabled": true,
"maxProlongationLength": 1
},
{
"productType": "M6",
"currency": "CZK",
"ratePerc": 1,
"balloon": false,
"installmentCount": 6,
"minAmount": 100000,
"maxAmount": 600000,
"postponeEnabled": true,
"maxPostponeLength": 2
}
]
}'
Response
The view query parameter sets the level of detail:
view |
Use for | Returns |
|---|---|---|
summary (default) |
Interactive preview while the customer chooses the product, amount and deferral. Call about 300 ms after the last change, not on every slider move. | Main figures of each plan. |
full |
Installment overview with the repayment schedule, for example before the customer submits the application. | Main figures, all installments and deferral fees. |
For example, the preview can show the monthly fee (feeMonthly) and the total to repay (amountTotal) for each product. The installment overview can also show the repayment schedule (installments) and the deferral fee (feePostponeTotal or feeProlongationTotal).
A product that cannot be used with the chosen amount or deferral does not fail the call. Its plan has eligible: false and an ineligibleReason, see the table below.
{
"plans": [
{
"productType": "M3",
"eligible": true,
"feeMonthly": 1500,
"amountTotal": 154500,
"regularInstallmentAmount": 1500,
"lastInstallmentAmount": 151500,
"installmentCount": 3,
"firstDueDate": "2026-12-05"
},
{
"productType": "M6",
"eligible": true,
"feeMonthly": 1500,
"amountTotal": 159000,
"regularInstallmentAmount": 26500,
"lastInstallmentAmount": 26500,
"installmentCount": 6,
"firstDueDate": "2026-12-05"
}
]
}
Same request with the M6 product only:
{
"plans": [
{
"productType": "M6",
"eligible": true,
"feeMonthly": 1500,
"amountTotal": 159000,
"regularInstallmentAmount": 26500,
"lastInstallmentAmount": 26500,
"installmentCount": 6,
"firstDueDate": "2026-12-05",
"balloon": false,
"postponeLength": 0,
"prolongationLength": 0,
"principal": 150000,
"feePostponeMonth": 1500,
"feePostponeTotal": 0,
"feeProlongationMonth": 0,
"feeProlongationTotal": 0,
"installments": [
{ "index": 1, "principal": 25000, "fee": 1500, "dueDate": "2026-12-05" },
{ "index": 2, "principal": 25000, "fee": 1500, "dueDate": "2027-01-05" },
{ "index": 3, "principal": 25000, "fee": 1500, "dueDate": "2027-02-05" },
{ "index": 4, "principal": 25000, "fee": 1500, "dueDate": "2027-03-05" },
{ "index": 5, "principal": 25000, "fee": 1500, "dueDate": "2027-04-05" },
{ "index": 6, "principal": 25000, "fee": 1500, "dueDate": "2027-05-05" }
]
}
]
}
ineligibleReason |
Cause |
|---|---|
AMOUNT_OUT_OF_RANGE |
principal is not between minAmount and maxAmount. |
POSTPONE_NOT_ALLOWED |
postponeLength is set for a product without postponement. |
POSTPONE_TOO_LONG |
postponeLength is above maxPostponeLength, or not lower than installmentCount. |
PROLONGATION_NOT_ALLOWED |
prolongation is set for a product without prolongation. |
Errors
| HTTP status | Cause |
|---|---|
400 |
A required field is missing, an amount is negative, there are more than 6 products, or a product type is repeated. |
Deferral
Show one "defer by N months" control. Each product defers in one of two ways:
| Product | Send | Effect |
|---|---|---|
postponeEnabled is true |
postponeLength: N, up to maxPostponeLength |
The first N installments contain no repayment of the amount, only the fee and a postpone fee. The number of installments stays the same. |
Only prolongationEnabled is true, for example M1 and M3 |
prolongation: true |
The first installment contains no repayment of the amount, only the fee and a prolongation fee. One installment is added at the end. |
With the SDK, getCalculatorParams does this for you.
3. Submit the application
Fully Embedded (Native)
POST /partner-api/v2/financings – Submit financing application
| Customer's choice | Request field |
|---|---|
Offer id |
offerId |
| Product type | product.type |
| Amount | product.amount |
| Currency | product.currency |
postponeLength |
product.postponedPeriods |
prolongation |
product.prolonged |
| Promo code | promoCodeSlug, see Promo codes |
The rate is taken from the offer stored at Flowpay, identified by offerId.
Embedded (iFrame), customer integration type
Start the application with the same offerId and product, then launch the embed, see Integration types.
Changed terms
Flowpay can approve the application with different terms, for example a lower amount. The financing then moves to state WAIT_NEW_CONDITIONS (see the financing-state webhook) and waits until the customer accepts or rejects the new terms.
Fully Embedded (Native) – show the new terms to the customer and send their decision:
POST /partner-api/v2/financings/{id}/accept-changed-terms– Accept changed termsPOST /partner-api/v2/financings/{id}/reject-changed-terms– Reject changed terms
Other integrations – the customer accepts or rejects the new terms in myFlowpay. You do not need to call these endpoints.