Skip to main content

Intro

An installment purchase splits one product’s price into parts paid over time. The customer pays the first installment at checkout; that payment opens an installment plan and saves their card, and the remaining installments are collected later — by you through the API, by the customer through a pay link, or automatically by Khaime on each due date.
The word is installment everywhere in the API. In the Partner API, “split” means marketplace commission (how one sale is divided between an operator and a sub-merchant), never paying in parts.

Context

Installments are set per product, like a price: a product carries an installment template (installment_plan) and every installment purchase of it follows that template. The first installment goes through the same checkout as any other payment (Create Payment Session or the dedicated Installment Checkout), so Gateway Routing and Multicurrency apply unchanged. Each paid installment is its own payment: it has its own transaction (visible with Get Transaction), credits the wallet, and can be refunded on its own. On top of that, the plan has its own lifecycle and webhook events. All amounts are integers in the smallest currency unit. Installment amounts are always whole units that add up exactly to the total charged.

Hows

1. Give the product an installment template

Set installment_plan when you create or update a product with the Marketplace Products endpoints:
Send { "enabled": false } to stop selling the product in installments. Product reads return installment_plan (or null).

2. Preview the schedule

Returns each installment’s amount and when it would fall due if the plan started today — see Installment Quote.

3. Take the first installment

"installment": { "enabled": true } also works on POST /payments/sessions, POST /payments/intents and POST /sdk/initialize. The response is a payment to complete in the browser: confirm Stripe with Stripe.js and the client_secret (3-D Secure is handled there), or redirect to payment_url for Paystack and Flutterwave. When the checkout is recorded the plan is created (installment_plan.created, status pending); when the customer pays, the first installment is paid, the plan becomes active, the card is saved and the remaining installments get their due dates — monthly from that day.

4. Collect the rest

Choose per plan: Automatic collection charges each installment on its due date and retries a failed charge after 1, 3 and 7 days. The third failure moves the plan to past_due; if the last retry fails too, the installment is marked failed and automatic collection stops for it (you can still charge it or send a pay link). Customers are emailed 3 days before each automatic charge and after each failed one.

5. Follow the plan

  • List and get plans for their status, amounts paid and due, and each installment’s status and due date.
  • Listen for the installment webhooks: installment_plan.created, .past_due, .completed, .cancelled and installment.paid, .failed, .due_soon.
  • installment.paid fires for every installment, however it was paid, with the payment_id of its transaction.
  • Installments paid through checkout or a pay link also fire payment.succeeded, with payment_type: "installment" and installment: { plan_id, position, total_installments }. Installments charged off session (the charge endpoint or automatic collection) are reported by installment.paid only.

Cancel and refund

  • Cancel a plan to stop collecting: unpaid installments are cancelled, paid ones are untouched.
  • Refund one installment with Refunds and installment: { plan_id, position } instead of a transaction ID. Only that installment’s money is returned, and the customer keeps access to the product while other installments remain paid.

Scope and environments

Every installment endpoint is scoped to your API key: plans of your business and, for a marketplace operator, its active sub-merchants — and only plans in the key’s environment. A sandbox key never sees or charges a live plan. Anything outside that scope answers 404 INSTALLMENT_PLAN_NOT_FOUND.

Error codes

Whys

Installments are a product setting rather than a per-checkout option so that every buyer of a product gets the same terms and the schedule a customer saw in the quote is the schedule they get. The first installment reuses normal checkout — instead of a separate “create plan” call — so it inherits gateway routing, currency conversion, fees and 3-D Secure without a second integration path, and saving the card happens as part of a payment the customer is already making. Later installments are recorded as their own payments (own transaction, wallet credit, payment.succeeded, refundable on their own) because that is what they are to accounting, reporting and refunds; the plan is the thread that ties them together. Charges need an Idempotency-Key because a network retry on a money-moving call must never charge twice; Khaime additionally refuses to charge an installment that is already paid, whatever the key.

Why nots

  • The schedule is monthly from the first payment; custom intervals and start dates are not configurable yet.
  • A template can’t mix percentage and amount installments.
  • Changing a product’s template doesn’t change existing plans — each plan keeps the amounts it was opened with.
  • POST /payments/charge (product-agnostic charges) doesn’t support installments — installments need a product with a template.
  • Cancelling a plan doesn’t refund paid installments; refund them separately.
  • A customer who defaults keeps their access unless the business revokes it; there is no automatic access revocation on default yet.