Payment Orchestrator
Multiple Cards

Multiple Cards

Paying with multiple cards splits one order into parts made of cards only. For example, a ₺1,000 order = Card A ₺600 + Card B ₺400. The amount is first held on each card; once every card's hold is taken, the holds are captured and the order is complete. If a card's hold cannot be taken, the holds on the other cards are released and no money is taken from the cards.

This page covers what is specific to cards. What both ways of splitting share is on the Split Payments page:

If you use cards together with non-card methods, see also Multiple Payment Methods. The card rules on this page apply there too.

Card part

  • Each part uses a different card.
  • In the Checkout Form the buyer enters the cards in the form.
  • In the API the card parts are stored cards of the same cardholder: the owner's key goes in ownerRef, the cards' tokens in cardToken.
  • A card part cannot carry a method block.

Installments on a card part

Each card part can choose its own installments.

  • The installment fee is added on top of that part's amount. The order amount does not change; the parts still add up to the order amount.
  • Installments need a binding installment quote, and the quote is taken with the part's amount. In the Checkout Form the form does this; for the API see Card part fields.
  • If installments are off or the card does not support them, the part is charged in a single payment.
  • In a payment with insurance and in a payment with a credit approval, card parts are charged in a single payment; details: Insurance, Credit part.
  • The installment count and the charged amount including the installment fee of a card part are in the leg's installmentCount and chargeAmount fields of the GET /payments/split/:id response.

With the Checkout Form

The buyer selects the Pay with more than one method entry in the method list, adds their cards as parts and distributes the amount across the cards. For each card part they can choose installments; the installment fee is shown per part. When the payment starts, the form runs the cards' 3D Secure verifications one after another.

Enabling the form and the steps of the flow: Split Payments › With the Checkout Form.

The request the form sends

This request is for reference; the Checkout Form SDK sends it and you do not need to call it.

POST https://api-gateway.lunixi.com/api/v1/payments/form/split/init
{
  "token": "<form-token>",
  "legs": [
    { "cardToken": "<card-1-token>", "amount": 60000 },
    { "cardToken": "<card-2-token>", "amount": 40000, "installment": 3, "installmentQuoteToken": "<installment-quote>" }
  ]
}
  • cardToken is a single-use token produced by the form's secure card fields; no card data is in the body.
  • The form takes the quote of a part with installments using the part's amount.
  • The response carries the step list (steps), the expected step (pendingStep) and the main payment's paymentId. The other form endpoints: Endpoint reference.

3D Secure display

In the panel, under Payments → Form Settings → 3D Secure → 3D Secure display, you choose how a card part's 3D Secure verification opens:

OptionWhat happens
Within the form (default)The bank's verification screen opens in a window over the form. When verification finishes, the window closes and the form moves to the next step. The buyer stays on your page until the end of the payment
On a separate pageThe buyer is redirected to the bank's page. The bank returns the buyer to the continuation page; the remaining steps run there
  • Automatic separate page: With Within the form selected, if the bank does not allow its verification screen to open in a window, 3D Secure for the same card is automatically restarted on a separate page and the payment continues on the continuation page.
    • The buyer does not enter the card again and no second hold is placed on the card.
    • The restart happens once per card part. A new request after the separate page has been opened gets 409 split_pay.three_ds.restart_exhausted. If the separate page has not been opened yet, the same request returns the same response.
    • If the bank's 3D Secure session is closed or has expired, no restart is made: 410 split_pay.three_ds.restart_expired. The buyer is then asked to enter the card again.
  • The choice is fixed when the split payment starts. Changing the setting does not affect a payment in progress.
  • The threeDsDisplay field in the form responses (INLINE or REDIRECT) shows the choice the payment started with.
  • The choice applies only to the Checkout Form path. In a split payment started from the API, the buyer returns to your callbackUrl after 3D Secure.

Continuation page

