Skip to main content

Command Palette

Search for a command to run...

How to Override Apple Pay Domain Association Controller in Magento 2

Updated
4 min read
How to Override Apple Pay Domain Association Controller in Magento 2

Introduction

If you're implementing Apple Pay on your Magento 2 store, you'll need to serve the apple-developer-merchantid-domain-association file from the .well-known directory. While Magento's Payment Services PayPal module handles this automatically, you might need to customize the content without modifying the database or vendor files.

In this comprehensive guide, I'll show you how to override the controller using Magento's dependency injection system in a clean, maintainable way.

The Challenge

The Magento Payment Services PayPal module serves the domain association file through a controller that reads content from the database configuration. However, there are several reasons you might want to override this:

  • No database modifications: Keep your configuration clean

  • Version control: Track changes in your code repository

  • Easy updates: Simple file-based management

  • No vendor edits: Survives module updates

Solution Overview

We'll create a custom module that overrides the domain association controller to serve content from a static file instead of the database.

Directory Structure

app/code/
└── Company/
    └── AppleDomain/
        ├── etc/
        │   ├── module.xml
        │   └── di.xml
        ├── Controller/
        │   └── Index/
        │       └── DomainAssociation.php
        ├── etc/
        │   └── apple-developer-merchantid-domain-association
        └── registration.php

Step-by-Step Implementation

Step 1: Create the Module Structure

First, create the necessary directories:

# Navigate to your Magento root directory
cd /path/to/your/magento

# Create the module directory structure
mkdir -p app/code/Company/AppleDomain/{etc,Controller/Index}

Step 2: Create the Registration File

Create app/code/Company/AppleDomain/registration.php:

<?php
/**
 * Copyright © Company, Inc. All rights reserved.
 */
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::MODULE,
    'Company_AppleDomain',
    __DIR__
);

Step 3: Define the Module

Create app/code/Company/AppleDomain/etc/module.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Company_AppleDomain" setup_version="1.0.0">
        <sequence>
            <module name="Magento_PaymentServicesPaypal"/>
        </sequence>
    </module>
</config>

Step 4: Configure Dependency Injection

Create app/code/Company/AppleDomain/etc/di.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference 
        for="Magento\PaymentServicesPaypal\Controller\Index\DomainAssociation" 
        type="Company\AppleDomain\Controller\Index\DomainAssociation" />
</config>

Step 5: Create the Custom Controller

Create app/code/Company/AppleDomain/Controller/Index/DomainAssociation.php:

<?php
/**
 * Copyright © Company, Inc. All rights reserved.
 */
namespace Company\AppleDomain\Controller\Index;

use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Filesystem\Driver\File;
use Magento\Framework\Exception\NotFoundException;

/**
 * Custom controller for serving Apple Pay domain association file
 */
class DomainAssociation implements HttpGetActionInterface
{
    /**
     * @var ResultFactory
     */
    private $resultFactory;

    /**
     * @var File
     */
    private $fileDriver;

    /**
     * Custom domain association file path
     */
    private const CUSTOM_DOMAIN_ASSOCIATION_FILE = 'app/code/Company/AppleDomain/etc/apple-developer-merchantid-domain-association';

    /**
     * @param ResultFactory $resultFactory
     * @param File $fileDriver
     */
    public function __construct(
        ResultFactory $resultFactory,
        File $fileDriver
    ) {
        $this->resultFactory = $resultFactory;
        $this->fileDriver = $fileDriver;
    }

    /**
     * Serve custom domain association file
     *
     * @return ResultInterface
     * @throws NotFoundException
     */
    public function execute()
    {
        $content = $this->getCustomDomainAssociationContent();

        if (empty($content)) {
            throw new NotFoundException(__('Domain association file not found.'));
        }

        $result = $this->resultFactory->create(ResultFactory::TYPE_RAW);
        $result->setHeader('Content-Type', 'text/plain');
        $result->setContents($content);

        return $result;
    }

    /**
     * Get custom domain association content from file
     *
     * @return string
     */
    private function getCustomDomainAssociationContent(): string
    {
        try {
            $filePath = BP . '/' . self::CUSTOM_DOMAIN_ASSOCIATION_FILE;

            if ($this->fileDriver->isExists($filePath)) {
                return $this->fileDriver->fileGetContents($filePath);
            }

            return '';
        } catch (\Exception $e) {
            return '';
        }
    }
}

Step 6: Add Your Domain Association File

Create app/code/Company/AppleDomain/etc/apple-developer-merchantid-domain-association and add your content:

-----BEGIN MERCHANT ID-----
Your actual Apple domain association content goes here
This is provided by Apple Merchant Center
Typically starts with -----BEGIN MERCHANT ID-----
-----END MERCHANT ID-----

Step 7: Enable and Test the Module

Run the following commands to enable your module:

# Enable the module
bin/magento module:enable Company_AppleDomain

# Run setup upgrade
bin/magento setup:upgrade

# Clean cache
bin/magento cache:clean
bin/magento cache:flush

# Deploy static content (if needed)
bin/magento setup:static-content:deploy

Step 8: Verify the Implementation

Test that your custom domain association file is being served:

# Test the endpoint
curl -s https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association

# Check HTTP status
curl -I https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association

How It Works

The Magic of Dependency Injection

When Magento receives a request to /.well-known/apple-developer-merchantid-domain-association, here's what happens:

  1. Request Routing: Magento's router identifies the request pattern

  2. Dependency Injection: Our di.xml preference tells Magento to use our custom controller instead of the original

  3. Custom Controller: Our controller reads the content from the static file

  4. Response: Returns the content with proper headers

Troubleshooting Common Issues

Module Not Working?

# Check if module is enabled
bin/magento module:status Company_AppleDomain

# Check for compilation issues
bin/magento setup:di:compile

# Verify file permissions
chmod 644 app/code/Company/AppleDomain/etc/apple-developer-merchantid-domain-association

Conclusion

Overriding the Apple Pay domain association controller in Magento 2 is a clean, maintainable solution that follows Magento best practices. By using dependency injection and custom controllers, you gain full control over the content while maintaining the integrity of your Magento installation.

This approach demonstrates the power of Magento's modular architecture and provides a pattern you can use for other controller overrides in your projects.

Happy coding!

Need help with your Magento project? Feel free to reach out in the comments below or contact me directly for consulting services.