How to Implement a Custom Gift Card System in Magento 2

Why You Need a Custom Gift Card System in Magento 2

Gift cards are a fantastic way to boost sales, encourage repeat customers, and increase brand loyalty. While Magento 2 offers a built-in gift card feature in Adobe Commerce (formerly Magento Commerce), Open Source users or those needing more flexibility might need a custom solution. Whether you want to integrate with third-party providers, add unique validation rules, or customize the checkout experience, building a custom gift card system gives you full control.

Understanding the Basics

Before diving into code, let’s outline the core components of a gift card system:

  • Gift Card Product Type – A way to create and sell gift cards like any other product.
  • Code Generation – Unique codes (random or pattern-based) for each card.
  • Balance Management – Tracking remaining amounts after purchases.
  • Checkout Integration – Applying gift cards during checkout.
  • Expiration & Validation – Setting expiry dates and validating codes.

Step 1: Creating a Custom Gift Card Product Type

First, we need a new product type. Here’s how to define it:

// app/code/Vendor/GiftCard/etc/product_types.xml  
<?xml version="1.0"?>  
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/product_types.xsd">  
    <type name="giftcard" label="Gift Card" modelInstance="Vendor\GiftCard\Model\Product\Type\GiftCard" isQty="true" sortOrder="50">  
        <customAttributes>  
            <attribute name="refundable" value="false"/>  
        </customAttributes>  
    </type>  
</config>

Next, create the model:

// app/code/Vendor/GiftCard/Model/Product/Type/GiftCard.php  
namespace Vendor\GiftCard\Model\Product\Type;  

use Magento\Catalog\Model\Product\Type\AbstractType;  

class GiftCard extends AbstractType  
{  
    const TYPE_CODE = 'giftcard';  

    public function deleteTypeSpecificData(\Magento\Catalog\Model\Product $product)  
    {  
        // Handle cleanup if needed  
    }  
}

Step 2: Generating Gift Card Codes

Gift card codes should be unique and secure. Here’s a simple generator:

// app/code/Vendor/GiftCard/Helper/CodeGenerator.php  
namespace Vendor\GiftCard\Helper;  

class CodeGenerator  
{  
    public function generate($length = 12)  
    {  
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';  
        $code = '';  
        for ($i = 0; $i < $length; $i++) {  
            $code .= $chars[rand(0, strlen($chars) - 1)];  
        }  
        return $code;  
    }  
}

Step 3: Managing Gift Card Balances

Create a database table to store gift card data:

// app/code/Vendor/GiftCard/Setup/InstallSchema.php  
namespace Vendor\GiftCard\Setup;  

use Magento\Framework\DB\Ddl\Table;  
use Magento\Framework\Setup\InstallSchemaInterface;  

class InstallSchema implements InstallSchemaInterface  
{  
    public function install(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context)  
    {  
        $table = $setup->getConnection()  
            ->newTable($setup->getTable('vendor_giftcard'))  
            ->addColumn('giftcard_id', Table::TYPE_INTEGER, null, ['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true])  
            ->addColumn('code', Table::TYPE_TEXT, 32, ['nullable' => false])  
            ->addColumn('balance', Table::TYPE_DECIMAL, '12,4', ['nullable' => false])  
            ->addColumn('expires_at', Table::TYPE_DATETIME, null, ['nullable' => true]);  
        $setup->getConnection()->createTable($table);  
    }  
}

Step 4: Applying Gift Cards at Checkout

To let customers apply gift cards, create a custom total collector:

// app/code/Vendor/GiftCard/etc/sales.xml  
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Sales:etc/sales.xsd">  
    <section name="quote">  
        <group name="totals">  
            <item name="giftcard" instance="Vendor\GiftCard\Model\Quote\GiftCard" sortOrder="500"/>  
        </group>  
    </section>  
</config>

Then, implement the logic:

// app/code/Vendor/GiftCard/Model/Quote/GiftCard.php  
namespace Vendor\GiftCard\Model\Quote;  

use Magento\Quote\Model\Quote\Address\Total\AbstractTotal;  

class GiftCard extends AbstractTotal  
{  
    public function collect(\Magento\Quote\Model\Quote $quote)  
    {  
        $giftCardCode = $quote->getGiftcardCode();  
        if ($giftCardCode) {  
            $balance = $this->getGiftCardBalance($giftCardCode);  
            $quote->setGrandTotal($quote->getGrandTotal() - $balance);  
        }  
        return $this;  
    }  
}

Step 5: Adding a Frontend Form

Let customers enter their gift card code in checkout. Add this to your checkout layout:

// app/code/Vendor/GiftCard/view/frontend/layout/checkout_index_index.xml  
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">  
    <body>  
        <referenceBlock name="checkout.root">  
            <arguments>  
                <argument name="jsLayout" xsi:type="array">  
                    <item name="components" xsi:type="array">  
                        <item name="checkout" xsi:type="array">  
                            <item name="children" xsi:type="array">  
                                <item name="steps" xsi:type="array">  
                                    <item name="children" xsi:type="array">  
                                        <item name="billing-step" xsi:type="array">  
                                            <item name="children" xsi:type="array">  
                                                <item name="payment" xsi:type="array">  
                                                    <item name="children" xsi:type="array">  
                                                        <item name="giftcard" xsi:type="array">  
                                                            <item name="component" xsi:type="string">Vendor_GiftCard/js/view/giftcard</item>  
                                                        </item>  
                                                    </item>  
                                                </item>  
                                            </item>  
                                        </item>  
                                    </item>  
                                </item>  
                            </item>  
                        </item>  
                    </item>  
                </argument>  
            </arguments>  
        </referenceBlock>  
    </body>  
</page>

Final Thoughts

A custom gift card system in Magento 2 requires careful planning but pays off with flexibility. Need a ready-made solution? Check out Magefine’s extensions for optimized gift card modules. Happy coding!