Mollie
Accept payments with Mollie. Use this skill when the project needs to integrate Mollie for European payments, iDEAL, Bancontact, SEPA, Klarna, subscriptions, payment links, or multi-currency checkout. Covers the Mollie API, payments, subscriptions, mandates, refunds, and webhooks. Popular in Netherlands, Belgium, Germany, and across Europe.
You are a payments specialist who integrates Mollie into projects. Mollie is a
European payment service provider with strong support for local payment methods
like iDEAL, Bancontact, SOFORT, and Klarna alongside global card processing.
## Key Points
- Always fetch the payment from Mollie in webhooks — don't trust the webhook body
- Don't specify a payment method to show all available options to the customer
- Use customer objects for subscription billing
- Support iDEAL for Dutch customers, Bancontact for Belgian
- Use the Mollie dashboard for refund management when manual intervention is needed
- Test with Mollie's test mode and test amounts
- Trusting the redirect to confirm payment — always use webhooks
- Not supporting local payment methods for European customers
- Creating subscriptions without a valid mandate (first payment)
- Hardcoding payment methods instead of letting Mollie show available ones
- Not handling expired payments — users may have abandoned checkout
## Quick Example
```bash
npm install @mollie/api-client
```
```typescript
import createMollieClient from '@mollie/api-client';
const mollie = createMollieClient({
apiKey: process.env.MOLLIE_API_KEY,
});
```skilldb get payment-services-skills/mollieFull skill: 170 linesMollie Payment Integration
You are a payments specialist who integrates Mollie into projects. Mollie is a European payment service provider with strong support for local payment methods like iDEAL, Bancontact, SOFORT, and Klarna alongside global card processing.
Core Philosophy
Local payment methods win in Europe
In the Netherlands, iDEAL accounts for 60%+ of online payments. In Belgium, it's Bancontact. In Germany, SOFORT and Klarna dominate. Mollie makes these as easy to integrate as card payments — one API, all methods.
Redirect-based flow
Most Mollie payment methods use a redirect flow: create a payment, redirect to Mollie's hosted page, customer pays, Mollie redirects back. This is simpler and more universally compatible than embedded payment forms.
Webhooks confirm everything
Mollie calls your webhook URL when a payment status changes. This is the only reliable way to confirm payment — never trust the redirect alone.
Setup
Install
npm install @mollie/api-client
Initialize
import createMollieClient from '@mollie/api-client';
const mollie = createMollieClient({
apiKey: process.env.MOLLIE_API_KEY,
});
Key Techniques
Create payment (redirect flow)
const payment = await mollie.payments.create({
amount: { currency: 'EUR', value: '29.00' },
description: 'Pro Plan - Monthly',
redirectUrl: 'https://yourdomain.com/payment/return',
webhookUrl: 'https://yourdomain.com/api/webhooks/mollie',
metadata: { userId: '123', plan: 'pro' },
method: 'ideal', // Optional: pre-select method
});
// Redirect user to payment.getCheckoutUrl()
Create payment (all methods)
// Don't specify method — Mollie shows all available options
const payment = await mollie.payments.create({
amount: { currency: 'EUR', value: '29.00' },
description: 'Pro Plan',
redirectUrl: 'https://yourdomain.com/payment/return',
webhookUrl: 'https://yourdomain.com/api/webhooks/mollie',
metadata: { userId: '123' },
});
Subscriptions (recurring payments)
// Step 1: Create first payment with sequenceType 'first' to set up mandate
const firstPayment = await mollie.payments.create({
amount: { currency: 'EUR', value: '29.00' },
description: 'Pro Plan - First payment',
sequenceType: 'first',
customerId: mollieCustomerId,
redirectUrl: 'https://yourdomain.com/payment/return',
webhookUrl: 'https://yourdomain.com/api/webhooks/mollie',
});
// Step 2: After first payment succeeds, create subscription
const subscription = await mollie.customerSubscriptions.create({
customerId: mollieCustomerId,
amount: { currency: 'EUR', value: '29.00' },
interval: '1 month',
description: 'Pro Plan - Monthly',
webhookUrl: 'https://yourdomain.com/api/webhooks/mollie',
metadata: { userId: '123', plan: 'pro' },
});
// Cancel subscription
await mollie.customerSubscriptions.cancel(subscriptionId, {
customerId: mollieCustomerId,
});
Customer management
const customer = await mollie.customers.create({
name: 'Alice',
email: 'user@example.com',
metadata: { userId: '123' },
});
Refunds
const refund = await mollie.paymentRefunds.create({
paymentId: 'tr_xxx',
amount: { currency: 'EUR', value: '29.00' },
description: 'Customer request',
});
Webhook Processing
| Status | Action |
|---|---|
paid | Grant access |
failed | Notify user |
expired | Log — payment window expired |
canceled | Log — user canceled |
refunded | Adjust access |
export async function POST(req: Request) {
const form = await req.formData();
const paymentId = form.get('id') as string;
// Always fetch the full payment — don't trust webhook body
const payment = await mollie.payments.get(paymentId);
switch (payment.status) {
case 'paid':
await grantAccess(payment.metadata.userId);
break;
case 'failed':
case 'expired':
await notifyPaymentFailed(payment.metadata.userId);
break;
}
return new Response('OK');
}
Best Practices
- Always fetch the payment from Mollie in webhooks — don't trust the webhook body
- Don't specify a payment method to show all available options to the customer
- Use customer objects for subscription billing
- Support iDEAL for Dutch customers, Bancontact for Belgian
- Use the Mollie dashboard for refund management when manual intervention is needed
- Test with Mollie's test mode and test amounts
Anti-Patterns
- Trusting the redirect to confirm payment — always use webhooks
- Not supporting local payment methods for European customers
- Creating subscriptions without a valid mandate (first payment)
- Hardcoding payment methods instead of letting Mollie show available ones
- Not handling expired payments — users may have abandoned checkout
Install this skill directly: skilldb add payment-services-skills
Related Skills
Paddle
Accept payments with Paddle as merchant of record. Use this skill when the project needs to integrate Paddle for subscription billing, one-time payments, checkout overlay, tax compliance, invoicing, or global payment processing where Paddle handles tax, compliance, and payouts. Covers Paddle Billing API, checkout, subscriptions, transactions, webhooks, and Paddle.js.
Paypal
Accept payments with PayPal. Use this skill when the project needs to integrate PayPal for checkout, subscriptions, one-time payments, PayPal buttons, venmo, invoicing, payouts, or PayPal REST API. Covers the PayPal JavaScript SDK, REST API v2, Orders, Subscriptions, Webhooks, and Smart Payment Buttons.
Razorpay
Accept payments with Razorpay. Use this skill when the project needs to integrate Razorpay for payments in India and international markets, UPI, subscriptions, payment links, invoicing, route (split payments), or Razorpay Checkout. Covers the Razorpay API, Checkout.js, orders, subscriptions, webhooks, and UPI.
Square
Accept payments with Square. Use this skill when the project needs to integrate Square for online payments, in-person POS, invoicing, subscriptions, catalog management, or omnichannel commerce. Covers the Square API, Web Payments SDK, Orders, Subscriptions, Invoices, Catalog, and webhooks.
Stripe
Accept payments and manage subscriptions with Stripe. Use this skill when the project needs to integrate Stripe for one-time payments, recurring subscriptions, checkout sessions, payment intents, customer management, invoicing, webhook processing, billing portal, metered billing, or payment method management. Covers the Stripe API, Stripe.js, Checkout, Elements, Billing, and webhooks.
Adyen
Accept payments with Adyen. Use this skill when the project needs to integrate Adyen for online payments, drop-in checkout, tokenization, subscriptions, payouts, or omnichannel payment processing. Covers Adyen Checkout API, drop-in components, webhooks, and recurring payments.