Xgenious/ docs

Overview

Payment gateways are implemented as plugins that hook into two core filters: payment.charge (initiate) and payment.complete (verify and complete).

Architecture

Core Checkout --payment.charge--> Gateway Plugin (redirects to provider)
                                        |
                           Provider redirects back / sends IPN webhook
                                        |
                                        v
Core Completion <--payment.complete-- Gateway Plugin (verifies & delegates)

Key principle: Core never references gateway plugins by name. Plugins self-register via the registry and hook into filters.

Directory Structure

plugins/my-payment-gateway/
├── plugin.json
├── README.md
├── config/
│   └── my-payment-gateway.php
├── routes/
│   ├── web.php                    # Auth-protected (checkout, admin)
│   └── api.php                    # Public (IPN/callback — no CSRF)
├── src/
│   ├── MyPaymentGatewayPlugin.php # Entry class
│   ├── MyGateway.php              # Gateway logic
│   └── Http/
│       ├── Controllers/
│       │   ├── MyCheckoutController.php   # Optional: hosted checkout page
│       │   ├── MyIpnController.php        # Webhook receiver
│       │   └── MyAdminController.php      # Admin settings
│       └── ...
├── views/
│   ├── pay.blade.php              # Optional: checkout view
│   └── admin/
│       └── settings.blade.php     # Admin settings view
└── database/
    └── migrations/                # Optional: custom tables

Step 1: plugin.json

{
    "name": "My Payment Gateway",
    "slug": "my-payment-gateway",
    "version": "1.0.0",
    "entry": {
        "file": "src/MyPaymentGatewayPlugin.php",
        "class": "MyPaymentGateway\\MyPaymentGatewayPlugin"
    },
    "autoload": {
        "psr-4": {
            "MyPaymentGateway\\": "src/"
        }
    },
    "requires": {
        "framework": ">=1.0",
        "php": ">=8.3"
    },
    "provides": ["payment.charge"],
    "capabilities": ["outbound-https"],
    "xilancerMetaData": {
        "plugin_type": "external"
    }
}

Last updated: September 2026

Still stuck?
Our support team is ready to help you get set up.
Get support