Integration GuideAPI Reference
Integration Guide

"QRIS" Payment Method

Payment Method Definition

📓

displayedPaymentMethods

displayedPaymentMethods defines which payment methods are shown to the payer on the Hosted Checkout form. It is the Hosted Checkout alternative to paymentMethodName, which is used in Host-to-Host integrations.

Provide this parameter in paymentIntent.formDetails.displayedPaymentMethods.

To make QRIS available on the checkout form, include the QRIS value. If QRIS is the only value in the array, the payment-method selection step is skipped and the payer is taken directly to the QRIS flow.


Payment Method Features

FeatureValue
CountryIndonesia
Processing CurrenciesIDR
PaymentsYes
-- Min per transaction amount1 000 IDR, unless another limit is defined in your contract
-- Max per transaction amount10 000 000 IDR, unless another limit is defined in your contract
RefundsYes — full amount only
-- Partial refundsNo
ChargebacksNo
📘

IDR is a zero-decimal currency: send whole numbers (e.g. 150000), not 150000.00.


Workflow

  1. Create an Intent with useCheckoutForm set to true and include QRIS in paymentIntent.formDetails.displayedPaymentMethods.
  2. Receive the Hosted Checkout URL in paymentIntent.additionalData.url.
  3. Redirect the payer to the returned URL.
  4. The platform creates a QRIS payment and displays its QR code and copyable QRIS payload on the checkout form. No information is collected from the payer — there is no data-entry step.
  5. The payer scans the QR code, or copies the QRIS payload, in any Indonesian banking or e-wallet application and confirms the payment.
  6. Wait for the payment webhook. Treat the payment as successful only when its status becomes CAPTURED.
⚠️

The synchronous Intent response confirms that the Hosted Checkout session was created. It does not create a successful QRIS payment and does not confirm that the payer completed the transfer.

The initial response contains the URL of the Carusell Hosted Checkout form, not the QRIS payload. QRIS payment data is created and displayed later, inside the checkout flow.


Create Intent Request

Specifics

  • We use one unified Intent creation request for all supported payment methods: POST /processing/api/v1/intents.
  • The overall structure is the same, but some fields change depending on the integration type: Host-to-Host or Hosted Checkout.
    • For Host-to-Host, complete the Payment object.
    • For Hosted Checkout, complete the PaymentIntent object.
  • For QRIS Hosted Checkout:
    • Set useCheckoutForm to true.
    • Provide paymentIntent instead of payments.
    • Include QRIS in paymentIntent.formDetails.displayedPaymentMethods.
    • Do not send paymentMethodName, paymentInstrument, or QRIS incomingDetails in the initial Intent request.
    • The checkout form collects no data from the payer. For QRIS it only creates and displays the QRIS payment (QR code and copyable payload) — there is no name, document, email, or phone entry step.
    • paymentIntent.submittedAmount.currency can be IDR or another supported currency when FX conversion is enabled. The QRIS payment itself is authorised in IDR.
    • Provide paymentIntent.webhookUrl and wait for payment status updates instead of treating the Intent creation response as confirmation of payment.

'Intent' vs 'Payment' vs 'PaymentIntent'

Some objects and parameters in this API may appear similar, but they represent different concepts and are used in different integration scenarios. The explanation below clarifies the purpose of each term.

TermMeaning
Intent
  • A universal top-level container for transaction-related operations.
  • Depending on the integration scenario, it may contain objects such as Payment, PaymentIntent, or other transaction types.
Payment
  • Used in Host-to-Host integrations.
  • You provide the payment method, amount, currency, and payer details upfront because the payment flow is handled on your side.
  • For QRIS Host-to-Host, the synchronous response contains the QRIS payload (url) and QR image (qrBase64). See the QRIS Host-to-Host page.
PaymentIntent
  • Used in Hosted Checkout integrations.
  • It contains the order details and checkout configuration, but not the payment instrument data.
  • The actual Payment object is created later, when the payer opens the checkout form and starts the QRIS payment.
  • Multiple payment attempts may occur within one Intent. Each attempt follows the rules and configuration defined in the corresponding PaymentIntent.

Request/Response Description

Request Description