After 3D Secure on a separate page, the bank returns the buyer not to your site but to a payment continuation page hosted by Lunixi (https://api-gateway.lunixi.com/api/v1/payments/split/return/…). You do not need to write code or change settings for this page.

  • The page runs all remaining steps of the payment in order: the next card's 3D Secure redirect, a verification code or requested data for a non-card part, waiting for credit approval. For example, in a payment with three cards and mobile billing, the cards' 3D Secure verifications and the verification code screen come one after another on this page.
  • The remaining time and the step list are shown on the page.
  • The buyer does not return to your site in the middle of the payment. When the payment concludes, the page sends the buyer to your callbackUrl with the result.
  • The link works in a single window. If the same link is opened in a second window, the buyer sees "your payment is continuing in another window" (409 split_pay.resume.already_opened).
  • The link is valid for the split payment's time limit plus 15 minutes. An expired or unrecognized link gets 410 split_pay.resume.unavailable and the page shows "invalid link". If the result becomes final after that, it reaches you by webhook.
  • This page is separate from the continuation link sent by email when a credit approval is delayed.

The result sent to your callbackUrl

When the payment concludes on the continuation page, the buyer's browser is sent to the callbackUrl you gave on the intent with the same signed form POST (application/x-www-form-urlencoded) as the single-card 3D Secure return:

FieldMeaning
paymentIdThe order's payment record (main payment). Part identifiers are not sent
orderIdYour order reference from the intent (only if set on the intent)
statussuccess, failure or pending (below)
success"true" only when status is success; otherwise "false"
codeThe split payment's status, e.g. COMPLETED, VOIDED; see Statuses
messageHuman-readable result message
_timestamp, _signaturePlatform integrity fields; same format as 3D Form › Signed POST
Split payment statusstatus
COMPLETEDsuccess
VOIDED, FAILED, COMPENSATINGfailure
RECONCILIATION_REQUIREDpending
  • If the intent has no callbackUrl, the result is shown on the continuation page.
  • This POST is for managing the buyer's interface. Do not treat the order as paid based on it: the final result is the main payment's payment.captured event and GET /payments/{paymentId}.
  • With Within the form selected, the payment completes in the window; the buyer is already on your page and this POST is not sent.

With the API

Send only card parts in the POST /api/v1/payments/split request. Authentication, Idempotency-Key, the top-level fields and the response: Split Payments › With the API.

Request

curl https://api-gateway.lunixi.com/api/v1/payments/split \
  -H "Authorization: Bearer <access-token>" \
  -H "X-Key-Id: <kid>" \
  -H "X-Date: <iso-8601>" \
  -H "X-Nonce: <single-use-value>" \
  -H "Digest: SHA-256=<base64>" \
  -H "X-Signature: <ed25519-signature>" \
  -H "Idempotency-Key: split-order-2026-002" \
  -H "Content-Type: application/json" \
  -d '{
    "totalAmount": 100000,
    "currency": "TRY",
    "ownerRef": "cuk_abc123",
    "orderId": "order-2026-002",
    "callbackUrl": "https://shop.example/payment-return",
    "legs": [
      { "cardToken": "ct_cardA", "amount": 60000, "force3D": true },
      { "cardToken": "ct_cardB", "amount": 40000, "installment": 3, "installmentQuoteToken": "iq_…" }
    ]
  }'

The first card is taken as a 3D Secure hold, the second in 3 installments. Because force3D is sent, callbackUrl is required.

Card part fields

FieldRequiredDescription
paymentMethodNoOmitted or CARD
cardTokenYesThe stored card's token
amountYesThe part's amount, minor units
force3DNotrue: the part is taken as a 3D Secure hold; callbackUrl becomes required
installmentNoNumber of installments; 1 or omitted means a single payment
installmentQuoteTokenWhen installment is 2 or moreThe part's installment quote: in the POST /bin/installments call send the part's amount as amount and do not send intentId. Put the returned quoteToken in this field

A card part cannot carry a method block.

3D Secure step

When the turn of a card part sent with force3D comes, pendingStep.step in the response is THREE_DS:

{
  "success": false,
  "code": "AWAITING_3DS",
  "data": {
    "splitPaymentId": "b1e4…",
    "status": "AWAITING_3DS",
    "pendingStep": {
      "legId": "leg-1",
      "sequence": 1,
      "step": "THREE_DS",
      "paymentMethod": "CARD",
      "providerCode": null,
      "amount": 60000,
      "paymentId": null,
      "actionId": null,
      "redirectPath": "/api/v1/payments/threed/9c41…",
      "action": null
    },
    "expiresAt": null
  }
}
  1. Redirect the buyer without delay to https://api-gateway.lunixi.com + redirectPath.
  2. When the buyer completes verification, they return to your callbackUrl; the split payment moves on to the next card by itself.
  3. Read the current step by sending the same request with the same Idempotency-Key (duplicate: true, no new charge). If the next card also awaits 3D Secure, pendingStep.step is THREE_DS again and carries a new redirectPath.
  4. When every card's hold is taken, the cards are captured and the result arrives with the main payment's payment.captured event.
⚠️

Abandoned 3D Secure. If the buyer never completes the verification, a background cleanup (about 15 minutes) finalizes the pending authorization; the split payment compensates, the holds taken are released and it ends VOIDED. While 3D Secure is awaited no part has been charged.

3D Secure holds may not be enabled on every installation. On an unsupported setup a force3D part ends with an open decline (FAILED) without charging, and the split payment is compensated; a part is never silently charged without 3D Secure.

The compensation rules that apply when a card part fails: Failure and compensation.

Related pages