# Cards

You can start accepting Card payments on the Web using [Hosted Payment Page](https://docs.monei.com/integrations/use-prebuilt-payment-page/.md) or [Card Input Component](https://docs.monei.com/monei-js/reference/.md#cardinput-component). No additional configuration is required for the Hosted Payment Page. It already supports all available payment methods and does not require coding.

Our [Card Input Component](https://docs.monei.com/monei-js/reference/.md#cardinput-component) renders a card input to your custom payment page. The Card Input Component lets you securely collect card information all within one component. It includes a dynamically-updating card brand icon as well as inputs for number, expiry and CVC. It is responsive, optimized for mobile devices, completely customizable and localized to 14 languages.

[](https://payments-demo.monei.com)

[Live demo](https://payments-demo.monei.com)

[Source code](https://github.com/MONEI/monei-payments-demo)

## Before you begin[​](#before-you-begin "Direct link to Before you begin")

This page explains how to add Card Input Component to your custom payment page. If you don't need a custom checkout experience we recommend using our [Hosted Payment Page](https://docs.monei.com/integrations/use-prebuilt-payment-page/.md).

To accept card payments you need to have at least one configured Card processor. To configure Card processors go to [MONEI Dashboard → Settings → Payment Methods → Card payments](https://dashboard.monei.com/settings/payment-methods/card).

To test your integration:

* Use your [test mode](https://docs.monei.com/testing/.md) Account ID and API Key.
* Use the test [card numbers](https://docs.monei.com/testing/.md#test-card-numbers).
* You can check the status of a test payment in your [MONEI Dashboard → Payments](https://dashboard.monei.com/payments) (in test mode).

## Integration[​](#integration "Direct link to Integration")

### 1. Create a Payment `Server-side`[​](#1-create-a-payment-server-side "Direct link to 1-create-a-payment-server-side")

Create a [Payment](https://docs.monei.com/apis/rest/schemas/payment/.md) on your server with an amount and currency. Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious customers from being able to choose their own prices.

<!-- -->

* cURL
* Node.js
* PHP
* Python

POST https\://api.monei.com/v1/payments

```
curl --request POST 'https://api.monei.com/v1/payments' \

--header 'Authorization: YOUR_API_KEY' \

--header 'Content-Type: application/json' \

--data-raw '{

  "amount": 110,

  "currency": "EUR",

  "orderId": "14379133960355",

  "description": "Test Shop - #14379133960355",

  "customer": {

    "email": "email@example.com"

   },

  "callbackUrl": "https://example.com/checkout/callback"

}'
```

(Replace `YOUR_API_KEY` with your actual MONEI API key)

server.js

```
import {Monei} from '@monei-js/node-sdk';



// Replace YOUR_API_KEY with your actual MONEI API key

const monei = new Monei('YOUR_API_KEY');



const payment = await monei.payments.create({

  amount: 110,

  currency: 'EUR',

  orderId: '14379133960355',

  description: 'Test Shop - #14379133960355',

  customer: {

    email: 'email@example.com'

  },

  callbackUrl: 'https://example.com/checkout/callback'

});



// Pass payment.id to your client-side

const paymentId = payment.id;
```

server.php

```
<?php

require_once 'vendor/autoload.php';



use Monei\Model\CreatePaymentRequest;

use Monei\Model\PaymentCustomer;

use Monei\MoneiClient;



// Replace YOUR_API_KEY with your actual MONEI API key

$monei = new MoneiClient('YOUR_API_KEY');



$payment = $monei->payments->create(

  new CreatePaymentRequest([

    'amount' => 110,

    'currency' => 'EUR',

    'order_id' => '14379133960355',

    'description' => 'Test Shop - #14379133960355',

    'customer' => new PaymentCustomer([

      'email' => 'email@example.com'

    ]),

    'callback_url' => 'https://example.com/checkout/callback'

  ])

);



// Pass payment ID to your client-side

$paymentId = $payment->getId();

?>
```

server.py

```
import Monei

from Monei import CreatePaymentRequest, PaymentCustomer



# Replace YOUR_API_KEY with your actual MONEI API key

monei = Monei.MoneiClient(api_key="YOUR_API_KEY")



payment = monei.payments.create(

    CreatePaymentRequest(

        amount=110,

        currency="EUR",

        order_id="14379133960355",

        description="Test Shop - #14379133960355",

        customer=PaymentCustomer(

          email="email@example.com"

        ),

        callback_url="https://example.com/checkout/callback"

    )

)



# Pass payment ID to your client-side

payment_id = payment.id
```

The following parameters are required:

* **amount** positive integer - Amount intended to be collected by this payment. A positive integer representing how much to charge in the smallest currency unit (e.g., 100 cents to charge 1.00 USD)
* **currency** string - Three-letter [ISO currency code](https://en.wikipedia.org/wiki/ISO_4217), in uppercase. Must be a supported currency.
* **orderId** string - An order ID from your system. A unique identifier that can be used to reconcile the payment with your internal system.
* **callbackUrl** string - The URL to which a payment result should be sent asynchronously.

Check all available [request parameters](https://docs.monei.com/apis/rest/payments-create/.md).

Included in the returned Payment object is a payment `id`, which is used on the client side to securely complete the payment process instead of passing the entire Payment object.

### 2. Collect card details `Client-side`[​](#2-collect-card-details-client-side "Direct link to 2-collect-card-details-client-side")

Include `monei.js` on your checkout page by adding the script tag to the `head` of your HTML file.

checkout.html

```
<head>

  <title>Checkout</title>

  <script src="https://js.monei.com/v3/monei.js"></script>

</head>
```

Add MONEI [Card Input Component](https://docs.monei.com/monei-js/reference/.md#cardinput-component) to your payment page. Create empty DOM nodes (containers) with unique IDs in your payment form.

checkout.html

```
<form id="payment-form">

  <div class="card-field">

    <div id="card-input">

      <!-- A MONEI Card Input Component will be inserted here. -->

    </div>

    <!-- Used to display card errors. -->

    <div id="card-error"></div>

  </div>

  <button type="submit" id="payment-button">Submit payment</button>

</form>
```

Initialize Card Input Component

client.js

```
const container = document.getElementById('card-input');

const errorText = document.getElementById('card-error');



// Create an instance of the Card Input using payment_id.

const cardInput = monei.CardInput({

  paymentId: '{{payment_id}}',

  onChange: function (event) {

    // Handle real-time validation errors.

    if (event.isTouched && event.error) {

      container.classList.add('is-invalid');

      errorText.innerText = event.error;

    } else {

      container.classList.remove('is-invalid');

      errorText.innerText = '';

    }

  }

});



// Render an instance of the Card Input into the `card_input` <div>.

cardInput.render(container);
```

The Card Input Component simplifies the form and minimizes the number of required fields by inserting a single, flexible input field that securely collects all necessary card details.

note

Card Input Component is also available as a [React](https://docs.monei.com/monei-js/react/.md), [Vue](https://docs.monei.com/monei-js/vue/.md), [Angular](https://docs.monei.com/monei-js/angular/.md), and [Svelte](https://docs.monei.com/monei-js/svelte/.md) component.

Check the [MONEI JS Reference](https://docs.monei.com/monei-js/reference/.md#cardinput-component) for more options.

### 3. Confirm the payment `Client-side`[​](#3-confirm-the-payment-client-side "Direct link to 3-confirm-the-payment-client-side")

To complete the payment you need to confirm it using monei.js [confirmPayment](https://docs.monei.com/monei-js/reference/.md#confirmpayment-function) function.

You need to provide a `paymentId` (obtained in [step 1](#1-create-a-payment-server-side)) and `paymentToken` generated with Card Input Component. You can also provide additional parameters like `customer.email`. Check all available [parameters](https://docs.monei.com/apis/rest/payments-confirm/.md).

client.js

```
// Handle form submission.

const paymentForm = document.getElementById('payment-form');

const paymentButton = document.getElementById('payment-button');

paymentForm.addEventListener('submit', async function (event) {

  event.preventDefault();

  paymentButton.disabled = true;

  try {

    // Generate a payment token from the card input

    const {token, error} = await cardInput.submit();



    if (error) {

      // Inform the user if there was an error.

      container.classList.add('is-invalid');

      errorText.innerText = error;

      return;

    }



    container.classList.remove('is-invalid');

    errorText.innerText = '';



    // Confirm the payment with the generated token

    const result = await monei.confirmPayment({

      paymentId: '{{payment_id}}',

      paymentToken: token,

      paymentMethod: {card: {cardholderName: 'JOHN DOE'}}

    });



    // At this moment you can show a customer the payment result

    // But you should always rely on the result passed to the callback endpoint on your server

    // to update the order status

    console.log(result);

  } catch (error) {

    console.error(error);

  } finally {

    paymentButton.disabled = false;

  }

});
```

After the form is submitted MONEI will automatically show a popup window with 3d secure confirmation screen (if needed)

note

As an alternative process you can submit generated `paymentToken` to your server and then [confirm payment](https://docs.monei.com/apis/rest/payments-confirm/.md) on the server-side.

### 4. Process Webhook Notification `Server-side`[​](#4-process-webhook-notification-server-side "Direct link to 4-process-webhook-notification-server-side")

After the client-side interaction and any necessary background processing (like 3D Secure or bank authorization), MONEI sends the final, authoritative payment status via an asynchronous HTTP POST request to the `callbackUrl` you provided in Step 1.

The request body contains the full [Payment object](https://docs.monei.com/apis/rest/schemas/payment/.md) in JSON format.

This webhook is the **only reliable way** to confirm the definitive payment outcome.

**Crucially, you must:**

1. **Verify the `MONEI-Signature` header** included in the request. This confirms the webhook genuinely came from MONEI. See the [Verify Signatures guide](https://docs.monei.com/guides/verify-signature/.md) for implementation details.
2. **Return a `200 OK` HTTP status code** immediately upon receiving the webhook to acknowledge receipt. Any other status code tells MONEI the notification failed.

If MONEI doesn't receive a `200 OK`, it will retry sending the webhook.

Once the signature is verified, inspect the `status` field in the Payment object (`SUCCEEDED`, `FAILED`, `CANCELED`, etc.) to determine whether to fulfill the order or handle the failure.

## Before you go live[​](#before-you-go-live "Direct link to Before you go live")

* Make sure that you are using [live (production) mode](https://docs.monei.com/testing/.md) Account ID and API Key.
* Make sure that you have at least one [enabled card processor](https://dashboard.monei.com/settings/payment-methods/card).

## Additional information[​](#additional-information "Direct link to Additional information")

### Transaction limits[​](#transaction-limits "Direct link to Transaction limits")

The default maximum amount per card transaction is 4,000 EUR. This limit can be increased — contact our [Support Team](https://support.monei.com/hc/requests/new) to adjust it for your account.

### Refunds[​](#refunds "Direct link to Refunds")

Businesses can issue refunds directly through the [MONEI Dashboard](https://dashboard.monei.com) within 180 days of the transaction date. For refunds on older transactions, please contact our [Support Team](https://support.monei.com/hc/requests/new).