{
  "clientReferenceId": "order-20260909-0001",
  "useCheckoutForm": true,
  "paymentIntent": {
    "formDetails": {
      "displayedPaymentMethods": ["QRIS"],
      "backToStoreRedirectUrl": "https://merchant.example.com/orders/order-20260909-0001"
    },
    "submittedAmount": {
      "value": 150000,
      "currency": "IDR"
    },
    "description": "Order 20260909-0001",
    "webhookUrl": "https://merchant.example.com/webhooks/payments"
  }
}
Top-Level Request Parameters
ParameterTypeRequiredDescription
clientReferenceIdStringRequiredOrder or Intent reference in the merchant system.
useCheckoutFormBooleanConditionalOptional in the general Intent contract. Must be set to true when using Hosted Checkout.
paymentIntentObjectConditionalOptional in the general Intent contract. Must be provided when using Hosted Checkout. Do not send a payments array for the flow described on this page.
descriptionStringOptionalIntent-level order description.
merchantObjectOptionalMerchant information. Provide it when merchant details must be associated with the Intent or displayed on the checkout form according to your configuration.
paymentIntent
ParameterTypeRequiredDescription
formDetailsObjectRequiredCheckout-form configuration. Required for Carusell Hosted Checkout.
submittedAmountObjectRequiredOrder amount and submitted currency.
authorizationAmountObjectOptionalAuthorisation amount and currency when these are supplied explicitly under an agreed FX flow. For QRIS, the authorisation currency must be IDR. Do not send this object unless the FX flow is enabled for you.
descriptionStringOptionalOrder title or payment reason. Recommended: a meaningful value improves payer recognition and reconciliation.
webhookUrlStringRequiredHTTPS URL to which payment status change webhooks for payments created within the Intent will be sent.
formDetails
ParameterTypeRequiredDescription
templateStringOptionalName of a checkout template configured for the settlement account. If omitted, the default template is used.
displayedPaymentMethodsArray of StringsConditionalInclude QRIS to make QRIS available on the checkout form. If only QRIS is provided, the payment-method selection step is skipped. If omitted, the form shows the methods available under the account configuration.
backToStoreRedirectUrlStringOptionalHTTPS URL to which the payer can return after leaving or completing the checkout flow. The Back to Store control is unavailable when this parameter is omitted.
submittedAmount
ParameterTypeRequiredDescription
valueNumberRequiredSubmitted order amount. IDR is zero-decimal — use whole numbers (e.g. 150000). The applicable QRIS limit is normally from 1 000 to 10 000 000 IDR unless another limit is defined in your contract.
currencyStringRequiredSubmitted currency in ISO 4217 alpha-3 format. Use IDR when no FX conversion is required. Another supported currency may be used when FX is enabled.
authorizationAmount
ParameterTypeRequiredDescription
valueNumberRequiredExplicit QRIS authorisation amount. Supply it only as part of an agreed FX flow.
currencyStringRequiredAuthorisation currency in ISO 4217 alpha-3 format. For QRIS, the value must be IDR.
merchant
ParameterTypeRequiredDescription
nameStringOptionalStore name that may be displayed on the checkout form when this presentation is configured.
websiteStringOptionalMerchant website associated with the Intent.

QRIS Checkout Experience

📘

The payer completes all QRIS steps on the Carusell Hosted Checkout form. The merchant must redirect the payer to paymentIntent.additionalData.url; the merchant does not render the QRIS QR code or payload in this integration.

QRIS Hosted Checkout collects no information from the payer. There is no name, document, email, or phone entry step — the form goes straight to displaying the QRIS payment.

Once the payment is created, the checkout form displays both representations of the same QRIS payment:

  • a QR code for scanning from another device;
  • a copyable QRIS payload for pasting into a QRIS-enabled banking or wallet application.

The payer must not modify the QRIS payload, amount, CRC, or any other character in the copyable value.


Payment Statuses

StatusMeaningMerchant action
AUTHORIZATION_REQUESTEDThe QRIS payment was created and is waiting for the payer to complete the transfer.Wait for a webhook. Do not fulfil the order.
CAPTUREDThe QRIS transfer was successfully completed.Fulfil the order.
DECLINEDThe payment was rejected.Do not fulfil the order. The payer may start another attempt while the checkout session remains active.
CANCELLEDThe payment was cancelled or the QR expired before completion.Do not fulfil the order. The payer may start another attempt while the checkout session remains active.
ERRORA technical or processing error prevented the payment from completing.Do not fulfil the order. Use the error fields for diagnostics and allow another attempt only when appropriate.
⚠️

A checkout session and a QRIS payment have separate lifecycles. paymentIntent.additionalData.expirationDateTime describes the checkout session lifetime. A QRIS QR created during that session has its own payment status and may expire independently.


Refunds

QRIS payments completed through Hosted Checkout support the same refund flow as QRIS payments created through Host-to-Host integration.

  • A refund can be created only after the QRIS payment reaches CAPTURED.
  • Use the payment id received through the payment webhook or retrieved from the Intent or Payment API.
  • Create the refund with POST /processing/api/v1/refunds.
  • Full refunds only — QRIS does not support partial refunds. The refund is returned to the original QRIS payment source.
  • Only one refund per payment is possible.
  • Refund processing is asynchronous. Treat it as successful only when the refund reaches REFUNDED.

Webhooks

🔗

Payment status notifications

  • The platform sends payment webhooks to paymentIntent.webhookUrl whenever the status of a QRIS payment created within the checkout session changes.
  • The synchronous Intent response only creates the checkout session. Fulfil the order only after receiving a payment with status CAPTURED.
  • A payer may make multiple payment attempts during the checkout session lifetime. Correlate each webhook by its platform payment ID and correlate the overall checkout flow by the Intent ID.
  • Webhooks may be delivered more than once. Process them idempotently.
  • If a webhook is delayed or missed, retrieve the Intent or Payment by ID to reconcile the latest state.

For more information about payment webhooks, see the dedicated page.


Did this page help you?