Skip to content

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

Integration Modes

ModeDescriptionUse Case
FullRenders the entire checkout form including saved cards and submit button.Fastest integration with minimal frontend effort
Embed Card ElementsEmbed only the necessary input elements (card input, expiry, CVV), with full UI control.Custom UI or deeper

Full Flow Overview

Merchant's FrontendMerchant's APIxMoney API SDKxMoney Frontend SDKxMoney APIInit SDK with SecretKeyRedirect to backurl if setloop[Every minute]Do something with order statusPrepare order data.initializeCheckout()Encrypted payloadEncrypted payload.xMoneyCheckout()fetch cards for userId if neededreturn cardsRender payment form.submitPayment()Process transactionGet order status.getOrder()get orderreturn order dataorder dataorder dataMerchant's FrontendMerchant's APIxMoney API SDKxMoney Frontend SDKxMoney API

1. Set up the xMoney Fronted SDK

First, add the xMoney Client SDK to your website.

Installation

Via CDN

    <script
      src="https://secure-stage.xmoney.com/sdk/0.0.7/xmoney.js"
    ></script>

Full Payment Form

const sdk = new window.XMoneyPaymentForm({
    container: "payment-form-widget", // placeholder for the payment form
    elementsOptions: {
      appearance: customThemeStyles,
      locale: "en-US", // "en-US" | "el-GR" | "ro-RO";
      saveCardOption?: true; // displays the checkbox for saving the cards
      validationMode?: "onSubmit" | "onChange" | "onBlur" | "onTouched"; // Validation mode for the form. Default is "onSubmit".
    }
    savedCards: [], // list with saved cards prefetched for a customerId
    checksum: '', // checksum for the payment payload, received from the API
    payload: '', // order payload
    publicKey: PUBLIC_KEY, // your public key using the pk_<env>_<siteId> format
    onReady: () => setIsReady(true), // callback when the paymentForm is ready
    onError: (err: any) => console.error("❌ Payment error", err), // error callback
  });

Display the Inline Checkout Form

<div id="payment-form-widget" style={{ opacity: isReady() ? 1 : 0 }} />

This creates a secure, payment form directly into your checkout page.

SDK Instance public properties

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.

Methods

updateOrder(payload: string, checksum: string): void

Updates the order details in the payment form.

Parameters:
  • payload (string): A JSON string containing the updated order details.
  • checksum (string): A string used to verify the integrity of the request.

updateLocale(locale: "en-US" | "el-GR" | "ro-RO"): void

Changes the locale of the payment form to support multiple languages.

Parameters:
  • 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)

updateAppearance(appearance: AppearanceOptions): void

Updates the visual appearance and theme of the payment form.

Parameters:
  • appearance (AppearanceOptions): An object that defines the theme and styling rules.
AppearanceOptions Object:
  • 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.

close(): void

Closes the payment form interface without destroying it.


destroy(): void

Performs cleanup and permanently destroys the payment form instance.


Init Parameters explained

ParameterTypeRequiredDescriptionAvailability
containerstringyesDOM selector where the card input will be mounted. This will draw all 3 card elements (card number, expiry, cvv) into the DOM.v1.0
publicKeystringyesMerchant’s public key. It has this format: pk_<env>_siteUID. Env can be: test or live.v1.0
onReadyfunctionnoCallback fired when the widget is successfully loaded.v1.0
onErrorfunctionnoCallback fired when the payment fails. Receives an error object with details.v1.0
elementOptionsobjectnoOptional customizations (primary text color, font)v1.0

Customize the Experience

You can easily customize the UI of your checkout form.

Theme Options

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",
  },

Localization

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

Advanced: Saved Cards and One-Click Payments

If you want to offer one-click checkout for returning customers, simply enable card saving:

saveCardOption: true; // show "Save card" checkbox for new cards

On future checkouts, pre-fill saved cards securely without collecting card info again.

SDK Instance methods

2. Create a Payment Intent (Server Side)

Before submitting a payment, you must create a payment intent on your server using the xMoney API SDK.

Install the API SDK

npm install @xmoney/api-sdk

Initialize the API SDK

import xMoneyApiClient from "@xmoney/api-sdk";

const client = new xMoneyApiClient({
  secretKey: "sk_test_secretkey",
});

Initialize the checkout


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

3. Validate the card inputs

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.

4. Handle the payment result

Client

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.

Handle response without redirect

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.

Prerequisites
  • You have the orderId from your system
  • You have access to the xMoney Get Order
Behaviour
  • 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-ok or complete-failed) stop the polling and update the UI
  • Remove the payment form by calling sdk.close()

API

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.

5. 3DSv2 Authentication

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.

6. Mobile Integration via WebView

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.

Example

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

7. Examples

Checkount-Samples-API setup

Clone the repository

git clone git@github.com:xMoney-Payments/checkout-samples-api.git
cd checkout-samples-api

Install dependencies

npm install

Set the secretKey Update the app.service.ts class and set the correct secret key when initialising the xMoneyApiClient

constructor() {
    this.xMoneyApiClient = new xMoneyApiClient({
      secretKey: 'sk_test_<your-secret-key>',
      verbose: true,
    });
  }

Run

npm run start:dev

Checkout-Samples setup

Clone the repository

git clone git@github.com:xMoney-Payments/checkout-samples.git
cd checkout-sample

Install dependencies

npm install

Update 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 USER_ID too. After the first successful test payment you will receive customerId in the response which can be used for future testing.

export const USER_ID = <customerId>;

Run the app

npm start

Testing

To test various scenarios you can use these test cards