Installments
Configure MSI and MCI campaigns, retrieve the options that apply to an order, and send the customer's exact selection with the payment.
On this page
Installment campaigns turn merchant rules into payment options that DEUNA can show for a specific order and card. A campaign does not charge the customer by itself. It defines which terms are eligible; the checkout retrieves those terms and the purchase sends the exact option the customer selected.
What is an installment campaign?#
A campaign is a merchant-scoped set of eligibility and pricing rules. In the DEUNA Admin, you choose the campaign type, currency, validity period, payment providers, installment terms, and card-brand rules. Each card-brand rule can define a minimum and maximum per-installment amount and the applicable rate or merchant cost.
At checkout, DEUNA combines the campaign with the live payment context. An option is returned only when the relevant conditions match.
| Campaign or payment context | How it affects the result |
|---|---|
| Merchant, store, status, and dates | The campaign must belong to the merchant, apply to the order's store, be active, and be within its validity period. A campaign with no store override applies to all. |
| Currency | The campaign option currency must match the order currency. |
| Card brand | DEUNA derives the brand from the supplied BIN or stored card and applies the matching brand rule. |
| Per-installment amount range | The calculated amount of each installment must meet the configured minimum and optional maximum for that term and brand. |
| Payment provider | At least one processor configured on the campaign must be eligible for the payment. |
| Routing constraints | Smart or dynamic routing can remove processors or installment terms that are not valid for the selected route. |
From campaign to payment#
For DEUNA Widgets, the supported checkout experience retrieves and presents applicable options. For a Direct API integration, your checkout performs the retrieval, displays the returned values, and sends the selection with Purchase V2.
1. Configure a campaign#
Open Installments configuration in the DEUNA Admin. A user needs permission to view installment campaigns; creating, editing, activating, or disabling them requires the corresponding edit permission.
- Choose
MSIorMCI, name the campaign, and confirm its currency. - Set an optional start and end date, or leave the campaign without a fixed validity window.
- Select one or more compatible payment providers.
- Add the installment terms to offer.
- For each term, enable the card brands and configure their per-installment amount range and rate or cost.
- Save and activate the campaign.
Provider support, commercial agreements, and account configuration determine which processors appear. Confirm unsupported or market-specific requirements with your DEUNA Technical Account Manager (TAM).
2. Retrieve applicable options#
Use the order token and a card BIN to retrieve the options for a new card. A stored-card flow can use its supported card identifier instead. Because eligibility depends on the order, a Direct API journey that displays installments before payment needs an order token before this request.
curl --request GET \
--url 'https://api.sandbox.deuna.io/merchants/transactions/orders/ORDER_TOKEN/installments?bin=411111' \
--header 'X-Api-Key: YOUR_PRIVATE_API_KEY' \
--header 'X-Merchant-ID: YOUR_MERCHANT_ID'const response = await fetch("https://api.sandbox.deuna.io/merchants/transactions/orders/ORDER_TOKEN/installments?bin=411111", {
method: "GET",
headers: {
"X-Api-Key": "YOUR_PRIVATE_API_KEY",
"X-Merchant-ID": "YOUR_MERCHANT_ID"
}
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"GET",
"https://api.sandbox.deuna.io/merchants/transactions/orders/ORDER_TOKEN/installments?bin=411111",
headers={
"X-Api-Key": "YOUR_PRIVATE_API_KEY",
"X-Merchant-ID": "YOUR_MERCHANT_ID"
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/merchants/transactions/orders/ORDER_TOKEN/installments?bin=411111",
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Api-Key: YOUR_PRIVATE_API_KEY",
"X-Merchant-ID: YOUR_MERCHANT_ID"
]
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/merchants/transactions/orders/ORDER_TOKEN/installments?bin=411111"))
.header("X-Api-Key", "YOUR_PRIVATE_API_KEY")
.header("X-Merchant-ID", "YOUR_MERCHANT_ID")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
)
func main() {
request, err := http.NewRequest("GET", "https://api.sandbox.deuna.io/merchants/transactions/orders/ORDER_TOKEN/installments?bin=411111", nil)
if err != nil { panic(err) }
request.Header.Set("X-Api-Key", "YOUR_PRIVATE_API_KEY")
request.Header.Set("X-Merchant-ID", "YOUR_MERCHANT_ID")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}See List installment options for the complete endpoint contract.
A returned option contains the values your checkout should display and preserve:
{
"installments": [
{
"installments": 6,
"installments_amount": 16667,
"display_installments_amount": "MXN 166.67",
"installment_rate": 0,
"display_installment_label": "6 payments of MXN 166.67 without interest",
"plan_option_id": "a4756a5f-7f9b-414d-8712-e3a9da2be337",
"installment_total_amount": 100000,
"display_installment_total_amount": "MXN 1,000.00"
}
]
}Amounts are expressed in the currency's minor unit. Use the display fields for customer-facing copy when they are returned, and keep the numeric fields for calculations and reconciliation.
3. Send the selected option#
Send both values from the same response item:
payment_source.card_info.installments: the selected number of installments.payment_source.card_info.installment.plan_option_id: the exact ID of that selected option.
{
"order_token": "ORDER_TOKEN",
"payer_info": {
"email": "customer@example.com"
},
"payment_source": {
"method_type": "credit_card",
"card_info": {
"card_id": "CARD_ID",
"installments": 6,
"installment": {
"plan_option_id": "a4756a5f-7f9b-414d-8712-e3a9da2be337"
}
}
}
}The number and ID must describe the same option. DEUNA uses the option ID to recover the resolved plan and eligible processors, and it uses the installment count in the payment request sent through the selected connection.
Continue with Create payment for the full Purchase V2 contract.
Implementation checklist#
- Show only the options returned for the current order and card context.
- Preserve
plan_option_idwith its correspondinginstallmentsvalue. - For MCI, show the returned financed total and installment amount before confirmation.
- Retrieve options again when the order amount, currency, card, or relevant payment context changes.
- Treat an empty options list as “no eligible campaign option,” not as a payment failure.
- Test with cards and payment providers approved for the configured campaign.