Use a prebuilt payment page
MONEI's Hosted Payment Page offers the simplest, PCI-compliant way to securely collect payments from your customers using various methods.
Key Features:
- Designed to remove friction: Real-time card validation with built-in error messaging.
- Mobile-ready: Fully responsive design.
- International: Supports 13 languages.
- Multiple payment methods: Supports various payments methods.
- Customization and branding: Customizable logo, buttons, and background color via your MONEI Dashboard.
- 3D Secure: Built-in support for SCA verification.
- Fraud and compliance: Simplified PCI compliance and SCA-ready.
You can customize the appearance in your MONEI Dashboard → Settings → Branding.
Before You Begin
- You'll need a MONEI account and your API keys (test or live). Find them in your MONEI Dashboard.
- Use your test mode keys for integration testing.
- Ensure relevant payment methods are enabled in your account settings.
- You can monitor test payments in your MONEI Dashboard → Payments (ensure Test Mode is active).
Integration Steps
The integration involves creating a payment on your server, redirecting your customer to MONEI's secure page, and handling their return to your site via redirects and webhooks.
1. Create Payment (Server-side)
First, make a server-side API call to create a new Payment object. This registers the payment intent with MONEI.
- cURL
- Node.js
- PHP
- Python
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": {
"name": "John Doe",
"email": "email@example.com",
"phone": "+34666555444"
},
"billingDetails": {
"name": "John Doe",
"address": {
"country": "ES",
"city": "Malaga",
"line1": "Fake Street 123",
"zip": "29001"
}
},
"callbackUrl": "https://example.com/checkout/callback",
"completeUrl": "https://example.com/checkout/complete",
"cancelUrl": "https://example.com/checkout/cancel"
}'
(Replace YOUR_API_KEY
with your actual MONEI API key)
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: {
name: 'John Doe',
email: 'email@example.com',
phone: '+34666555444'
},
billingDetails: {
name: 'John Doe',
address: {
country: 'ES',
city: 'Malaga',
line1: 'Fake Street 123',
zip: '29001'
}
},
callbackUrl: 'https://example.com/checkout/callback',
completeUrl: 'https://example.com/checkout/complete',
cancelUrl: 'https://example.com/checkout/cancel'
});
// You will need the redirectUrl from the response in the next step
const redirectUrl = payment.nextAction.redirectUrl;
<?php
require_once 'vendor/autoload.php';
use Monei\Model\CreatePaymentRequest;
use Monei\Model\PaymentCustomer;
use Monei\Model\PaymentBillingDetails;
use Monei\Model\Address;
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([
'name' => 'John Doe',
'email' => 'email@example.com',
'phone' => '+34666555444'
]),
'billing_details' => new PaymentBillingDetails([
'name' => 'John Doe',
'address' => new Address([
'country' => 'ES',
'city' => 'Malaga',
'line1' => 'Fake Street 123',
'zip' => '29001'
])
]),
'callback_url' => 'https://example.com/checkout/callback',
'complete_url' => 'https://example.com/checkout/complete',
'cancel_url' => 'https://example.com/checkout/cancel'
])
);
// You will need the redirectUrl from the response in the next step
$redirectUrl = $payment->getNextAction()->getRedirectUrl();
?>
import Monei
from Monei import CreatePaymentRequest, PaymentCustomer, PaymentBillingDetails, Address
# 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(
name="John Doe",
email="email@example.com",
phone="+34666555444"
),
billing_details=PaymentBillingDetails(
name="John Doe",
address=Address(
country="ES",
city="Malaga",
line1="Fake Street 123",
zip="29001"
)
),
callback_url="https://example.com/checkout/callback",
complete_url="https://example.com/checkout/complete",
cancel_url="https://example.com/checkout/cancel"
)
)
// You will need the redirectUrl from the response in the next step
redirect_url = payment.next_action.redirect_url
Key Parameters:
- amount
positive integer
: Amount in the smallest currency unit (e.g., 110 for €1.10). - currency
string
: Three-letter ISO currency code (e.g.,EUR
). - orderId
string
: Your unique order identifier. - completeUrl
string
: Where the customer is redirected after attempting payment (success or failure). - callbackUrl
string
: Your server endpoint URL for asynchronous webhook notifications (crucial for final status). - cancelUrl `string**: Where the customer is redirected if they click cancel or **"Back to shop"**.
Check all available request parameters.
The API response includes the payment.id
and, importantly, payment.nextAction.redirectUrl
.
2. Handle Payment Interaction (Client-side via Redirect)
The API response from Step 1 contains a nextAction
object with a redirectUrl
. You must redirect your customer's browser to this URL.
{
"id": "af6029f80f5fc73a8ad2753eea0b1be0", // MONEI Payment ID
// ... other fields ...
"status": "PENDING", // Initial status
"nextAction": {
"type": "CONFIRM",
"mustRedirect": true, // Indicates redirection is needed
"redirectUrl": "https://secure.monei.com/payments/af6029f80f5fc73a8ad2753eea0b1be0" // <-- REDIRECT CUSTOMER HERE
}
}
This redirectUrl
leads the customer to the secure, MONEI-hosted payment page where they will select a payment method and enter their details.
Instead of a full page redirect, you can use monei.js
to present payment options within a modal on your own site. See the Payment Modal Guide for details.
Customer Actions:
- The customer completes the payment details on the MONEI page.
- They might undergo 3D Secure verification if required by their bank.
- After completion, failure, or cancellation, they are redirected back to your site:
- To the
completeUrl
if they attempted payment. - To the
cancelUrl
if they explicitly cancelled.
- To the
Important: The redirect to completeUrl
does not guarantee payment success. You must rely on the webhook (Step 3) for the final status.
3. Process Webhook Notification (Server-side)
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 in JSON format.
This webhook is the only reliable way to confirm the definitive payment outcome, regardless of customer browser actions or redirects.
Crucially, you must:
- Verify the
MONEI-Signature
header included in the request. This confirms the webhook genuinely came from MONEI. See the Verify Signatures guide for implementation details. - 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.
{
"id": "af6029f80f5fc73a8ad2753eea0b1be0",
"amount": 110,
// ... other fields ...
"status": "SUCCEEDED", // <-- Check this for final status
"createdAt": 1594215339,
"updatedAt": 1594215345
}