Developer Documentation – Custom Payment Gateway Implementation

⌘K
  1. Home
  2. Docs
  3. MultiSaas – Multi-T...
  4. Developer Documentation
  5. Developer Documentation – Custom Payment Gateway Implementation

Developer Documentation – Custom Payment Gateway Implementation

Here is a Sample Plugin with a Custom payment gateway implemented, you can explore it to understand how it actually work

https://github.com/xgenious-official/nazmart-plugin-sample

First, create a custom module using the artisan command,

php artisan module:make ModuleName

Put this in your custom payment module module.json file

"paymentGateway": {
            "name": "Your Payment Gateway Name",
            "slug": "payment_gateway_slug",
            "tenant": false,
            "chargeCustomerMethodNameSpace": "Modules\\TestManage\\Http\\Controllers\\TestManageController",
            "chargeCustomerMethodName": "paymentGateway",
            "test_mode" : false,
            "status" : true,
            "extraInfoMarkupBlade" : "payment_blade",
            "logo_file" : "payment-logo.png"
        }

Put your payment gateway logo_file in Module > assets > payment-gateway-image and place the logo file name in the module.json

Create extraInfoMarkupBlade blade file in Module > Resource > views > payment-gateway-view and place the blade file name in the module.json, if any extra information is needed while checkout


extraInfoMarkupBlade the file looks like this,

<div class="form-group single-input mt-4">
    <label for="ali">AliPay ID Here</label>
    <input type="text" name="ali_id"
           class="form-control form--control mt-2"
           placeholder="Ali ID" id="ali">

    <label for="ali1">Ali Express Code Here</label>
    <input type="text" name="ali_express_code"
           class="form-control form--control mt-2"
           placeholder="Ali Express Code" id="ali1">

    <label for="ali2">Ali Transaction Attachment</label>
    <input type="file" name="ali_attachment"
           class="form-control form--control mt-2"
           placeholder="Transaction ID" accept="image/*" id="ali2">
</div>

Create a Controller or PHP class and include its namespace in the module.json file

Create a charge customer method inside the class and include the method name in the JSON file like this,

In the chargeCustomerMethod take an array-type parameter and you will find the payment details in it to continue your logic.

The chargeCustomerMethod will look like this,

public function customChargeCustomer($args){
   // $args has the payment details along with request information
   // Your code
}

You can update your current payment details from the database like this,

// For Landlord
PaymentLogs::find($args['payment_details']['id'])->update([
            'transaction_id' => $args['request']['ali_id'] ?? '',
            'attachments' => $args['request']['ali_express_code'] ?? '',
            'status' => 'complete',
            'payment_status' => 'complete',
            'updated_at' => Carbon::now()
]);

// For Tenant
ProductOrder::find($args['order_id'])->update([
              'payment_status' => 'success'
]);

To create tenant use this functions according to your logic,

public function tenant_create_event_with_credential_mail($order_id)
    {
        $log = PaymentLogs::findOrFail($order_id);
        if (empty($log))
        {
            abort(462,__('Does not exist, Tenant does not exists'));
        }

        $user = User::where('id', $log->user_id)->first();
        $tenant = Tenant::find($log->tenant_id);

        if (!empty($log) && $log->payment_status == 'complete' && is_null($tenant)) {
            event(new TenantRegisterEvent($user, $log->tenant_id, get_static_option('default_theme')));
            try {
                $raw_pass = get_static_option_central('tenant_admin_default_password') ??'12345678';
                $credential_password = $raw_pass;
                $credential_email = $user->email;
                $credential_username = get_static_option_central('tenant_admin_default_username') ?? 'super_admin';

                Mail::to($credential_email)->send(new TenantCredentialMail($credential_username, $credential_password));

            } catch (\Exception $e) {

            }

        } else if (!empty($log) && $log->payment_status == 'complete' && !is_null($tenant) && $log->is_renew == 0) {
            try {
                $raw_pass = get_static_option_central('tenant_admin_default_password') ??'12345678';
                $credential_password = $raw_pass;
                $credential_email = $user->email;
                $credential_username = get_static_option_central('tenant_admin_default_username') ?? 'super_admin';

                Mail::to($credential_email)->send(new TenantCredentialMail($credential_username, $credential_password));

            } catch (\Exception $exception) {
                $message = $exception->getMessage();
                if(str_contains($message,'Access denied')){
                    abort(463,__('Database created failed, Make sure your database user has permission to create database'));
                }
            }
        }

        return true;
    }

