In the vast e-commerce landscape, offering a seamless payment experience is a critical aspect that can make or break the user's journey.

Mollie, a prominent payment processing platform, has been trusted by many for its wide range of payment options and reliable service. For web developers working with PHP, integrating Mollie can sometimes seem challenging due to the various steps involved. This guide will take you through the entire process, ensuring your users have a hassle-free checkout experience on your website.

Disclaimer: This guide provides basic examples for integrating Mollie payments. In a real-world scenario, you'd need to add essential security layers, such as user authentication, to protect order details and other sensitive operations.

1. Displaying Available Payment Options in the Checkout Form

Mollie offers a variety of payment methods. Fetch them via the Mollie API and display them during the checkout process.

require 'vendor/autoload.php';

$mollie = new \Mollie\Api\MollieApiClient();

$methods = $mollie->methods->all();

foreach ($methods as $method) {
    echo '<input type="radio" name="method" value="' . htmlspecialchars($method->id) . '">';
    echo '<img src="' . htmlspecialchars($method->image->normal) . '" alt="' . htmlspecialchars($method->description) . '">';

2. Handling Webhooks for Payment Status Updates

On Production:

When the payment status changes, Mollie will send an HTTP request to your specified webhook endpoint.

    $payment_id = $_POST["id"];
    $payment = $mollie->payments->get($payment_id);
    $orderId = $payment->metadata->order_id;

    if ($payment->isPaid()) {
        // Handle the payment confirmation logic here.
    } elseif ($payment->isFailed()) {
        // Handle the failed payment logic here.
    } elseif ($payment->isOpen()) {
        // Handle the open payment logic here.

Locally Using Expose:

Expose (by Beyondcode) allows you to test webhooks on your local machine.

  1. Install expose: composer global require beyondcode/expose
  2. Start expose: expose share your_local_domain.test
  3. Set the exposed URL as your webhook URL in the Mollie Dashboard.

Note: The webhookUrl provided when creating the payment cannot be a local address. For local testing, use tools like

Manually Triggering Webhooks:

If you're testing locally and cannot use the standard webhook, you can manually trigger the webhook handler using the following curl command:

curl -d "id=tr_xxxxxxx" https://my-domain.local/mollie/webhook

3. Handling the Return Page

Handle the various payment statuses post-payment.

$payment_id = $_GET["id"];
$payment = $mollie->payments->get($payment_id);

if ($payment->isPaid()) {
    echo "Thank you for your payment!";
} elseif ($payment->isFailed()) {
    echo "Payment failed. Please try again.";
    // You can provide a link to restart the payment for the same order.
} elseif ($payment->isOpen()) {
    echo "Payment is still being processed. Please wait a moment.";

Restarting the Payment:

Allow users to retry failed payments seamlessly.

if ($payment->isFailed()) {
    echo "Payment failed. <a href='restart-payment.php?orderId=$orderId'>Try again</a>";

And in restart-payment.php:

$orderId = $_GET['orderId'];
// Fetch order details from your database using $orderId.

// Create a new Mollie payment using the order details.
$payment = $mollie->payments->create([
    "amount" => [
        "currency" => "EUR",
        "value" => "10.00" // Ensure this value matches the actual order amount
    "description" => "Order payment for $orderId",
    "redirectUrl" => "$orderId/",
    "webhookUrl"  => "",

// Store the new payment ID in your database associated with the order.
// This will be useful for verifying that payments belong to the correct order.
// Then, redirect the user to the payment page.

Important Notes:

  • Storing Payment IDs: Always store payment IDs in your local database. This ensures payments align with their corresponding orders and helps in tracking.

  • Creating Payments: The provided example creates a payment with a hardcoded amount and description. Ensure you're fetching the correct details from your database or checkout session for real-world scenarios.

  • Webhook URL: Remember, when setting the webhookUrl, it can't be a local address. Use tools like Expose or manually simulate webhooks with the provided curl command for local testing.

This guide offers a foundational understanding of Mollie payment integrations using PHP. As always, consider your website's unique requirements and ensure you adhere to best security practices.

Robin Dirksen
Robin Dirksen

Follow me on Twitter, there I post web-related content, tips/tricks, and other interesting things.

On my blog, you can find articles that I've found useful or wanted to share with anyone else.

If you want to know more about this article or just want to talk to me, don't hesitate to reach out.