This documentation provides a comprehensive guide to integrating Monri Components into your web application for secure and flexible payment processing.
1. Overview
Monri Components are a set of UI elements provided by Monri.js that allow you to securely collect sensitive payment information (like card details or cryptocurrency payment initiation) directly from your customers' browsers without compromising PCI DSS compliance.
By using Components, you embed hosted fields directly into your payment form, ensuring that sensitive data never touches your servers.
Key Benefits:
- PCI DSS Compliance: Sensitive data is handled directly by Monri.
- Customizable UI: Components can be styled to match your brand.
- Simplified Integration: Streamlined process for card and crypto payments.
2. Requirements
2.1. HTTPS
All submissions of payment information using Monri Components are made via a secure HTTPS connection. To ensure maximum security and prevent Mixed Content warnings in modern browsers, the page containing your payment form MUST also be served over HTTPS (https://
) rather than just http://
.
For more information on SSL certificates and enabling HTTPS, please refer to our security documentation.
2.2. Components script loading from the source
Components script must always load directly from monri.com
. For more information please refer to 3.2.1. Set Up Monri Components below.
3. Core Integration: Card Payments
This section details the primary integration steps for accepting card payments using Monri Components.
3.1. Creating a New Payment on Your Backend
This is the initial step, ideally executed once you have sufficient information to create a customer's order. You will typically generate a client_secret
on your backend which is then sent to your frontend for use with Monri Components.
For detailed backend integration, refer to the Payment API documentation.
Demo: See a live demonstration of Components integration here: Demo Components
3.2. Confirming Payment on Your Application (Frontend)
After generating the client_secret
on your backend and sending it to your frontend application, you will use Monri Components to confirm the payment.
Steps:
- Ensure you have a valid
client_secret
(obtained from your backend viapayment/new
API call). - Set up Monri Components (initialize
Monri.js
). - Create the necessary HTML containers for your custom payment form.
- Confirm payment using
monri.confirmPayment
. - Handle the
ConfirmPaymentResponse
.
3.2.1. Set Up Monri Components
Components are part of the Monri.js
library. To get started, include the following script on your pages. This script must always load directly from monri.com
to remain PCI compliant; you cannot bundle it or host a copy yourself.
<script src="[https://ipgtest.monri.com/dist/components.js](https://ipgtest.monri.com/dist/components.js)"></script>
Next, create an instance of Monri and components:
var monri = Monri('<authenticity-token>');
var components = monri.components({"clientSecret": "<client-secret>"});
- Replace
<authenticity-token>
with the value provided in your merchant dashboard. - Replace
<client-secret>
with the value obtained in the "Creating New Payment on Merchant's Backend" step.
When ready to accept live payments, ensure you replace theauthenticity-token
andclient-secret
with your production values.
Monri Constructor Options:
TheMonri
constructor accepts an optional second parameter for customization:
locale
: Sets the language for components (details below).
fonts
: An array ofFontFace
objects for custom styling (explained below).
Localization:
Components can be localized by specifying the locale
option. For example, to use the Croatian (hr
) locale:
var monri = Monri('authenticity-token', {locale: 'hr'});
Currently supported locales are:
hr
(Croatian - ICUhr_HR
)en
(English - ICUen_US
, default)sr
(Serbian - ICUsr_SR
)
"Locale" currently refers to language only; number and date formats are not supported.
Custom Fonts:
Components can be styled using custom fonts by passing an array of FontFace
objects to the fonts
property in Monri
options:
var monri = Monri('<authenticity-token>', {
fonts: [
{
family: 'Rubik-Light',
src: '/static/fonts/rubik-light.ttf'
},
{
family: 'Rubik-Regular',
src: '[https://some-site.com/fonts/roboto.ttf](https://some-site.com/fonts/roboto.ttf)',
weight: '900'
}
]
});
The family
and src
properties are required. Optional properties include display
, weight
, style
, stretch
, and unicode-range
. For display
values, refer to MDN web docs.
Localization and font options can be combined:
var monri = Monri('<authenticity-token>', {
locale: 'hr',
fonts: [...] // Your font array
});
3.2.2. Create Your Payment Form
To securely collect card details, Monri Components create UI elements that are hosted by Monri and then embedded into your form.
Create empty DOM elements (containers) with unique IDs within your payment form. We recommend using a <label>
with a for
attribute matching the container's id
for improved accessibility (automatic focus when the label is clicked).
Example HTML Structure:
<form action="" method="post" id="payment-form">
<div class="form-row">
<label for="card-element">
Credit or debit card
</label>
<div id="card-element">
</div>
<div id="card-errors" role="alert"></div>
</div>
<button>Submit Payment</button>
</form>
If your inserted payment form is invisible, it might be a CSS issue. Try removing classes like form-row
for diagnostics.
After your form loads, create an instance of a Component and mount it to its container:
// Custom styling can be passed to options when creating an Component.
var style = {
base: {
// Add your base input styles here. For example:
fontSize: '16px',
color: '#663399',
}
};
// Create an instance of the card Component.
var card = components.create('card', {style: style});
// Add an instance of the card Component into the `card-element` <div>.
card.mount('card-element');
The card
Component simplifies the form by providing a single, flexible input field for all necessary card details.
In addition to the card
component, saved_card
and cvv
components are also available:
var savedCard = components.create('saved_card', {style: style});
// Mount savedCard...
var cvvComponent = components.create('cvv', {style: style});
// Mount cvvComponent...
For the cvv
component, you can change the default payment method using _setActivePaymentMethod
and providing a valid token for the saved card.
3.2.3. Validation & Listening to Changes
Components validate user input as it is typed. Listen to change
events on the card
Component to display validation errors to your customers.
Listening to change
Events:
card.onChange(function (event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
Reacting to Specific Input Element Changes - addChangeListener
:
You can add listeners for specific input elements using the addChangeListener
method:
card.addChangeListener('<input_element>', function (event) {
console.log(event.data);
console.log(event.message);
console.log(event.valid);
console.log(event.element);
});
Supported input elements for addChangeListener
are: card_number
, expiry_date
, and cvv
.
Card Number Change Listener
card.addChangeListener('card_number', function (event) {
console.log(event.data);
console.log(event.data.bin);
console.log(event.data.brand);
console.log(event.message);
console.log(event.valid);
console.log(event.element);
});
Event Details:
key
:card_number
event
object:data
: objectbin
:String | null
(min-length: 6, max-length: 6). Available only if at least 6 digits are entered, otherwisenull
.brand
:String
(e.g.,visa
,master
,amex
).
element
:String
(card_number
).message
:String | null
(null
if valid, message if invalid).valid
:boolean
(false
if input is invalid).
Example card_number
Event Data:
{
"data": {
"bin": "411111",
"brand": "visa"
},
"element": "card_number",
"message": null,
"valid": true
}
Save Card Change Listener
card.addChangeListener('save_card', function (event) {
console.log(event.data);
console.log(event.data.checked); // true if user clicked on save card
console.log(event.valid); // always true
});
Event Details:
key
:save_card
event
object:data
: objectchecked
:boolean
.
element
:String
(save_card
).message
:String | null
(null
if valid).valid
:boolean
(alwaystrue
for this event).
Example save_card
Event Data:
{
"data": {
"checked": true
},
"element": "save_card",
"message": null,
"valid": true
}
Expiry Date Change Listener
card.addChangeListener('expiry_date', function (event) {
console.log(event.data);
console.log(event.data.month);
console.log(event.data.year);
console.log(event.message);
console.log(event.valid);
console.log(event.element);
});
Event Details:
key
:expiry_date
- event object:
data
: objectmonth
:Number
(1-12).year
:Number
(e.g., 2024).
element
:String
(expiry_date
).message
:String | null
(null
if valid, message if expiry date is in the past or invalid).valid
:boolean
(false
if input is invalid).
Example expiry_date
Event Data:
{
"data": {
"month": 11,
"year": 2021
},
"element": "expiry_date",
"message": null,
"valid": true
}
CVV Change Event
card.addChangeListener('cvv', function (event) {
console.log(event.data);
console.log(event.message);
console.log(event.valid);
console.log(event.element);
});
Event Details:
key
:cvv
event
object:data
:object
(empty object).element
:String
(cvv
).message
:String | null
(null
if valid, message if invalid).valid
:boolean
(false
if input is invalid).
Example cvv
Event Data:
{
"data": {},
"element": "cvv",
"message": null,
"valid": true
}
Installments Change Event
card.addChangeListener('installments', function (event) {
console.log(event.data);
console.log(event.data.selectedInstallment);
console.log(event.message);
console.log(event.valid);
console.log(event.element);
});
Event Details:
key
:installments
event
object:data
: objectselectedInstallment
:Number
.
element
:String
(installments
).message
:String | null
(null
if valid, message if invalid).valid
:boolean
(false
if input is invalid).
Example installments
Event Data:
{
"data": {
"selectedInstallment": 11
},
"element": "cvv",
"message": null,
"valid": true
}
3.2.4. Authorization
Although you can easily collect payment result directly in application via onSuccess call it’s better to implement callback listener (WebHook) on your backend.
For request authentication we use Authorization
header created from:
authorization schema
: String =WP3-v2
authenticity_token
: String = value from merchant’s configurationtimestamp
: Integer = unix timestamp (eg PHP’stime()
)body_as_string
: String = Json encoded request body, egjson_encode($data)
digest
: String =sha512(merchant_key + timestamp + authenticity_token + body_as_string)
You can check digest on this link Calculate Digest
Parts above are joined by space, so Authorization
header should be in this form:
Authorization: schema authenticity_token timestamp digest
Example: Authorization: WP3-v2 abc...def 1585229134 314d32d1...0b49
Request endpoint is <base_url>/v2/payment/new
where base_url is:
https://ipgtest.monri.com
for TEST environmenthttps://ipg.monri.com
for PROD environment
TIP: Parametrize merchant_key
, authenticity_token
and base_url so it can be easily changed when you are ready for
production environment.
Payment/new response contains:
status
: String: approved | declined -id
: String - Unique payment identifier used to track payment flow on Monri’s
side. Useful for debugging if something goes wrong. Save this value in your database.client_secret
: String - Value you’ll send to your application which then will use this secret to confirm payment
using Monri Components.
Request example in PHP:
$data = [
'amount' => 100, //minor units = 1EUR
// unique order identifier
'order_number' => 'random' . time(),
'currency' => 'EUR',
'transaction_type' => 'purchase',
'order_info' => 'Create payment session order info',
'scenario' => 'charge'
'supported_payment_methods' => ['67f35b84811188a5c581b063c4f21bd6760c93b2a04d7ac4f8845dd5bbb3f5c6']
];
$body_as_string = Json::encode($data); // use php's standard library equivalent if Json::encode is not available in your code
$base_url = 'https://ipgtest.monri.com'; // parametrize this value
$ch = curl_init($base_url . '/v2/payment/new');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $body_as_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
$timestamp = time();
$digest = hash('sha512', $key . $timestamp .$authenticity_token. $body_as_string);
$authorization = "WP3-v2 $authenticity_token $timestamp $digest";
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($body_as_string),
'Authorization: ' . $authorization
)
);
$result = curl_exec($ch);
if (curl_errno($ch)) {
curl_close($ch);
$response = ['client_secret' => null, 'status' => 'declined', 'error' => curl_error($ch)];
} else {
curl_close($ch);
$response = ['status' => 'approved', 'client_secret' => Json::decode($result)['client_secret']];
}
var_dump($response);
3.2.5. Confirm Payment using Monri Components
When the payment details are ready, invoke monri.confirmPayment
to finalize the transaction. While confirmPayment
can be called at any time, it's best practice to intercept the form's submit
event and then call it.
confirmPayment
accepts two arguments:
component
: The component instance you created (e.g.,card
).transactionParams
: An object containing buyer and order information.
All transactionParams
fields are validated against the rules defined in "Variables - Names, Lengths, and Formats" (see section 7).
MonriError
and PaymentResult
Types:
type MonriError = {
message: string
}
type Result<PaymentResult> = {
result: PaymentResult | null,
error: MonriError | null
}
type PaymentResult = {
status: string, // approved or declined
currency: string,
amount: number, // amount in minor units, eg 10.24 USD is 1024
order_number: string,
pan_token: string | null, // pan token representing tokenized card
created_at: string,
transaction_type: string, // authorize or purchase, depending on trx type used in payment/new
payment_method: SavedCardPaymentMethod | null, // available if card is tokenized for future payments, null if not
errors: Array<string> | null // errors if transaction is declined
}
type SavedCardPaymentMethod = {
type: string,
data: SavedCardPaymentMethodData
}
type SavedCardPaymentMethodData = {
brand: string,
issuer: string,
masked: string,
expiration_date: string,
token: string
}
Important: 3D Secure (3DS) authentication is automatically handled by the Monri Components library.
Card Component Example:
// Confirm payment or display an error when the form is submitted.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function (event) {
event.preventDefault();
const transactionParams = {
address: "Adresa",
fullName: "Test Test",
city: "Sarajevo",
zip: "71000",
phone: "+38761000111",
country: "BA",
email: "tester+components_sdk@monri.com",
orderInfo: "Testna trx"
}
monri.confirmPayment(card, transactionParams).then(function (result) {
if (result.error) {
// Inform the customer that there was an error.
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
handlePaymentResult(result.result)
}
});
});
3.2.6. Handle Payment Result (Frontend)
The final step on the frontend is to handle the PaymentResult
. This depends entirely on your application's use case. The response can be submitted to your merchant's backend or handled directly within the client-side application.
For a secure and stable transaction processed notification, we highly recommend implementing a callback listener (WebHook) on your backend (see section 6).
function handlePaymentResult(paymentResult) {
// Handle PaymentResult
if (paymentResult.status == 'approved') {
alert("Transaction approved")
} else {
alert("Transaction declined")
}
}
3.3. Getting Payment Result on Merchant’s Backend (WebHook)
While you can collect payment results on the client-side via the onSuccess
callback, it is highly recommended to implement a Callback listener (WebHook) on your backend for secure and stable transaction notifications.
Requirements for your WebHook Endpoint:
- Must be publicly available over the internet.
- Must be secured (HTTPS).
- Must be configured in your merchant's settings on the Monri dashboard (contact support if you need assistance setting this value).
How it Works:
- Upon successful transaction processing and approval, Monri will send an HTTP POST request to your configured callback endpoint.
- Your backend should validate the received request to ensure it originates from Monri.
- Update or deliver the order based on the transaction status.
Example POST Request Body Sent to Callback Endpoint:
{
"id": 214,
"acquirer": "integration_acq",
"order_number": "3159daf002e3809",
"amount": 100,
"currency": "EUR",
"ch_full_name": "John Doe",
"outgoing_amount": 100,
"outgoing_currency": "EUR",
"approval_code": "687042",
"response_code": "0000",
"response_message": "approved",
"reference_number": "000003036888",
"systan": "000214",
"eci": "06",
"xid": null,
"acsv": null,
"cc_type": "visa",
"status": "approved",
"created_at": "2020-03-26T11:09:17.959+01:00",
"transaction_type": "purchase",
"enrollment": "N",
"authentication": null,
"pan_token": null,
"masked_pan": "411111-xxx-xxx-1111",
"issuer": "xml-sim",
"number_of_installments": null,
"custom_params": "{a:b, c:d}"
}
Example Request Headers:
Header | Value |
---|---|
accept-encoding |
gzip;q=1.0,deflate;q=0.6,identity;q=0.3 |
authorization |
WP3-callback d5e4528ad8a0e0f4262e518c663d5ff83cd4a8f381db68f9d30f99961409ceebb719c16d423757fc36c532b902c987012f5825dc8d32dde3a9b7ed95876be77a |
content-type |
application/json |
http_authorization |
WP3-callback d5e4528ad8a0e0f4262e518c663d5ff83cd4a8f381db68f9d30f99961409ceebb719c16d423757fc36c532b902c987012f5825dc8d32dde3a9b7ed95876be77a |
user-agent |
Faraday v0.15.4 |
content-length |
621 |
connection |
keep-alive |
The authorization
and http_authorization
headers are generated as:
digest = sha512(merchant_key + body)
(You can check the digest on this link: Calculate Digest)
authorization_header_value = WP3-callback digest
To validate if the request is from Monri, you should:
- Check if the authorization header schema is
WP3-callback
. - Extract the digest (the second part of the header value).
- Verify the extracted digest against a locally computed digest using your
merchant_key
and the receivedbody
.
4. Crypto Currencies: PayCek Payments
Monri Components also support integration with PayCek for cryptocurrency payments.
4.1. Set Up PayCek Component
The PayCek component is available via Monri.js
. As with other components, it must be loaded directly from monri.com
.
Test Environment:
<script src="https://ipgtest.monri.com/dist/components.js"></script>
Production Environment:
<script src="https://ipg.monri.com/dist/components.js"></script>
Initialize Monri
and components
instances:
var monri = Monri('<authenticity-token>');
var components = monri.components({"clientSecret": "<client-secret>"});
- Replace
<authenticity-token>
with your merchant dashboard value. - Replace
<client-secret>
with the value from your backend's "Creating New Payment" step.
Monri Options:
Additional options can be passed to the Monri
constructor, such as locale
. For localization details, refer to section 3.2.1.
4.2. Create Your PayCek Payment Form
Similar to card components, create an empty DOM container with a unique ID for the PayCek component within your payment form.
Example HTML:
<form action="" method="post" id="pay-cek-payment-form-form">
<div class="form-row">
<div id="pay-cek-element">
</div>
</div>
<button>Submit Payment</button>
</form>
If your inserted payment form is invisible, it might be a CSS issue. Try removing classes like form-row
for diagnostics.
Once the form is loaded, create and mount the PayCek Component:
// Custom styling can be passed to options when creating PayCek Component.
var options = {
payCekOptions: {size: "small"}
};
// Create an instance of the PayCek Component.
var payCek = components.create("pay-cek", options)
.onStartPayment(() => {
// This is invoked after user clicks on PayCek button
// Here you can:
// 1. Collect user's info such as name, email address
// 2. Invoke confirmPayment with PayCek
const transactionParams = {
address: "Adresa",
fullName: "Test Test",
city: "Sarajevo",
zip: "71000",
phone: "+38761000111",
country: "BA",
email: "tester+components_sdk@monri.com",
orderInfo: "Testna trx"
}
monri
// confirmPayment opens a popup window for crypto currency selection
// then displays a QR code with wallet address
// finally, returns an Approved or Declined transaction response as a Promise
.confirmPayment(payCek, transactionParams) // Changed 'params' to 'transactionParams' for consistency
.then(e => {
if (e.error) {
// Inform the customer that there was an error.
alert(e.error.message)
} else {
// Handle approved or declined result
// For secure and stable result, handle on backend via WebHook (section 6)
}
})
.catch(e => {
alert(e);
})
});
// Add an instance of the PayCek component into the `pay-cek-element` <div>.
payCek.mount("pay-cek-element");
5. Customizing Components
Monri Components offer various options for styling and specific functionalities.
5.1. Styling Components
Components can be styled via the style
property in the second parameter of the create
method (as shown in section 3.2.2).
The style
object consists of four properties representing component element states, which override the base
style if specified:
base
: Defines the default style applied to each component element.complete
: Style applied when a component element is filled with a valid value.empty
: Style applied when a component element is empty and loses focus.invalid
: Style applied when a component element contains an invalid value and loses focus.
Additionally, style
properties for label
, input
, rememberCardLabel
, and selectPaymentMethod
elements can be set explicitly.
Styles are applied to all component elements that have received focus at least once.
Supported CSS Properties (all string type, all optional):
Attribute | CSS attribute | Description |
---|---|---|
fontSize |
font-size |
Size of the font |
color |
color |
Component element color |
fontFamily |
font-family |
Family of the font |
fontSmoothing |
font-smoothing |
Selected font smoothing |
fontVariant |
font-variant |
Variant of the font |
fontWeight |
font-weight |
Font weight |
letterSpacing |
letter-spacing |
Font letter spacing |
textDecoration |
text-decoration |
Component element text decoration |
textShadow |
text-shadow |
Component element text shadow |
textTransform |
text-transform |
Component element text transform |
border |
border |
Component element border |
borderTop |
border-top |
Component element top border |
borderRight |
border-right |
Component element right border |
borderBottom |
border-bottom |
Component element bottom border |
borderLeft |
border-left |
Component element left border |
borderRadius |
border-radius |
Component element border radius |
padding |
padding |
Component element padding |
margin |
margin |
Component element margin |
lineHeight |
line-height |
Component element line height |
textIndent |
text-indent |
Component element text indent |
position |
position |
Component element position |
top |
top |
Component element top |
bottom |
bottom |
Component element bottom |
left |
left |
Component element left |
right |
right |
Component element right |
width |
width |
Component element width |
backgroundColor |
background-color |
Component element background color |
height |
height |
Component element height |
boxShadow |
box-shadow, moz-box-shadow, webkit-box-shadow |
Component element box shadow |
Example of Custom Style Object:
var style = {
base: {
fontFamily: 'Rubik-Regular'
},
invalid: {
color: 'red'
},
complete: {
color: 'blue'
},
label: {
base: {
color: 'blue',
textTransform: 'none'
},
invalid: {
color: 'gray'
},
complete: {
color: 'green'
}
},
input: {
base: {
fontSize: '15px',
color: "#663399",
borderBottom: "1px solid purple"
}
},
rememberCardLabel: {
base: {
fontSize: '15px',
color: "#663399"
}
},
selectPaymentMethod: {
base: {
fontSize: '15px',
color: "#663399"
}
}
};
Style Object Structure (empty fields can be omitted):
var style = {
base: {},
invalid: {},
complete: {},
empty: {},
label: {
base: {},
invalid: {},
complete: {},
empty: {}
},
input: {
base: {},
invalid: {},
complete: {},
empty: {}
},
rememberCardLabel: {
base: {},
invalid: {},
complete: {},
empty: {}
},
selectPaymentMethod: {
base: {},
invalid: {},
complete: {},
empty: {}
}
}
5.2. Component-Specific Options
Card Component Options
Card component options extend common component options with:
Option | Type | Description | Default Value |
---|---|---|---|
tokenizePan |
boolean | Tokenizes the PAN when the client enters card info. | false |
tokenizePanOffered |
boolean | Offers the client the option to tokenize their PAN. | false |
showInstallmentsSelection |
boolean | Shows the installments selection dropdown if enabled. | false |
tokenizePan
Option:
If true
, the PAN is tokenized upon transaction approval, and the pan_token
value is populated in the transaction response.
var style = {} // Define styling options for card component
var card = components.create("card", {
style: style,
tokenizePan: true // This will tokenize the PAN upon transaction approval
});
tokenizePanOffered
Option:
If true
, a "save card for future payments" checkbox is presented to the customer. If checked, the PAN is tokenized upon transaction approval, and pan_token
is populated.
var style = {} // Define styling options for card component
var card = components.create("card", {
style: style,
tokenizePanOffered: true // This enables the 'save card for future payments' checkbox in the form
});
Important Notes:
- If
tokenizePan
istrue
,tokenizePanOffered
is ignored. - Setting
tokenizePan
totrue
requires prior user consent (e.g., through accepted terms and conditions).
showInstallmentsSelection
Option:
If true
and installments are enabled for your merchant account, a dropdown for installment selection will be displayed.
var style = {} // Define styling options for card component
var card = components.create("card", {
style: style,
showInstallmentsSelection: true // This enables installments selection
});
Important Note: If showInstallmentsSelection
is true
but the dropdown doesn't appear, it means installments are disabled for your merchant account. Contact support@monri.com to enable them.
6. Transactions API: Variables, Lengths, and Formats
This section defines the variables and their properties used in API calls, particularly for JSON documents.
Buyer's Profile Fields
Name | Length | Format | Additional Info |
---|---|---|---|
ch_full_name |
3-30 | alphanumeric | Buyer's full name |
ch_address |
3-100 | alphanumeric | Buyer's address |
ch_city |
3-30 | alphanumeric | Buyer's postal code (ZIP) |
ch_zip |
3-9 | alphanumeric | Buyer's postal code (ZIP) |
ch_country |
2-3 | alphanumeric | Buyer’s country in alpha2, alpha3 letter code, or 3-digit ISO numeric code |
ch_phone |
3-30 | alphanumeric | Buyer's phone number |
ch_email |
3-100 | alphanumeric | Buyer's email address |
Order Details Fields
Name | Length | Format | Additional Info |
---|---|---|---|
order_info |
3-100 | alphanumeric | Short description of the order being processed |
order_number |
1-40 | printable characters | Unique identifier for the order |
amount |
3-11 | integer | Amount in minor units (e.g., 10.24 USD is sent as 1024) |
currency |
predefined | alphabetic | Possible values are USD, EUR, or BAM |
7. Viewport Meta Tag Requirements
To ensure an optimal user experience for 3D Secure (3DS) authentication across all devices, you should set your page’s viewport width
to device-width
using the viewport meta tag. Other viewport settings can be configured as needed, but width=device-width
is crucial.
Example:
<meta name="viewport" content="width=device-width, initial-scale=1"/>
If this tag is already present on your page and includes width=device-width
, no further action is required.