Making a payment method

Estimated reading: 5 minutes

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 the famous Omnipay package, which eases 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, let’s add the Omnipay v3 gateway to 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": "simple-icons-paypal",
    "version": "1.0.0",
    "active": 1,
    "providers": [
        "Modules\\PaypalExpress\\Providers\\Event",
        "Modules\\PaypalExpress\\Providers\\Main"
    ],
    "aliases": {},
    "files": [],
    "requires": [],
    "settings": [
        {
            "type": "text",
            "name": "name",
            "title": "general.name",
            "attributes": {
                "required": "required"
            },
            "rules": "required|string"
        },
        {
            "type": "text",
            "name": "order",
            "title": "paypal-express::general.order",
            "attributes": {},
            "rules": "nullable|integer"
        },
        {
            "type": "text",
            "name": "username",
            "title": "paypal-express::general.username",
            "attributes": {
                "required": "required"
            },
            "rules": "required"
        },
        {
            "type": "text",
            "name": "password",
            "title": "paypal-express::general.password",
            "attributes": {
                "required": "required"
            },
            "rules": "required"
        },
        {
            "type": "text",
            "name": "signature",
            "title": "paypal-express::general.signature",
            "attributes": {
                "required": "required"
            },
            "rules": "required"
        },
        {
            "type": "select",
            "name": "mode",
            "title": "paypal-express::general.mode",
            "values": {
                "live": "Live",
                "test": "Test"
            },
            "selected": "live",
            "attributes": {},
            "rules": "required"
        },
        {
            "type": "accountSelect",
            "name": "account_id",
            "attributes": {
                "required": "required"
            },
            "rules": "required"
        },
        {
            "type": "toggle",
            "name": "customer",
            "title": "paypal-express::general.customer",
            "attributes": {}
        }
    ]
}

Listener

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
{
    public function handle(Event $event): void
    {
        $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}', 'Payment@show')->name('invoices.show');
    Route::post('invoices/{invoice}/confirm', 'Payment@confirm')->name('invoices.confirm');
    Route::get('invoices/{invoice}/return', 'Payment@return')->name('invoices.return');
    Route::get('invoices/{invoice}/cancel', 'Payment@cancel')->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}', 'Payment@show')->name('invoices.show');
    Route::post('invoices/{invoice}/confirm', 'Payment@confirm')->name('invoices.confirm');
    Route::get('invoices/{invoice}/return', 'Payment@return')->name('invoices.return');
    Route::get('invoices/{invoice}/cancel', 'Payment@cancel')->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 first 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 to 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' => [

    ],
];
Share this Doc

Making a payment method

Or copy link

CONTENTS