Get a free eCommerce advice now!

    Pick the topic
    Web developingE-shop that sellsSEO & SEMApp developingDeveloper OutsourcingOther

    Thank you for your message. It has been sent.

    Woocommerce custom payment gateway plugin – a dev guide

    February 6, 2025
    Last update: February 18, 2025
    8 min read
    87
    1
    0
    Woocommerce custom payment gateway plugin – a dev guide

    Challenge: Integrate an external payment system into WooCommerce

    Solution: Implement a custom payment gateway plugin for Woocommerce

    Welcome to the “WooCode” series, where we delve into the technicalities of WooCommerce – the popular eCommerce platform that powers a significant portion of online stores. Today, we’re focusing on a critical component that stands at the heart of every eCommerce shop: payment gateways.

    While there are numerous ready-to-use payment gateways available, the unique needs of your eCommerce business might lead you down the path of creating a custom payment gateway. This is where the real magic happens, allowing you to tailor the payment process to fit specific requirements, integrate with niche payment providers, or add custom features that standard gateways don’t offer.

    Custom Woocommerce Payment gateways

    Custom payment gateways in WooCommerce open up a world of possibilities. They offer you control over the user experience, transaction processing, and even the level of security. Whether you’re looking to integrate a local payment service, implement special transaction logic, or simply want to understand the inner workings of WooCommerce payments, developing a custom payment gateway is an invaluable skill.

    This guide is crafted for developers who are venturing into the realm of WooCommerce customization. We’ll walk through the essentials of setting up a basic payment gateway plugin, extending the WC_Payment_Gateway class, adding custom settings, and mocking function for payment process.

    screenshot of an order with custom payment method

    Crafting a custom WooCommerce payment gateway

    Let’s dive into the heart of our plugin, exploring key pieces of code that bring our custom Woocommerce payment gateway to life. If you are an owner of existing eCommerce store you may like to check our eCommerce healthcheck phases

    Plugin activation and WooCommerce dependency check

    Our journey begins with ensuring our plugin plays well with WooCommerce:

    function my_custom_gateway_activate() {
        if ( !class_exists( 'WooCommerce' ) || version_compare( get_option('woocommerce_version'), '7.0', '<' ) ) {
            deactivate_plugins(plugin_basename(__FILE__));
            wp_die(__('This plugin requires WooCommerce 7.0 or higher', 'my-plugin-textdomain'), 'Plugin dependency check', array('back_link' => true));
        }
    }
    register_activation_hook(__FILE__, 'my_custom_gateway_activate');

    This snippet checks if WooCommerce is installed and is of the required version. If these conditions aren’t met, it deactivates the plugin and notifies the user. This helps prevent potential errors on activation and ensures your plugin is used in the right environment.

    The gateway class

    Next, we have the heart of our plugin – the custom gateway class:

    class WC_My_Custom_Gateway extends WC_Payment_Gateway {
        public function __construct() {
            $this->id                 = 'my_custom_gateway';
            $this->icon               = '';
            $this->has_fields         = false; // True if you need custom credit card form
            $this->method_title       = 'My Custom Gateway';
            $this->method_description = 'Description of My Custom Gateway';
           
            $this->supports = array( 'products', 'refunds' );
           
            // Load the settings.
            $this->init_form_fields();
            $this->init_settings();
           
            // Define user set variables
            $this->title        = $this->get_option( 'title' );
            $this->description  = $this->get_option( 'description' );
           
            // Actions
            add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
        }   
    }

    Here, WC_My_Custom_Gateway extends the WC_Payment_Gateway class, tapping into WooCommerce’s payment handling system. This extension is creating a functional payment gateway, as it allows us to utilize and override methods crucial for processing payments.

    Initialization and settings

    Our Woocommerce payment gateway needs to present itself in the WooCommerce settings:

    public function init_form_fields(){
        $this->form_fields = array(
            'enabled' => array(
                'title'       => 'Enable/Disable',
                'label'       => 'Enable My Custom Gateway',
                'type'        => 'checkbox',
                'default'     => 'no'
            ),
            'title' => array(
                'title'       => 'Title',
                'type'        => 'text',
                'default'     => 'My Custom Payment Gateway',
            ),
            'api_key' => array(
                'title'       => 'API Key',
                'type'        => 'text'
            ),
            'api_secret' => array(
                'title'       => 'API Secret',
                'type'        => 'password'
            )
            // Additional fields here if necessary
        );
    }
    
    custom woocommerce payment plugin configuration

    The init_form_fields method defines the settings our gateway will offer in the WooCommerce admin, like API keys and descriptive text. These settings are essential for ensuring that store owners can easily configure our gateway to work with their specific setup.

    Processing payments

    Now, let’s look at the core of transaction handling:

    public function process_payment( $order_id ) {
        global $woocommerce;
        $order = wc_get_order( $order_id );
        $woocommerce->cart->empty_cart();

        // Get the API credentials.
        $api_key    = $this->get_option( 'api_key' );
        $api_secret = $this->get_option( 'api_secret' );

        // Simulate an API request.
        $response = $this->simulate_api_request($api_key, $api_secret, $order);

        if ($response['success']) {
            // Payment was successful.
            $order->payment_complete();

            // Save the transaction ID as order meta
            $order->set_transaction_id($response['transaction_id']);
            $order->save(); // Make sure to save the order to store meta data

            // Add order note
            $order->add_order_note( 'Payment completed using My Custom Gateway.' );

            // Return thankyou redirect
            return array(
                'result'   => 'success',
                'redirect' => $this->get_return_url( $order )
            );
        } else {
            // Payment failed.
            wc_add_notice( 'Payment error: ' . $response['message'], 'error' );
            return;
        }
    }

    process_payment is the most important function. This method is responsible for handling the payment once the customer clicks ‘Place Order’. We simulate an API request and process the response, completing the order on success, or providing an error message on failure.

    Custom Woocommerce payment plugin refund capability

    A significant feature for any payment gateway is the ability to handle refunds:

    public function process_refund( $order_id, $amount = null, $reason = '' ) {
        $order = wc_get_order( $order_id );
        $transaction_id = $order->get_transaction_id();

        if ( ! $transaction_id ) {
            return new WP_Error( 'error', __( 'Refund failed: No transaction ID', 'woocommerce' ) );
        }

        // Check if the refund amount is valid
        if ( ! is_numeric( $amount ) || $amount <= 0 ) {
            return new WP_Error( 'error', __( 'Refund failed: Invalid amount', 'woocommerce' ) );
        }

        // Prepare your API request here. This is an example.
        $api_response = $this->api_refund_request( $transaction_id, $amount );

        if ( $api_response['success'] ) {
            // Refund was successful
            return true;
        } else {
            // Refund failed
            return new WP_Error( 'error', __( 'Refund failed: ' . $api_response['message'], 'woocommerce' ) );
        }
    }

    This snippet shows how our plugin attempts to process a refund. It’s a basic implementation that can be expanded to interact with real payment provider APIs for handling refund requests.

    refund form in custom woocommerce payment gateway plugin

    Registering the gateway

    Finally, we make sure WooCommerce knows about our new gateway:

    add_filter( 'woocommerce_payment_gateways', 'add_my_custom_gateway' );
    function add_my_custom_gateway( $gateways ) {
        $gateways[] = 'WC_My_Custom_Gateway';
        return $gateways;
    }

    By adding our custom gateway class to the list of WooCommerce payment gateways, we ensure that it appears as an option for store owners, alongside other standard payment methods.

    Initializing on plugins_loaded Hook

    A critical aspect of our plugin’s behavior is how and when it initializes:

    add_action( 'plugins_loaded', 'initialize_my_payment_gateway' );

    function initialize_my_payment_gateway() {
        if ( ! class_exists( 'WC_Payment_Gateway' ) ) return;

        // Class definition here...
    }

    By hooking our class initialization to plugins_loaded, we ensure that our payment gateway class is only loaded after all plugins, including WooCommerce, have been loaded. This prevents potential errors stemming from trying to use WooCommerce functionality before it’s available.

    Mock API methods for custom Woocommerce payment plugin

    Since our example is a starting point, we simulate interactions with an external payment API. Let’s dissect these mock methods:

    Simulating the API request

    private function simulate_api_request($api_key, $api_secret, $order) {
        $order_total = $order->get_total();

        // Here you'd normally make an HTTP request to your payment provider.
        // Include the order total in the request.
        // Below is a mock response to simulate a transaction.

        // Simulating a check for the correct amount.
        if ($this->is_correct_amount($order_total)) {
            // Mock response for successful transaction.
            return array(
                'success' => true,
                'transaction_id' => '123456', // Transaction ID from the payment provider.
                'message' => 'Transaction successful'
            );
        } else {
            // Mock response for failed transaction due to incorrect amount.
            return array(
                'success' => false,
                'message' => 'Incorrect payment amount'
            );
        }
    }

    Here, simulate_api_request mimics the process of sending a payment request to an external service. In a real-world scenario, this method would make an HTTP request to a payment provider’s API. The method uses the API credentials and order information, returning a simulated response including a success status and a transaction ID.

    Validating the payment amount

    private function is_correct_amount($order_total) {
        // Here, you would compare the order total with the amount processed by the payment provider.
        // This is a mockup and always returns true for simplicity.
        return true; // In a real scenario, this should be the result of the amount check.
    }

    is_correct_amount serves as a placeholder for validating the transaction amount. In practice, this method would compare the order total from WooCommerce with the amount processed by the payment provider, ensuring transaction integrity.

    Refund functionality

    A comprehensive payment gateway is not just about processing payments but also managing refunds efficiently. Let’s take a closer look at the api_refund_request method, which is integral to our refund process:

    private function api_refund_request( $transaction_id, $amount ) {
        // This function would contain the logic to communicate with your payment API for refunds.
        // This is a mockup response.
        return array(
            'success' => true,  // or false in case of an error
            'message' => 'Refund processed successfully' // or the error message
        );
    }

    In our mock gateway, api_refund_request is a simplified version of what would be a call to your payment provider’s API to process a refund.

    Best practices and tips for creating Woocommerce custom payments plugin

    Rigorous testing: The foundation of any dependable payment gateway lies in exhaustive testing. It’s imperative to ensure your gateway’s robustness across a spectrum of scenarios, including successful transactions, failures, refunds, and various edge cases. Employ sandbox or test environments provided by payment processors for a risk-free simulation of transactions, eschewing the need for real financial exchanges.

    Security and compliance: Paramount in handling payment information is the stringent adherence to security protocols. The storage of sensitive data like credit card details on your server is strongly discouraged unless it aligns with rigorous standards such as PCI DSS. Furthermore, safeguard data transmission through secure protocols like HTTPS to prevent unauthorized access or data breaches.

    Effective error management and log keeping: Smooth gateway operation hinges on comprehensive error handling strategies and meticulous logging. Developing a system that can gracefully manage API failures or unforeseen responses is crucial. Consistent logging of transactional data and errors becomes an indispensable tool for debugging and enhancing customer support.

    User experience optimization: The crux of payment processing is an unobtrusive and intuitive user experience. Integration of the payment process within the WooCommerce checkout should be seamless, maintaining user engagement. Equally important is the provision of clear, user-friendly error messages to aid customers in navigating transactional challenges.

    Performance optimization: A paramount consideration is the efficiency of your gateway; it should not impede the checkout process. This entails optimizing code for performance and curtailing the frequency and duration of external API calls.

    Staying current: Keeping abreast of the latest updates in WooCommerce, WordPress, and your payment provider’s API is a non-negotiable aspect of gateway maintenance. Regularly updating your gateway ensures compatibility and incorporation of the latest features and technological advancements.

    Documentation and support: The success of any plugin is partly anchored in the clarity of its documentation and the responsiveness of its support. Detailed documentation covering installation, configuration, and usage, coupled with prompt and effective user support, significantly elevates user satisfaction.

    Iterative enhancement: The longevity and relevance of your payment gateway are sustained through continuous feedback-driven improvement. Regular updates and refinements, tailored to user feedback and evolving requirements, ensure your gateway remains a pertinent and efficient tool in the WooCommerce ecosystem.

    Source code

    For those interested in seeing this guide put into practice, the entire codebase discussed is accessible on GitHub : https://github.com/createit-dev/325-WooCommerce-Payment-Gateway-Example . This resource serves as a practical reference, allowing you to review, modify, and implement the concepts and techniques covered in this guide in your own WooCommerce projects.

    Conclusion

    In this guide, we’ve taken a detailed look at creating a custom WooCommerce payment gateway. Starting with the key elements of our plugin’s code, we’ve explored how to bring a payment gateway to life.

    We also tackled mock API methods, showing how a gateway interacts with payment systems in a simplified way. This is crucial for understanding the real-world workings of payment gateways and setting the stage for more complex integrations.

    The journey also covered some essential best practices and tips. We stressed the importance of thorough testing in different scenarios, keeping security at the forefront, and ensuring the gateway provides a good user experience. Staying updated with the latest WooCommerce and WordPress developments is also key to maintaining a functional and secure gateway. If you are not a tech person and need someone to provide the best solutions for your store, check out our ecommerce optimisation services!

    Support – Tips and Tricks
    All tips in one place, and the database keeps growing. Stay up to date and optimize your work!

    Contact us