public function updateTenant(){
  \DB::table('tenants')->where('id', $tenant->id)->update([
            'renew_status' => $renew_status = is_null($tenant->renew_status) ? 0 : $tenant->renew_status+1,
            'is_renew' => $renew_status == 0 ? 0 : 1,
            'start_date' => $payment_log->start_date,
            'expire_date' => get_plan_left_days($payment_log->package_id, $tenant->expire_date)
        ]);
}

Before proceeding to the success page wrap the order-id,

$id = random_int(100000,999999).$charge_data->id.random_int(100000,999999);
        return redirect()->route('landlord.frontend.order.payment.success', $id);

Payment gateway sidebar menu for admin

Add the below code inside the paymentGateway. The admin_settings accepts an array, so you can add multiple menu items inside the menu_item. Examples are the following,

"admin_settings": {
                "menu_item": [
                    {
                        "id" : "test-settings-menu-submenu",
                        "label": "Test Payment Menu",
                        "route": "tenant.admin.activity.log",
                        "tenantRoute": "tenant.admin.newsletter",
                        "permissions": ["general-settings-page-settings"]
                    }
                ]
            }

This menu can be used for both landlord and tenant. The route for landlord and tenant is separate. route for the landlord and tenantRoute for the tenant. The menu can be enabled or disabled for the landlord or tenant by changing these two attribute show_admin_landlord and show_admin_tenant

The full file for the payment gateway inside the module.json will look like something this,

{
    "name": "TestManage",
    "alias": "testmanage",
    "description": "",
    "keywords": [],
    "priority": 0,
    "providers": [
        "Modules\\TestManage\\Providers\\TestManageServiceProvider"
    ],
    "aliases": {},
    "files": [],
    "requires": [],
    "nazmartMetaData": {
        "style": [],
        "admin_settings": {
            "menu_item": [
                {
                    "id" : "test-settings-menu",
                    "label": "Test Menu",
                    "route": "tenant.admin.newsletter",
                    "tenantRoute": "tenant.admin.newsletter",
                    "parent": null,
                    "permissions": ["general-settings-page-settings", "general-settings-site-identity"],
                    "icon": "mdi mdi-settings"
                },
                {
                    "id" : "test-settings-menu-submenu",
                    "label": "Test Sub Menu",
                    "route": "tenant.admin.activity.log",
                    "parent": "test-settings-menu",
                    "permissions": ["general-settings-page-settings"]
                }
            ]
        },
        "header_hook": [],
        "footer_hook": [],
        "pageBuilderAddon": [
            "Modules\\TestManage\\Http\\PageBuilder\\Addons\\TestAddon"
        ],
        "widgetBuilderAddon": [
            "Modules\\TestManage\\Http\\WidgetBuilder\\Widgets\\FooterAbout"
        ],
        "paymentGateway": {
            "name": "AliPay",
            "slug": "alipay",
            "tenant": true,
            "show_admin_landlord": true,
            "show_admin_tenant": true,
            "chargeCustomerMethodNameSpace": "Modules\\TestManage\\Http\\Controllers\\TestManageController",
            "chargeCustomerMethodName": "paymentGateway",
            "test_mode" : false,
            "status" : true,
            "extraInfoMarkupBlade" : "ali_pay",
            "logo_file" : "ali-pay.png",
            "admin_settings": {
                "menu_item": [
                    {
                        "id" : "test-settings-menu-submenu",
                        "label": "Test Payment Menu",
                        "route": "tenant.admin.activity.log",
                        "tenantRoute": "tenant.admin.newsletter",
                        "permissions": ["general-settings-page-settings"]
                    }
                ]
            }
        }
    }
}
Was this article helpful to you? No Yes

How can we help?