Making a payment method

Akaunting is not used only for accounting management but also for getting invoices paid. That said, Akaunting is being used in 150+ countries that accept different payment methods. For example, while in Brazil PagSeguro is used to get paid, eWay is the leader of online payments in Australia. Therefore, there is a separate category for payment methods in Akaunting App Store.

Akaunting ships with famous Omnipay package which ease the way to accept payments. Furthermore, Akaunting has a specific trait for Omnipay which sets the invoice details and makes the proper redirects.

First of all, create and install a module.

Composer

First of all, let’s add the Omnipay v3 gateway into the composer file.

{
    "require": {
        "omnipay/paypal": "3.0.*"
    },
    "replace": {
        "guzzlehttp/guzzle": "*",
        "guzzlehttp/psr7": "*",
        "laravel/framework": "*",
        "omnipay/common": "*",
        "symfony/http-foundation": "*"
    },
    "scripts": {
        "test": [
            "composer install --prefer-dist --no-interaction --no-scripts --no-suggest --no-progress --no-ansi"
        ]
    }
}

Settings

The module should offer some settings such as API Key, Secret, etc. to the user/company that will get the payments. As described in the Settings documentation, you can do it 2 ways but generally the module.json file is more than enough for payment methods.

{
    "alias": "paypal-express",
    "icon": "fab fa-paypal",
    "version": "1.0.0",
    "active": 1,
    "providers": [
        "Modules\\PaypalExpress\\Providers\\Event",
        "Modules\\PaypalExpress\\Providers\\Main"
    ],
    "aliases": {},
    "files": [],
    "requires": [],
    "settings": [
        {
            "type": "textGroup",
            "name": "name",
            "title": "general.name",
            "icon": "fa fa-font",
            "attributes": {
                "required": "required"
            },
            "rules": "required|string"
        },
        {
            "type": "textGroup",
            "name": "order",
            "title": "paypal-express::general.order",
            "icon": "sort",
            "attributes": {},
            "rules": "nullable|integer"
        },
        {
            "type": "textGroup",
            "name": "username",
            "title": "paypal-express::general.username",
            "icon": "user",
            "attributes": {
                "required": "required"
            },
            "rules": "required"
        },
        {
            "type": "textGroup",
            "name": "password",
            "title": "paypal-express::general.password",
            "icon": "key",
            "attributes": {
                "required": "required"
            },
            "rules": "required"
        },
        {
            "type": "textGroup",
            "name": "signature",
            "title": "paypal-express::general.signature",
            "icon": "code",
            "attributes": {
                "required": "required"
            },
            "rules": "required"
        },
        {
            "type": "selectGroup",
            "name": "mode",
            "title": "paypal-express::general.mode",
            "icon": "plane",
            "values": {
                "live": "Live",
                "test": "Test"
            },
            "selected": "live",
            "attributes": {},
            "rules": "required"
        },
        {
            "type": "accountSelectGroup",
            "name": "account_id",
            "attributes": {
                "required": "required"
            },
            "rules": "required"
        },
        {
            "type": "radioGroup",
            "name": "customer",
            "title": "paypal-express::general.customer",
            "enable": "general.yes",
            "disable": "general.no",
            "attributes": {}
        }
    ]
}

Listener

In order to get shown in the payment method list when the customer views the invoice in the client portal or via a signed link, you have to register your module as shown below:

<?php

namespace Modules\PaypalExpress\Listeners;

use App\Events\Module\PaymentMethodShowing as Event;

class ShowAsPaymentMethod
{
    /**
     * Handle the event.
     *
     * @param  Event $event
     * @return void
     */
    public function handle(Event $event)
    {
        $method = setting('paypal-express');

        $method['code'] = 'paypal-express';

        $event->modules->payment_methods[] = $method;
    }
}

Routes

Getting shown in the payment methods list is the first step, the next one is to have the routes set up. The module should have at least 2 route files: portal.php for customers logged in and signed.php for guests with a shared link. Here you can see the examples:

portal.php

<?php

use Illuminate\Support\Facades\Route;

/**
 * 'portal' middleware and 'portal/paypal-express' prefix applied to all routes (including names)
 *
 * @see \App\Providers\Route::register
 */

Route::portal('paypal-express', function () {
    Route::get('invoices/{invoice}', '[email protected]')->name('invoices.show');
    Route::post('invoices/{invoice}/confirm', '[email protected]')->name('invoices.confirm');
    Route::get('invoices/{invoice}/return', '[email protected]')->name('invoices.return');
    Route::get('invoices/{invoice}/cancel', '[email protected]')->name('invoices.cancel');
});

signed.php

<?php

use Illuminate\Support\Facades\Route;

/**
 * 'signed' middleware and 'signed/paypal-express' prefix applied to all routes (including names)
 *
 * @see \App\Providers\Route::register
 */

Route::signed('paypal-express', function () {
    Route::get('invoices/{invoice}', '[email protected]')->name('invoices.show');
    Route::post('invoices/{invoice}/confirm', '[email protected]')->name('invoices.confirm');
    Route::get('invoices/{invoice}/return', '[email protected]')->name('invoices.return');
    Route::get('invoices/{invoice}/cancel', '[email protected]')->name('invoices.cancel');
});

Controller

Now that you’ve set up everything, it’s time to create the controller:

<?php

namespace Modules\PaypalExpress\Http\Controllers;

use App\Abstracts\Http\PaymentController;
use App\Models\Sale\Invoice;
use App\Traits\Omnipay;
use Illuminate\Http\Request;

class Payment extends PaymentController
{
    use Omnipay;

    public $alias = 'paypal-express';

    public $type = 'redirect';

    public function confirm(Invoice $invoice, Request $request)
    {
        $this->create('PayPal_Express');

        return $this->purchase($invoice, $request, [
            'username' => $this->setting['username'],
            'password' => $this->setting['password'],
            'signature' => $this->setting['signature'],
            'testMode' => ($this->setting['mode'] == 'test'),
        ]);
    }

    public function return(Invoice $invoice, Request $request)
    {
        $this->create('PayPal_Express');

        return $this->completePurchase($invoice, $request, [
            'username' => $this->setting['username'],
            'password' => $this->setting['password'],
            'signature' => $this->setting['signature'],
            'testMode' => ($this->setting['mode'] == 'test'),
        ]);
    }
}

As you can see from the example, it doesn’t extend the general Controller but PaymentController abstract of Akaunting. The confirm and return functions will firstly create an instance of Ompnipay and then redirect the customer.

As it’s also mentioned in the documentation of Omnipay, there are 2 types of payment methods: hosted which embeds the credit card form and redirect which redirects the customer to the payment method site to make the payment and redirects them back to Akaunting.

The view/blade part of both credit card and redirect is built into Akaunting so you don’t have take any further action, unless you don’t want to override them.

Language

Finally, the language file in Resources/lang/en-GB/general.php should be something like this:

<?php

return [

    'name'              => 'PayPal Express',
    'description'       => 'Express Checkout for faster PayPal transactions',

    'customer'          => 'Show to Customer',
    'username'          => 'Username',
    'password'          => 'Password',
    'signature'         => 'Signature',
    'mode'              => 'Mode',
    'order'             => 'Order',

    'error' => [

    ],
];
Scroll to top