Installment Payments
Topics covered on this page
Installment payments allow customers to split one large payment into several smaller payments over a fixed period. Omise offers a new installment payment flow and a set of APIs that allow you to offer your customers this convenient payment method.
For the legacy integration with installment payments using the redirect payment flow, see the Redirect Integration.
How to enable
- Supported Countries: Thailand
- Minimum API version:
2017-11-02
To enable Installment Payments, send an email requesting this feature to support@omise.co. You will need to review and accept the new terms and conditions.
Supported cards
| Credit Card | Source type | Installment Term Lengths (months) | Minimum Monthly Amount (THB) |
|---|---|---|---|
| Krungsri | installment_wlb_bay | 3, 4, 6, 9, 10 | 500 |
| Bangkok Bank | installment_wlb_bbl | 3, 4, 5, 6, 7, 8, 9, 10 | 500 |
| Krungsri First Choice | installment_wlb_first_choice | 3, 4, 6, 9, 10, 12, 18, 24, 36 | 300 |
| Kasikorn Bank | installment_wlb_kbank | 3, 4, 6, 10 | No Minimum Amount |
| Krungthai Card (KTC) | installment_wlb_ktc | 3, 4, 5, 6, 7, 8, 9, 10 | |
| Siam Commercial Bank | installment_wlb_scb | 3, 4, 6, 9, 10 | 500 |
| TMBThanachart Bank | installment_wlb_ttb | 3, 4, 6, 10 | 500 |
| United Overseas Bank (UOB) | installment_wlb_uob | 3, 4, 6, 10 | 500 |
Supported Loan Cards
| Card | Source type |
Installment Term Lengths (months) | Minimum Monthly Amount (THB) |
|---|---|---|---|
| Krungsri First Choice | installment_wlb_first_choice |
3, 4, 6, 9, 10, 12, 18, 24, 36 | 300 |
If the merchant enables Krungsri or Krungsri First Choice installment payments, Omise issues a 1-baht authorization charge for those cards during token creation. Omise voids the charge immediately afterward.
You can find the list of supported installment terms for each card type in the Capability API.
Payment flow
When customers choose to pay using installment payments, you (the merchant) display a checkout page that shows the relevant installment details for the customer to select.
Once the customer submits their card details and confirms the payment, Omise charges the card the same way as a normal credit card payment. Your current card processing settings therefore also apply to every charge, and Omise redirects the customer to the issuer to authenticate through 3DS. Upon completion, Omise redirects the customer back to your website.
The following screenshots demonstrate this payment flow. At checkout, the customer selects the installment payment method.


After the customer submits the credit card they want to pay with, Omise redirects them to the external webpage, where they might occasionally need to authenticate. After confirmation, Omise redirects the customer to your website through the specified return URI.
Setting who pays installment interest
Either you (the merchant) or the customer pays the interest for installment payments. We use the term zero-interest installments to describe the case where you pay the interest instead of the customer.
Default setting
Use the Dashboard to set the default party that pays installment interest. You can override this setting per charge.

