Mollie
Mollie : solution de paiements européenne avec 25+ méthodes locales (iDEAL, Bancontact, SEPA). Integration simple et pricing transparent.
📚 Ressources Complémentaires
📖 Guides Pratiques
⚖️ Comparatifs
Mollie : Paiements Européens Simplifiés
Qu’est-ce que Mollie ?
Mollie est la solution de paiements européenne de référence avec 200 000+ marchands incluant Booking.com, Philips et Coolblue. Cette fintech néerlandaise excelle dans la simplicité d’intégration avec 25+ méthodes locales (iDEAL, Bancontact, SEPA, Sofort) et pricing transparent sans frais cachés.
🚀 Fonctionnalités Principales
Méthodes Paiement Européennes
- iDEAL : banking direct Pays-Bas (60% market share)
- Bancontact : méthode dominante Belgique
- SEPA Direct Debit : prélèvements automatiques
- Sofort : instant bank transfer Allemagne/Autriche
Cartes & Wallets
- Visa/Mastercard : processing standard
- American Express : acceptation premium
- PayPal : integration seamless
- Apple Pay & Google Pay : mobile wallets
Developer-Friendly APIs
- RESTful APIs : modern architecture
- Webhooks : event notifications automatiques
- Test environment : sandbox complet
- SDKs : PHP, Python, Node.js, .NET
Business Tools
- Recurring billing : subscriptions et abonnements
- Marketplace : split payments automatiques
- Fraud protection : ML risk scoring
- Reporting : analytics et reconciliation
💰 Prix et Frais
Tarifs Standard
- Cartes européennes : 1,8% + 0,25€
- Cartes américaines : 2,8% + 0,25€
- iDEAL : 0,29€ par transaction
- Bancontact : 0,31€ par transaction
- SEPA Direct Debit : 0,25€ par transaction
Frais Additionnels
- Chargeback : 15€ per dispute
- Refund : gratuit (partial/full)
- Payout : gratuit daily automatic
- Currency conversion : 2% spread
Plans Enterprise
- Volume discounts : négociables >100k€/mois
- Custom rates : selon volume et mix methods
- Dedicated support : account manager
- SLA guarantees : uptime et response
⭐ Points Forts
🇪🇺 Expertise Paiements Locaux
European specialization :
- iDEAL integration parfaite (Pays-Bas)
- Bancontact optimization (Belgique)
- SEPA compliance native
- Local regulations knowledge
⚡ Simplicité Intégration
Developer experience excellent :
- 15 minutes setup typical
- Documentation claire et complète
- Code examples tous languages
- No merchant account setup required
💰 Pricing Transparent
No hidden fees :
- All-inclusive pricing structure
- No setup fees ou monthly minimum
- No gateway fees additionnels
- Real-time pricing calculator
🛠️ Support Technique
Customer success européen :
- Support multilingue (FR, NL, DE, EN)
- Technical support developers
- Response time <2h business hours
- European timezone coverage
⚠️ Points Faibles
🌍 Limitation Géographique
Europe-only focus :
- Pas de coverage US/APAC
- Limited international expansion
- No emerging markets support
- Euro-centric business model
📊 Fonctionnalités Avancées
Feature set basique :
- Limited reporting vs enterprise solutions
- Basic fraud protection
- No advanced analytics
- Simple dashboard functionality
🏪 Pas de Solution POS
Online-only platform :
- No physical terminals
- No in-store payment solutions
- No omnichannel capabilities
- Pure e-commerce focus
💼 Enterprise Limitations
SME-focused platform :
- Limited customization options
- Basic API rate limits
- No dedicated infrastructure
- Limited marketplace features
🎯 Pour Qui ?
✅ Parfait Pour
- E-commerces européens méthodes locales
- PME setup rapide sans complexity
- Startups early stage validation
- Subscription businesses SEPA recurring
- Marketplaces split payments basiques
❌ Moins Adapté Pour
- Enterprises >10M€ annual complex needs
- Global businesses multi-region
- Physical stores POS requirements
- High-volume merchants custom rates
- Advanced fraud protection needs
📊 Mollie vs European Payment Solutions
| Critère | Mollie | Adyen | Stripe |
|---|---|---|---|
| European Methods | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Ease of Integration | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Pricing Simplicity | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| Enterprise Features | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| Global Reach | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
🛠️ Configuration & Intégration
Mollie JavaScript Integration
// Mollie Components (hosted fields)
const mollie = Mollie(process.env.MOLLIE_PROFILE_ID, {
locale: 'fr_FR',
testmode: process.env.NODE_ENV !== 'production'
});
class MolliePaymentService {
constructor() {
this.mollie = mollie;
this.cardHolder = null;
this.cardNumber = null;
this.expiryDate = null;
this.verificationCode = null;
}
async initializeComponents() {
try {
// Create card components
this.cardHolder = this.mollie.createComponent('cardHolder');
this.cardNumber = this.mollie.createComponent('cardNumber');
this.expiryDate = this.mollie.createComponent('expiryDate');
this.verificationCode = this.mollie.createComponent('verificationCode');
// Mount components to DOM
this.cardHolder.mount('#card-holder');
this.cardNumber.mount('#card-number');
this.expiryDate.mount('#expiry-date');
this.verificationCode.mount('#verification-code');
// Add event listeners
this.setupEventListeners();
} catch (error) {
console.error('Mollie components initialization failed:', error);
}
}
setupEventListeners() {
// Card number validation
this.cardNumber.addEventListener('change', event => {
if (event.error) {
this.showError('Card number is invalid');
} else {
this.clearError();
}
});
// Form submission
document.getElementById('payment-form').addEventListener('submit', async (event) => {
event.preventDefault();
await this.processPayment();
});
}
async processPayment() {
try {
// Get card token
const { token, error } = await this.mollie.createToken();
if (error) {
this.showError(error.message);
return;
}
// Create payment on server
const paymentResponse = await fetch('/api/mollie/create-payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
cardToken: token,
amount: {
currency: 'EUR',
value: '99.99'
},
description: 'Premium Subscription',
redirectUrl: `${window.location.origin}/payment/return`,
webhookUrl: `${window.location.origin}/api/mollie/webhook`
}),
});
const payment = await paymentResponse.json();
if (payment.success) {
// Redirect to payment page or confirmation
if (payment.checkoutUrl) {
window.location.href = payment.checkoutUrl;
} else {
window.location.href = '/payment/success';
}
} else {
this.showError(payment.error);
}
} catch (error) {
console.error('Payment processing failed:', error);
this.showError('Payment processing failed. Please try again.');
}
}
showError(message) {
document.getElementById('payment-error').textContent = message;
document.getElementById('payment-error').style.display = 'block';
}
clearError() {
document.getElementById('payment-error').style.display = 'none';
}
}
// Initialize Mollie payment service
document.addEventListener('DOMContentLoaded', () => {
const paymentService = new MolliePaymentService();
paymentService.initializeComponents();
});
Server-Side Implementation (Node.js)
// Mollie server-side integration
const { createMollieClient } = require('@mollie/api-client');
class MollieServerService {
constructor() {
this.mollieClient = createMollieClient({
apiKey: process.env.MOLLIE_API_KEY,
});
}
async createPayment(paymentData) {
try {
const payment = await this.mollieClient.payments.create({
amount: paymentData.amount,
description: paymentData.description,
redirectUrl: paymentData.redirectUrl,
webhookUrl: paymentData.webhookUrl,
method: paymentData.method || null, // null allows all methods
metadata: {
order_id: paymentData.orderId,
customer_id: paymentData.customerId
}
});
return {
id: payment.id,
status: payment.status,
checkoutUrl: payment.getCheckoutUrl(),
amount: payment.amount,
description: payment.description
};
} catch (error) {
console.error('Mollie payment creation failed:', error);
throw new Error('Failed to create payment');
}
}
async createRecurringPayment(customerId, paymentData) {
try {
// First create customer if not exists
let customer;
try {
customer = await this.mollieClient.customers.get(customerId);
} catch (error) {
customer = await this.mollieClient.customers.create({
name: paymentData.customerName,
email: paymentData.customerEmail
});
}
// Create recurring payment
const payment = await this.mollieClient.payments.create({
amount: paymentData.amount,
description: paymentData.description,
customerId: customer.id,
sequenceType: 'recurring',
webhookUrl: paymentData.webhookUrl,
metadata: {
subscription_id: paymentData.subscriptionId
}
});
return payment;
} catch (error) {
console.error('Mollie recurring payment failed:', error);
throw new Error('Failed to create recurring payment');
}
}
async handleWebhook(paymentId) {
try {
const payment = await this.mollieClient.payments.get(paymentId);
switch (payment.status) {
case 'paid':
await this.handlePaymentPaid(payment);
break;
case 'failed':
case 'canceled':
case 'expired':
await this.handlePaymentFailed(payment);
break;
case 'pending':
await this.handlePaymentPending(payment);
break;
default:
console.log(`Unhandled payment status: ${payment.status}`);
}
return payment;
} catch (error) {
console.error('Webhook processing failed:', error);
throw new Error('Failed to process webhook');
}
}
async handlePaymentPaid(payment) {
console.log(`Payment paid: ${payment.id}`);
// Update order status
const orderId = payment.metadata?.order_id;
if (orderId) {
await this.updateOrderStatus(orderId, 'paid');
await this.sendConfirmationEmail(orderId);
await this.fulfillOrder(orderId);
}
}
async handlePaymentFailed(payment) {
console.log(`Payment failed: ${payment.id}, status: ${payment.status}`);
// Update order status
const orderId = payment.metadata?.order_id;
if (orderId) {
await this.updateOrderStatus(orderId, 'failed');
await this.sendFailureEmail(orderId);
}
}
async handlePaymentPending(payment) {
console.log(`Payment pending: ${payment.id}`);
// For bank transfers, SEPA, etc.
const orderId = payment.metadata?.order_id;
if (orderId) {
await this.updateOrderStatus(orderId, 'pending');
await this.sendPendingEmail(orderId);
}
}
async getPaymentMethods(amount, locale = 'fr_FR') {
try {
const methods = await this.mollieClient.methods.list({
amount: amount,
locale: locale,
include: 'pricing'
});
return methods.map(method => ({
id: method.id,
description: method.description,
image: method.image,
pricing: method.pricing
}));
} catch (error) {
console.error('Get payment methods failed:', error);
throw new Error('Failed to retrieve payment methods');
}
}
async refundPayment(paymentId, amount = null) {
try {
const refund = await this.mollieClient.payments_refunds.create({
paymentId: paymentId,
amount: amount, // null for full refund
description: 'Customer refund request'
});
return refund;
} catch (error) {
console.error('Refund failed:', error);
throw new Error('Failed to process refund');
}
}
// Helper methods
async updateOrderStatus(orderId, status) {
// Update order in database
console.log(`Updating order ${orderId} to status: ${status}`);
}
async sendConfirmationEmail(orderId) {
// Send order confirmation email
console.log(`Sending confirmation email for order: ${orderId}`);
}
async sendFailureEmail(orderId) {
// Send payment failure email
console.log(`Sending failure email for order: ${orderId}`);
}
async sendPendingEmail(orderId) {
// Send pending payment email
console.log(`Sending pending email for order: ${orderId}`);
}
async fulfillOrder(orderId) {
// Start order fulfillment process
console.log(`Fulfilling order: ${orderId}`);
}
}
// Express.js routes
const mollieService = new MollieServerService();
app.post('/api/mollie/create-payment', async (req, res) => {
try {
const payment = await mollieService.createPayment(req.body);
res.json({ success: true, payment });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
app.post('/api/mollie/webhook', async (req, res) => {
try {
const paymentId = req.body.id;
await mollieService.handleWebhook(paymentId);
res.status(200).send('OK');
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.get('/api/mollie/payment-methods', async (req, res) => {
try {
const { amount, locale } = req.query;
const methods = await mollieService.getPaymentMethods(
{ currency: 'EUR', value: amount },
locale
);
res.json({ methods });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
🏆 Notre Verdict
Mollie excellente solution paiements pour e-commerces européens privilégiant simplicité et méthodes locales. Integration rapide, pricing transparent, support local. Parfait PME/startups expansion européenne.
Note Globale : 4.2/5 ⭐⭐⭐⭐⭐
- European Methods : 5/5
- Integration Simplicity : 5/5
- Pricing Transparency : 5/5
- Advanced Features : 2/5
- Global Reach : 2/5
🎯 Cas d’Usage Réels
💡 Exemple : E-commerce Mode Benelux
Local payments optimization :
- iDEAL : 65% transactions Pays-Bas
- Bancontact : 40% transactions Belgique
- Conversion rate : +12% avec méthodes locales
- Setup time : 15 minutes vs 2 semaines alternatives
💡 Exemple : SaaS B2B Europe
Recurring billing SEPA :
- SEPA Direct Debit : subscriptions automatiques
- Multi-country : billing unifié 27 pays EU
- Cost reduction : 0,25€ vs 1,8% carte recurring
- Compliance : PSD2 et GDPR automatic
💡 Exemple : Marketplace Artisans
Split payments européens :
- Commission split : 15% platform, 85% artisan
- Multi-methods : iDEAL, cartes, bank transfer
- Payout automation : daily transfers sellers
- Tax handling : VAT compliance multi-country
💡 Conseil OSCLOAD : Mollie incontournable e-commerces européens cherchant simplicité et méthodes locales. Setup 15 minutes, pricing transparent. Alternative Stripe si expansion globale priorité.