# Embedded Checkout (v2)

Embedded Checkout is powered by the **xMoney.js v2 SDK**. It lets you add secure payment components directly to your website or mobile WebView while keeping sensitive card data inside xMoney-hosted iframes.

Use Embedded Checkout when you want customers to stay in your checkout experience instead of being redirected to the xMoney hosted checkout page. For redirect-based checkout, see [Hosted Checkout](/guides/checkout/hosted-checkout).

## What you can build

The SDK is modular. You can use one full payment form or compose individual components into a custom checkout.

| SDK method | Purpose |
|  --- | --- |
| `window.XMoney.paymentForm(config)` | Full inline checkout form with card, saved cards, Apple Pay, and Google Pay. |
| `window.XMoney.paymentCard(config)` | Card-only form for custom layouts. |
| `window.XMoney.applePay(config)` | Standalone Apple Pay button. |
| `window.XMoney.googlePay(config)` | Standalone Google Pay button. |
| `window.XMoney.savedCardPayment(config)` | Headless payment with an existing saved card. |
| `window.XMoney.getPaymentMethodCapabilities()` | Detect Apple Pay and Google Pay availability before rendering wallet buttons. |


## Integration guides

Website integration
Create an order on your backend, mount `paymentForm()`, handle callbacks, update cart totals, and clean up SDK instances.

Custom layouts
Compose `paymentCard()`, standalone wallet buttons, manual submit, validation, runtime theming, and capability checks.

Saved cards
Save cards during checkout and charge existing card tokens with `savedCardPayment().pay({ cardId })`.

3DS and results
Understand 3DS modal behavior, background transaction refresh, result callbacks, redirect fallback, and server-side confirmation.

Mobile WebViews
Use the same inline checkout page inside iOS or Android WebViews while preserving wallet and 3DS lifecycle behavior.

## Quickstart

### 1. Load the SDK

```html
<!-- Production -->
<script src="https://secure.xmoney.com/sdk/v2/xmoney.js"></script>

<!-- Staging -->
<script src="https://secure-stage.xmoney.com/sdk/v2/xmoney.js"></script>
```

### 2. Add a container

```html
<div id="xmoney-payment-form"></div>
```

### 3. Create a signed order on your backend

Your backend creates the order payload, signs it with your private key, and returns only the public values needed by the browser:

```json
{
  "publicKey": "pk_test_your_key",
  "orderPayload": "base64-encoded-order",
  "orderChecksum": "base64-encoded-checksum"
}
```

Never expose your private key in client-side code.

### 4. Mount the payment form

```javascript
const paymentForm = await window.XMoney.paymentForm({
  container: 'xmoney-payment-form',
  publicKey,
  orderPayload,
  orderChecksum,
  card: {
    savedCards: {
      enabled: true,
      optInVisible: true,
    },
  },
  paymentMethods: {
    applePay: { enabled: true },
    googlePay: { enabled: true },
  },
  options: {
    locale: 'en-US',
    enableBackgroundRefresh: true,
    appearance: {
      theme: 'light',
    },
  },
  onReady() {
    console.log('Payment form ready')
  },
  onPaymentProcessing(isProcessing) {
    console.log('Processing:', isProcessing)
  },
  onPaymentComplete(transaction) {
    console.log('Payment completed:', transaction)
  },
  onError(error) {
    console.error('Payment error:', error)
  },
})
```

### 5. Destroy on unmount

```javascript
paymentForm.destroy()
```

Always destroy SDK instances when your checkout component unmounts or the shopper leaves the checkout page.

## Common configuration

| Property | Required | Description |
|  --- | --- | --- |
| `container` | Required for visual widgets | Element id or `HTMLElement` where the iframe should be mounted. |
| `publicKey` | Yes | Your xMoney public site key, such as `pk_test_...` or `pk_live_...`. |
| `orderPayload` | Yes | Base64-encoded order payload from your backend. |
| `orderChecksum` | Yes | HMAC signature generated by your backend. |
| `card` | No | Card UI, saved cards, submit button, and validation behavior. |
| `paymentMethods` | No | Apple Pay and Google Pay configuration for `paymentForm()`. |
| `options` | No | Locale, appearance, and result behavior such as `enableBackgroundRefresh`. |


## Security model

Embedded Checkout keeps payment collection isolated:

1. Card inputs and wallet flows are rendered in xMoney-hosted iframes.
2. Your backend signs order details before the browser receives them.
3. The SDK validates that the signed payload matches the public key.
4. Final fulfillment should be confirmed server-side through webhooks or trusted API checks.


If your checkout page uses Content Security Policy, configure `frame-src` for the SDK's iframe-based 3DS modal. Issuer ACS domains vary, so embedded 3DS requires allowing HTTPS frame destinations. See [3DS and payment results](/guides/checkout/inline-checkout/3ds-results#content-security-policy-for-embedded-3ds).

Confirm final status on your backend
`onPaymentComplete` is a client-side callback for updating the shopper experience. Always verify the final transaction status server-side before fulfilling an order or storing a saved-card token.

## Browser and wallet support

The card form is designed for modern desktop and mobile browsers. Wallet availability depends on the shopper's device, browser, wallet setup, domain verification, and merchant activation.

Before rendering standalone wallet buttons, use:

```javascript
const capabilities = await window.XMoney.getPaymentMethodCapabilities()
```

For wallet-specific setup, see [Apple Pay](/guides/payments/payment-methods/apple-pay) and [Google Pay](/guides/payments/payment-methods/google-pay).