IPS - Instant Payment Serbia

Prev Next

Step 1: Set up IPS-RS Component

The ips-rs component is available as part of Monri.js. To get started, include the following script on your page.
This script must be loaded directly from monri.com to remain PCI-compliant —you cannot self-host or bundle it.

When generating the client_secret on your backend (via the /v2/payment/new endpoint), make sure to include
the ch_full_name field in the request and supported_payment_methods set to ips-rs.
If this field is missing, the generated client_secret will not be valid, and the IPS-RS component will fail to
initialize properly.

For detailed backend integration, refer to
the Payment API documentation.

Test Environment

<script src="https://ipgtest.monri.com/dist/components.js"></script>

Production Environment

<script src="https://ipg.monri.com/dist/components.js"></script>

Then, create an instance of Monri and initialize components:

const monri = Monri('<authenticity-token>');
const components = monri.components({clientSecret: '<client-secret>'});

Replace <authenticity-token> with the value from your merchant dashboard.

Replace <client-secret> with the value obtained when creating a payment via your backend.

⚠️ When switching to production, ensure you're using your production authenticity_token and client_secret.

Step 2: Create your Payment Form Container

Create a DOM element where the ips-rs component will be injected.

<div id="ips-rs-element"></div>

Step 3: Initialize and Mount ips-rs Component

You can now create and mount the component. Optional styles can be passed depending on screen size:

const isMobile = window.innerWidth <= 768;

// Create an instance of the ips-rs Components.
const ips = components.create("ips-rs", {
    trx_token: "<trx_token>",
    environment: isTestSystem ? "test" : "prod",
    // define styling options for ips-rs Components
    style: {
        container: {
            width: "100%",
            display: 'flex',
            flexDirection: 'row',
            maxWidth: "600px",
            margin: "0 auto",
            alignItems: "center",
            justifyContent: "center",
            gap: '15px'
        },
        descriptionRow: {
            display: "flex",
            gap: "1rem",
            marginBottom: isMobile ? "0rem" : "4rem",
            justifyContent: "space-between"
        },
        text: {
            display: "none"
        },
        logo: {
            alignSelf: "flex-start",
            width: "35vw",
            maxWidth: "120px",
            marginBottom: "0rem"
        },
        qrCodeContainer: {
            display: "flex",
            justifyContent: "center",
            marginBottom: "0rem"
        },
        regenerateBtn: {
            backgroundColor: "#f8f8f8",
            fontSize: "1.2rem"
        },
        timer: {
            textAlign: "center",
            marginTop: "1rem",
            fontFamily: "Myriad Pro",
            color: "#9396A6",
            fontSize: "0.9rem"
        },
        ifMobile: {
            display: "block",
            marginBottom: "0rem"
        },
        radioLabel: {
            display: "inline-flex",
            alignItems: "center",
            marginRight: "1rem"
        },
        radioInput: {
            scale: 1.2,
            margin: "0 0.5rem 0 0",
            padding: 0
        },
        bankSelect: {
            backgroundColor: "#FCF5FF",
            color: "#8132A7",
            borderRadius: '10px',
            borderColor: 'transparent',
            fontWeight: '400',
            cursor: 'pointer',
            fontFamily: 'Myriad Pro'
        },
        generateQRButton: {
            backgroundColor: '#FCF5FF',
            color: '#8132A7',
            fontWeight: '400',
            borderRadius: '8px',
            borderColor: 'transparent',
            fontSize: '0.9rem',
            padding: '0.3rem 0.9rem',
            transition: '0.3s ease-in-out',
            fontFamily: 'Myriad Pro',
            maxWidth: '150px',
            margin: '0 auto',
            display: 'block'
        },
        button: {
            fontSize: '1rem'
        },
        rightContainer: {
            display: "flex",
            flexDirection: "row"
        }
    }
});
// Add an instance of the Ips-Rs component into the `ips-rs-element` <div>.
ips.mount("ips-rs-element");
Option Description
trx_token Token received when creating the transaction on backend
environment Either 'test' or 'prod', depending on your system
style Optional custom styles for component containers (see example above)

Callback Example

When the IPS transaction is completed, Monri will send a server-to-server callback to your configured URL.
Below is a full example of the callback payload and headers:

{
  "url": "YOUR-CALLBACK-URL",
  "body": {
    "id": "TRANSACTION-ID",
    "acquirer": "Uac-Ips",
    "order_number": "MonriTestOrderNumber12345",
    "order_info": "testOrderInfo12345",
    "amount": 100,
    "currency": "RSD",
    "ch_full_name": "Test Monri",
    "outgoing_amount": 100,
    "outgoing_currency": "RSD",
    "approval_code": "100044",
    "response_code": "0000",
    "response_message": "Completed",
    "reference_number": "",
    "systan": "154416",
    "eci": null,
    "xid": null,
    "acsv": null,
    "cc_type": null,
    "status": "approved",
    "created_at": "2025-10-29T09:20:09.754+01:00",
    "transaction_type": "purchase",
    "enrollment": null,
    "authentication": null,
    "pan_token": null,
    "ch_email": "test@monri.com",
    "masked_pan": "N/A",
    "issuer": "uac",
    "number_of_installments": null,
    "custom_params": null,
    "expiration_date": "N/A",
    "issuer_groups": [],
    "cit_id": null,
    "ip": "79.101.141.44",
    "routing_context": null
  },
  "headers": {
    "Content-Type": "application/json",
    "HTTP_AUTHORIZATION": "WP3-callback CALLBACK-DIGEST-VALUE",
    "AUTHORIZATION": "WP3-callback CALLBACK-DIGEST-VALUE"
  }
}

Notes

Ensure the container #ips-rs-element exists before calling mount.

Use media queries or window.innerWidth to adjust styles for mobile/desktop.

QR codes or bank options are rendered automatically inside the component.

IPS-RS supports real-time payments and is optimized for bank selection and QR scanning.