Per charge setting
Override the default setting by passing the boolean parameter zero_interest_installments at both source creation and charge creation. When you set it to true, you (the merchant) pay the interest. When you set it to false, the customer pays. When you omit it, the default account value applies. The values you pass at source creation and charge creation must match.
If you charge a source directly, pass this parameter at charge creation.
Implementation
To create a charge using Installment Payments, make the following API requests.
- Create a new token using Omise.js or one of the mobile SDKs (iOS and Android).
- Create a new payment source (
type:installment_wlb_bay,installment_wlb_bbl,installment_wlb_first_choice,installment_wlb_kbank,installment_wlb_ktc,installment_wlb_scb,installment_wlb_ttb, orinstallment_wlb_uob) using Omise.js or one of the mobile SDKs (iOS and Android). - Create a new charge using the token ID and source ID you created in Steps 1 and 2.
- After you receive the charge completion webhook event, retrieve the charge to verify its status (optional, but recommended).
Use your public key to create the token and the Installment Payments source on the client (a customer's browser or mobile phone). Use your secret key to create the Installment Payments charge on the server.
If you must create and charge a source on the server side, you can do both in a single API request using your secret key.
Creating a card token
Omise.js is a client-side JavaScript library that provides a form with validation, so you can collect card information easily. It sends sensitive card data to Omise's secure vault server and generates a token.
When the customer confirms that they want to pay with a card, create a new token and specify the card details in a card object.
You can use a token only once.
The following examples demonstrate how to create a new card token for ฿4,000. Replace the omise_public_key and $OMISE_PUBLIC_KEY variables with the test public key from your Dashboard.
With Omise.js, you supply the
typeparameter as the first argument to thecreateTokenmethod.
Omise.setPublicKey(omise_public_key);
Omise.createToken('card', {
"name": "Somchai Prasert",
"number": "4242424242424242",
"expiration_month": "10",
"expiration_year": "2022",
"city": "Bangkok",
"postal_code": "10320",
"security_code": "123"
}, function(statusCode, response) {
console.log(response)
});
For testing, you can send the same request using curl.
curl https://vault.omise.co/tokens \
-X POST \
-u $OMISE_PUBLIC_KEY: \
-d "card[name]=Somchai Prasert" \
-d "card[city]=Bangkok" \
-d "card[postal_code]=10320" \
-d "card[number]=4242424242424242" \
-d "card[security_code]=123" \
-d "card[expiration_month]=12" \
-d "card[expiration_year]=2024"
{
"object": "token",
"id": "tokn_test_6275ran0cxjao4505d1",
"livemode": false,
"location": "https://vault.omise.co/tokens/tokn_test_6275ran0cxjao4505d1",
"used": false,
"charge_status": "unknown",
"card": {
"object": "card",
"id": "card_test_6275ramxwea3rk2uduo",
"livemode": false,
"location": null,
"deleted": false,
"street1": null,
"street2": null,
"city": "Bangkok",
"state": null,
"phone_number": null,
"postal_code": "10320",
"country": "us",
"financing": "credit",
"bank": "JPMORGAN CHASE BANK N.A.",
"brand": "Visa",
"fingerprint": "b3ejUqhKT6DjGjtnathYRJk8oifeVAFXPhgtoQMhZIs=",
"first_digits": null,
"last_digits": "4242",
"name": "Somchai Prasert",
"expiration_month": 12,
"expiration_year": 2024,
"security_code_check": true,
"tokenization_method": null,
"created_at": "2024-12-26T03:16:37Z"
},
"created_at": "2024-12-26T03:16:37Z"
}
The id attribute is the token identifier, which begins with tokn.
Creating a source
When the customer confirms that they want to pay with this payment method, create a new source and specify the amount, currency, installment_term, and type.
| Parameter | Type | Description |
|---|---|---|
amount |
integer | (required) See Limits |
currency |
string | (required) THB |
installment_term |
integer | (required) Valid installment term length in months |
type |
string | (required) Valid installment source type |
zero_interest_installments |
string | (optional, defaults to account setting) Whether the customer or the merchant absorbs interest. true when the merchant absorbs interest |
The following examples demonstrate how to create a new Installment Payments source for ฿4,000. Replace the omise_public_key and $OMISE_PUBLIC_KEY variables with the test public key from your Dashboard.
With Omise.js, you supply the
typeparameter as the first argument to thecreateSourcemethod.
Omise.setPublicKey(omise_public_key);
Omise.createSource('installment_wlb_ktc', {
"amount": 400000,
"currency": "THB",
"installment_term": 4
}, function(statusCode, response) {
console.log(response)
});
For testing, you can send the same request using curl.
curl https://api.omise.co/sources \
-u $OMISE_PUBLIC_KEY: \
-d "amount=400000" \
-d "currency=THB" \
-d "type=installment_wlb_ktc" \
-d "installment_term=4"
{
"object": "source",
"id": "src_test_6275raqws8zz5bm5oba",
"livemode": false,
"location": "/sources/src_test_6275raqws8zz5bm5oba",
"amount": 400000,
"barcode": null,
"bank": null,
"created_at": "2024-12-26T03:16:38Z",
"currency": "THB",
"email": null,
"flow": "redirect",
"installment_term": 4,
"ip": "35.198.236.178",
"absorption_type": "customer",
"name": null,
"mobile_number": null,
"phone_number": null,
"platform_type": null,
"scannable_code": null,
"billing": null,
"shipping": null,
"items": [],
"references": null,
"provider_references": null,
"store_id": null,
"store_name": null,
"terminal_id": null,
"type": "installment_wlb_ktc",
"zero_interest_installments": false,
"charge_status": "unknown",
"receipt_amount": null,
"discounts": [],
"promotion_code": null
}
The id attribute is the source identifier, which begins with src.
Creating a charge
Create a charge and specify the parameters return_uri, source, card, amount, and currency.
return_urispecifies the location on your website to which the customer returns after completing the payment authorization step.sourcespecifies the source identifier.cardspecifies the token identifier.- The
amountandcurrencymust match those of the source.
The following example demonstrates how to create a new charge using curl.
- Replace
$OMISE_SECRET_KEYwith the test secret key from your Dashboard. - Replace
$SOURCE_IDwith theidof the source. - Replace
$TOKEN_IDwith theidof the card token.
For installments, you can also pass the following parameter:
zero_interest_installments: The value must match the value in the source.
curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "source=$SOURCE_ID" \
-d "amount=400000" \
-d "currency=THB" \
-d "card=$TOKEN_ID" \
-d "return_uri=https://example.com/orders/345678/complete"
{
"object": "charge",
"id": "chrg_test_6275raual3km80ul0d3",
"location": "/charges/chrg_test_6275raual3km80ul0d3",
"amount": 400000,
"acquirer_reference_number": null,
"net": 384378,
"fee": 14600,
"fee_vat": 1022,
"interest": 0,
"interest_vat": 0,
"funding_amount": 400000,
"refunded_amount": 0,
"transaction_fees": {
"fee_flat": "0.0",
"fee_rate": "3.65",
"vat_rate": "7.0"
},
"platform_fee": {
"fixed": null,
"amount": null,
"percentage": null
},
"currency": "THB",
"funding_currency": "THB",
"ip": null,
"refunds": {
"object": "list",
"data": [],
"limit": 20,
"offset": 0,
"total": 0,
"location": "/charges/chrg_test_6275raual3km80ul0d3/refunds",
"order": "chronological",
"from": "1970-01-01T00:00:00Z",
"to": "2024-12-26T03:16:38Z"
},
"link": null,
"description": null,
"metadata": {},
"card": {
"object": "card",
"id": "card_test_6275ra9jn0agjscj9q1",
"livemode": false,
"location": null,
"deleted": false,
"street1": null,
"street2": null,
"city": "Bangkok",
"state": null,
"phone_number": null,
"postal_code": "10320",
"country": "us",
"financing": "credit",
"bank": "JPMORGAN CHASE BANK N.A.",
"brand": "Visa",
"fingerprint": "b3ejUqhKT6DjGjtnathYRJk8oifeVAFXPhgtoQMhZIs=",
"first_digits": null,
"last_digits": "4242",
"name": "Somchai Prasert",
"expiration_month": 9,
"expiration_year": 2025,
"security_code_check": true,
"tokenization_method": null,
"created_at": "2024-12-26T03:16:35Z"
},
"source": {
"object": "source",
"id": "src_test_6275r9v0js90wdo7saw",
"livemode": false,
"location": "/sources/src_test_6275r9v0js90wdo7saw",
"amount": 400000,
"barcode": null,
"bank": null,
"created_at": "2024-12-26T03:16:33Z",
"currency": "THB",
"email": null,
"flow": "redirect",
"installment_term": 4,
"ip": "35.198.236.178",
"absorption_type": "customer",
"name": null,
"mobile_number": null,
"phone_number": null,
"platform_type": null,
"scannable_code": null,
"billing": null,
"shipping": null,
"items": [],
"references": null,
"provider_references": null,
"store_id": null,
"store_name": null,
"terminal_id": null,
"type": "installment_wlb_ktc",
"zero_interest_installments": false,
"charge_status": "pending",
"receipt_amount": null,
"discounts": [],
"promotion_code": null
},
"schedule": null,
"linked_account": null,
"customer": null,
"dispute": null,
"transaction": null,
"failure_code": null,
"failure_message": null,
"merchant_advice": null,
"status": "pending",
"authorize_uri": "https://pay.omise.co/payments/pay2_test_6275rauc8sa7s5tl12s/authorize?acs=false",
"return_uri": "https://example.com/orders/345678/complete",
"created_at": "2024-12-26T03:16:38Z",
"paid_at": null,
"authorized_at": null,
"expires_at": "2025-01-02T03:16:38Z",
"expired_at": null,
"reversed_at": null,
"multi_capture": false,
"zero_interest_installments": false,
"branch": null,
"terminal": null,
"device": null,
"authorized": false,
"capturable": false,
"capture": true,
"disputable": false,
"livemode": false,
"refundable": false,
"partially_refundable": false,
"reversed": false,
"reversible": false,
"voided": false,
"paid": false,
"expired": false,
"can_perform_void": false,
"approval_code": null
}
Creating a source and charge
Alternatively, you can create and charge a source in a single API request.
curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=400000" \
-d "currency=THB" \
-d "return_uri=http://example.com/orders/345678/complete" \
-d "card=$TOKEN_ID_CHARGE_SOURCE" \
-d "source[type]=installment_wlb_ktc" \
-d "source[installment_term]=4"
Creating a source and charge where the customer pays interest
Override the default setting for who pays installment interest by passing the zero_interest_installments parameter. See setting who pays installment interest for more details.
curl https://api.omise.co/charges \
-u $OMISE_SECRET_KEY: \
-d "amount=400000" \
-d "currency=THB" \
-d "return_uri=http://example.com/orders/345678/complete" \
-d "zero_interest_installments=false" \
-d "card=$TOKEN_ID_CHARGE" \
-d "source[type]=installment_wlb_ktc" \
-d "source[installment_term]=4"
Completing the charge
You have created a new charge with its status set to pending.
The other possible values for charge status are successful, failed, and expired.
The following sections detail how to authorize a charge, receive its completion webhook event, and update its status.
Authorizing the charge
Redirect the customer to the location specified in authorize_uri so they can authorize the charge.
In test mode, you can simulate this authorization phase using our test cards.
After the customer completes the authorization phase, Omise redirects them to the location specified in return_uri.
Receiving the charge completion event
The best way to receive notification of a charge's completion is through webhook events.
Set up a location on your server to receive webhook events, and add this location as a webhook endpoint on the Dashboard.
Checking the charge status
After you receive this event, retrieve the charge using its id and confirm that its status matches the status of the charge in the event.
If the value of status is successful, you have received the payment.
If the value of status is failed, check the failure_code and failure_message in the charge object for an explanation.
The possible failure codes are as follows.
| Failure Code | Description |
|---|---|
insufficient_balance |
The account has insufficient funds, or the payment method has reached its limit. |
payment_cancelled |
The payer canceled the payment. |
timeout |
The payer did not take action before the charge expired. |
failed_processing |
A general payment processing failure occurred. |
Voids and refunds
See the Refunds API documentation for information on how to refund an installment payment charge.
Installment payment charges do not support partial refunds. Omise supports only full refunds.
| Credit Card | Refundable Period |
|---|---|
| Krungsri | 30 days |
| Bangkok Bank | 1 year |
| Krungsri First Choice | 30 days |
| Kasikorn Bank | 120 days |
| Krungthai Card (KTC) | 180 days |
| Siam Commercial Bank | 180 days |
| TMBThanachart Bank | 1 year |
| United Overseas Bank (UOB) | 1 year |
Limits
- Minimum:
200000(฿2,000.00) - Maximum:
15000000(฿150,000.00)
Most credit cards have their own monthly minimum, so the effective minimum charge amount may be higher depending on the credit card and installment term length you choose. Kasikorn Bank and Krungthai Card (KTC) have no monthly minimum, so only the general minimum above applies to them.
For example, a ฿3,300 charge paid over a 10-month installment term results in a monthly charge of approximately ฿330. The monthly charge falls below the ฿500 minimum for Bangkok Bank credit cards, so Bangkok Bank credit cards cannot process the charge. Kasikorn Bank and KTC credit cards have no monthly minimum, so they can process it.
Related API documentation
How to check the public key and secret key
For information on how to obtain and check the public and secret keys, see How to access Omise API keys.