This guide shows you how to securely accept payments (cards, alternative payments) directly on your website, using our Embedded Components SDK and API SDK.
This guide covers:
- Integrating the xMoney Client SDK
- Creating payment intents with the Server API SDK
- Submitting and confirming payments
- Mobile integration via WebView
| Mode | Description | Use Case |
|---|---|---|
| Full | Renders the entire checkout form including saved cards and submit button. | Fastest integration with minimal frontend effort |
| Embed Card Elements | Embed only the necessary input elements (card input, expiry, CVV), with full UI control. | Custom UI or deeper |
First, add the xMoney Client SDK to your website.
Via CDN
<script
src="https://secure.xmoney.com/sdk/v1/xmoney.js"
></script>const sdk = new window.XMoneyPaymentForm({
container: "payment-form-widget", // placeholder for the payment form
orderChecksum: '', // checksum for the payment payload, received from the API
orderPayload: '', // order payload
publicKey: PUBLIC_KEY, // your public key using the pk_<env>_<siteId> format
/**
* Session token used for background data refresh or saved card functionality.
*/
sessionToken?: '', // - Required if `options.enableBackgroundRefresh` is `true` or `options.enableSavedCards` is `true`.
/**
* Customer ID associated with the payment form.
*/
customerId?: 0; // Required if `options.enableSavedCards` is `true`.
options: {
appearance: customThemeStyles,
locale: "en-US", // "en-US" | "el-GR" | "ro-RO";
buttonType?: "book" | "buy" | "checkout" | "donate" | "order" | "pay" | "subscribe" | "topUp";
validationMode?: "onSubmit" | "onChange" | "onBlur" | "onTouched", // Validation mode for the form. Default is "onSubmit".
displaySaveCardOption?: true, // displays the checkbox for saving the cards
enableSavedCards?: true, // Display a list of saved cards
enableBackgroundRefresh?: true, // Enables background refresh for the payment form
displaySubmitButton?: true, // Displays the submit button in the form.
/**
* Card holder verification options.
*/
cardHolderVerification?: {
/**
* Name information for card holder verification.
*/
name: {
firstName: string;
middleName: string;
lastName: string;
},
/**
* Callback function for cardholder verification.
*/
onCardHolderVerification: (
verificationResult: CardHolderVerificationResult
) => boolean;
};
googlePay?: GooglePayOptions,
/**
* Appearance customization for Apple Pay button.
*/
applePay?: ApplePayOptions,
}
onReady: () => setIsReady(true), // callback when the paymentForm is ready
onError: (err: any) => console.error("❌ Payment error", err), // error callback
onPaymentComplete: (data: unknown) => void; // Callback executed when the payment is completed.
/**
* Callback executed when the form submission state changes.
*/
onSubmitPending?: (isPending: boolean) => void; // * // @param isPending - `true` if the form is submitting, `false` otherwise.
});<div id="payment-form-widget" style={{ opacity: isReady() ? 1 : 0 }} />This creates a secure, payment form directly into your checkout page.
The SDK instance provides several available methods for interacting with the xMoney Payment Form. It allows dynamic updates to order details, locale, appearance and handles form lifecycle events sucs as closing and destroying.
Updates the order details in the payment form.
orderPayload(string): A JSON string containing the updated order details.orderChecksum(string): A string used to verify the integrity of the request.
Changes the locale of the payment form to support multiple languages.
locale("en-US"|"el-GR"|"ro-RO"): The locale to set.
Supported values:en-US: English (United States)el-GR: Greek (Greece)ro-RO: Romanian (Romania)
Updates the visual appearance and theme of the payment form.
appearance(AppearanceOptions): An object that defines the theme and styling rules.
theme?("light"|"dark"|"custom"): The visual theme. Defaults to"light".variables?(Record<string, string>): CSS variables used in custom themes.rules?(Record<string, Record<string, string>>): CSS rules for targeted custom styling.
Submits the payment form. Useful when the submit button is not displayed.
Closes the payment form interface without destroying it.
Performs cleanup and permanently destroys the payment form instance.
| Parameter | Type | Required | Description | Availability |
|---|---|---|---|---|
| container | string | yes | DOM selector where the card input will be mounted. This will draw all 3 card elements (card number, expiry, cvv) into the DOM. | v1 |
| publicKey | string | yes | Merchant’s public key. It has this format: pk_<env>_siteUID. Env can be: test or live. | v1 |
| onReady | function | no | Callback fired when the widget is successfully loaded. | v1 |
| onError | function | no | Callback fired when the payment fails. Receives an error object with details. | v1 |
| onPaymentComplete | function | no | Callbeck fired when the payment is complete. This callback will not be triggered if enableBackgroundRefresh is false. | v1 |
| options | object | no | Optional customizations (primary text color, font) | v1 |
| sessionToken | string | no | Session token used for background data refresh or saved card functionality. Required if options.enableBackgroundRefresh is trueor options.enableSavedCards is true. | v1 |
| orderChecksum | string | yes | Checksum for the order, used for request integrity validation. The checksum is obtained by signing the orderPayload with the secret key. | v1 |
| orderPayload | string | yes | Base64-encoded order payload containing order details. | v1 |
| customerId | number | no | The id of the customer from xMoney. It is used to automatically fetch the list of saved cards. This is is returned when the customer is initialy created, after a succesfull order. Please store the customerId in your system for future usage. | v1 |
You can easily customize the UI of your checkout form.
const customThemeStyles = {
theme?: "light" | "dark" | "custom";
variables: {
colorPrimary: "#009688",
colorDanger: "#e53935",
colorText: "#212121",
colorTextSecondary: "#757575",
colorTextPlaceholder: "#bdbdbd",
colorBorder: "#e0e0e0",
colorBorderFocus: "#009688",
colorBackground: "#f5f5f5",
colorBackgroundFocus: "#0096880a",
},Set the locale manually or auto-detect based on browser settings.
locale: 'ro-RO'If locale is omitted the SDK will default to en-US
If you want to offer one-click checkout for returning customers, simply enable card saving:
displaySaveCardOption: true; // show "Save card" checkbox for new cardsOn future checkouts, pre-fill saved cards securely without collecting card info again.
Defines the label and intent of the submit payment button displayed on the payment form. This property helps merchants tailor the button text to the context of their checkout flow, improving clarity and conversion.
Type: "book" | "buy" | "checkout" | "donate" | "order" | "pay" | "subscribe" | "topUp"
Default: "pay"
Supported Values
| Value | Purpose / Typical Use Case |
|---|---|
| book | For reservation-based flows (e.g., booking services, appointments, travel). |
| buy | For direct product purchases, especially simple one-time purchases. |
| checkout | For multi-step or cart-based checkout flows. |
| donate | For donation-driven flows (charities, contributions, fundraising). |
| order | For ordering goods or services where the final action is “Place Order.” |
| pay (default) | Generic payment action suitable for most cases. |
| subscribe | For recurring payments or subscription-based products. |
| topUp | For adding balance to an account, wallet, or prepaid service. |
Determines when form fields are validated during user interaction. This setting controls how quickly users receive feedback about invalid or incomplete input.
Type:
- "onSubmit" | "onChange" | "onBlur" | "onTouched"
Default:
- "onChange"
Supported Values
| Value | Behavior / Typical Use Case |
|---|---|
| onSubmit | Validates only when the user submits the form. Ideal for simple forms or when you want to reduce interruptions during typing. |
| onChange (default) | Validates live as the user types or updates a field. Best for payment forms requiring immediate feedback on card number, expiry, etc. |
| onBlur | Validates when the user leaves a field. Useful for reducing validation noise while still giving timely feedback. |
| onTouched | Validates a field after it has been focused at least once, and then on subsequent updates. Balanced approach between onChange and onBlur. |
Configuration options for enabling and customizing the Google Pay payment option within the payment form.
googlePay: {
enabled?: boolean;
appearance?: {
color?: "white" | "black";
radius?: number;
type?:
| "book"
| "buy"
| "checkout"
| "donate"
| "order"
| "plain"
| "pay"
| "subscribe";
borderType?: "default_border" | "no_border";
};
}Properties
enabled: Enables Google Pay as an available payment method.
• Type: boolean
• Default: false
appearance: Controls the look and feel of the Google Pay button.
color: Defines the button color.
• Type: "white" | "black"
• Default: "black" in light theme, "white" in dark theme
radius: Sets the corner radius of the button.
• Type: number
• Default: 12
type: Customizes the label and action descriptor of the Google Pay button.
• Type: "book" | "buy" | "checkout" | "donate" | "order" | "plain" | "pay" | "subscribe"
• Default: "pay"
borderType: Determines the button’s border style.
• Type: "default_border" | "no_border"
• Default: "no_border"
Configuration options for enabling and customizing the Apple Pay payment option within the payment form.
applePay: {
enabled?: boolean;
appearance?: {
style?: "white" | "black" | "white-outline";
radius?: number;
type?:
| "add-money"
| "book"
| "buy"
| "checkout"
| "contribute"
| "continue"
| "donate"
| "order"
| "plain"
| "pay"
| "reload"
| "rent"
| "set-up"
| "subscribe"
| "support"
| "tip"
| "top-up";
};
}Properties
enabled: Enables Apple Pay as an available payment method.
• Type: boolean
• Default: false
appearance: Controls the visual appearance of the Apple Pay button.
style: Defines the Apple Pay button style.
• Type: "white" | "black" | "white-outline"
• Default: "black" in light theme, "white" in dark theme
radius: Corner radius of the Apple Pay button.
• Type: number
• Default: 12
type: Sets the Apple Pay button’s action type text, depending on the context of the transaction.
• Type: "add-money" | "book" | "buy" | "checkout" | "contribute" | "continue" | "donate" | "order" | "plain" | "pay" | "reload" | "rent" | "set-up" | "subscribe" | "support" | "tip" | "top-up"
• Default: "pay"
Before submitting a payment, you must create a payment intent on your server using the xMoney API SDK.
npm install @xmoney/api-sdkimport xMoneyApiClient from "@xmoney/api-sdk";
const client = new xMoneyApiClient({
secretKey: "sk_test_secretkey",
});There are 2 different ways to generate a new session token. Via our API SDK, or via API endpointl
const sessionToken = await client.getSessionToken();
console.log(sessionToken.token)The full details can be found here
- Test Environment:
https://api-stage.xmoney.com - Production Environment:
https://api.xmoney.com
GET /auth/jwt-tokenThe endpoint requires Bearer token authentication using your secret key. Refer to Authentication documents for extra details.
curl -X GET "https://api-stage.xmoney.com/auth/jwt-token" \
-H "Authorization: Bearer your_secret_key_here" \
-H "Content-Type: application/json"
async function createPaymentIntent(orderData, customerData) {
const checkout = client.initializeCheckout({
publicKey: orderData.publicKey,
customer: {
identifier: customerData.id,
firstName: customerData.firstName,
lastName: customerData.lastName,
country: customerData.country,
city: customerData.city,
email: customerData.email,
},
order: {
orderId: orderData.id,
description: orderData.description,
type: "purchase",
amount: orderData.amount,
currency: orderData.currency,
},
cardTransactionMode: "authAndCapture",
backUrl: "https://localhost:3002/transaction-result", // this is the client side URL, where the user will be redirected
});
return checkout; // { payload, checksum }
}You will use the checkout object as an input on the initialization of the paymentForm or submitPaymet() function on the Embedded card elemenets in client SDK
Before submitting the payment, you can validate the card fields programmatically, along with your own checkout page validation.
Use the built-in validate(showErrors: bool) method from the xMoneyCheckout instance. Passing true will automatically show the errors bellow the checkout elements. Passing false will just validate and return the errors so you can handle the messages and how they are displayed to your customers.
const { cardNumberError, expDateError, cvvError } = await xMoneyCheckout.validate(true);
if (cardNumberError || expDateError || cvvError) {
console.error('Validation errors:', { cardNumberError, expDateError, cvvError });
// Stop the process
} else {
// Proceed to submit the payment
}This ensures the card inputs are correctly validated before attempting a payment.
After submitting the payment, handle the encrypted response for the payment received on the redirect using the backUrl. Send the result back to your merchant backend for decryption.
To provide a seamless user experience in your inline checkout integration with xMoney, you can implement a polling mechanism that continuously checks the status of an order until it’s completed, avoiding the need for a post-payment redirect.
- You have the orderId from your system
- You have access to the xMoney Get Order
- Call GET
/order?page=0&perPage=1&externalOrderId=<your-order-id>endpoint repeatedly (e.g. every 6 seconds) - Once the status contains "complete" (e.g.
complete-okorcomplete-failed) stop the polling and update the UI - Remove the payment form by calling
sdk.close()
On the server side, decrypt the response using the API SDK:
const paymentResponse = this.xMoneyApiClient.decryptOrderResponse(
body.result,
);
//TODO Your business logic here
if (
paymentResponse.transactionStatus ===
xMoneyTransactionStatusEnum.CompleteOk
) {
console.log('Transaction was successful');
}
return Promise.resolve(paymentResponse);Display the decrypted transaction status to your users accordingly.
The SDK automatically detects and sends necessary 3DSv2 parameters, like:
- Browser IP
- Browser Language
- User Agent
You don't need to manually collect these unless you want to override defaults.
You can also use xMoney Checkout in a mobile app using a WebView. The API SDK returns a full HTML page that you load directly.
import xMoney from "@xmoney/api-sdk";
const xMoneyApiClient = new xMoney({
secretKey: "sk_test_secretKey",
});
const orderHtml = xMoneyApiClient.getWebviewCheckoutHtml({
publicKey: 'pk_test_abc123',
customer: {
identifier: "customerIdentifier",
firstName: "John",
lastName: "Doe",
country: "RO",
city: "Bucharest",
email: "john.doe@test.com",
},
order: {
orderId: "myUniqueOrderId",
description: "Order Description",
type: "purchase",
amount: 100,
currency: "EUR",
},
cardTransactionMode: "authAndCapture",
backUrl: "https://127.0.0.1:8080",
});Render orderHtml inside a mobile WebView. This is ideal for hybrid apps or apps where embedding raw form components is not desirable.
Find more details about Accepting Payments in Your Mobile App
- Frontend demo: Inline Checkout GitHub Example
- Backend demo: Inline Checkout API Githup Example
- SDK API
Clone the repository
git clone https://github.com/xMoney-Payments/checkout-samples-api.git
cd checkout-samples-apiInstall dependencies
npm installSet the secretKey Copy the .env.example file to .env and update the PRIVATE_KEY with you secret key
Copy and update the .env file with the correct secret key. This key will be used when initialising the xMoneyApiClient
cp .env.example .envRun
npm run start:devClone the repository
git clone https://github.com/xMoney-Payments/checkout-samples.git
cd checkout-sampleInstall dependencies
npm installUpdate configs
Set the public key in src/constants/general.constants.ts
export const PUBLIC_KEY = "pk_test_<your_site_id>";To fetch the saved cards you need to set a CUSTOMER_ID too. After the first successful test payment you will receive customerId in the response which can be used for future testing.
export const CUSTOMER_ID = <customerId>;Run the app
npm startTo test various scenarios you can use these test cards