Is this article helpful?
 
(optional) let us know why:

A basic payment plugin

In this tutorial, we will develop a basic plugin to integrate a payment method in our template plugin. We want to enable our customers to select the payment method Pay upon pickup in the checkout after choosing the shipping method Picked up by customer. The payment method Pay upon pickup allows the customers paying cash when picking up an item.

Step 1: Installing the template

If you haven't already set up a template in your plentymarkets system, do it before you start developing the payment plugin. In this way, you have your test environment ready and can directly check your coding output.

Step 2: Creating the plugin files

Our plugin is of the payment type and integrates with the Ceres template, i.e. our plugin consists of core features saved in the src folder, as well as the plugin.json and the config.json. This basic plugin does not require any design features. In more complex payment plugins, images and javascript files are saved in the resources folder.

PluginPayUponPickup/
    ├── src/
    │   ├── Helper/
    │   │   └── PayUponPickupHelper.php
    │   │
    │   ├── Methods/
    │   │   └── PayUponPickupPaymentMethod.php
    │   │
    │   └── Providers/
    │       └── PayUponPickupServiceProvider.php
    │
    ├── config.json // admin's plugin options
    └── plugin.json // plugin information

Step 3: Filling the source files

We start by creating the plugin.json file. We will also need a config.json, as well as a ServiceProvider, a Helper and a PaymentMethod in the src folder of our plugin. Create these files and copy the code examples.

Code for the plugin.json

PayUponPickup/plugin.json
{
    "name"              : "PayUponPickup",
    "description"       : "Pay upon pickup payment method",
    "author"            : "Your name",
    "keywords"          : ["plentymarkets", "payment method", "plugin"],
    "type"              : "payment",
    "namespace"         : "PayUponPickup",
    "require"           : [],
    "serviceProvider"   : "PayUponPickup\\Providers\\PayUponPickupServiceProvider"
}

Code for the config.json

PayUponPickup/config.json
[
    {
        "tab"     : "Settings",
        "key"     : "name",
        "label"   : "Name",
        "type"    : "text",
        "default" : "Pay upon pickup"
    },
    {
      "tab": "Settings",
      "key": "infoPage.type",
      "label": "Information page",
      "type": "dropdown",
      "possibleValues": {
        "0": "None",
        "1": "External content",
        "2": "Internal content"
      },
      "default": "0"
    },
    {
        "tab"     : "Settings",
        "key"     : "infoPage.intern",
        "label"   : "Internal information page",
        "type"    : "category_select"
    },
    {
        "tab"     : "Settings",
        "key"     : "infoPage.extern",
        "label"   : "External information page",
        "type"    : "text",
        "default" : ""
    },
    {
        "tab"             : "Settings",
        "key"             : "logo",
        "label"           : "Logo",
        "type"            : "dropdown",
        "possibleValues"  :
        {
            "0" : "None",
            "1" : "Logo URL"
        },
        "default"         : "0"
    },
    {
        "tab"     : "Settings",
        "key"     : "logo.url",
        "label"   : "Logo URL",
        "type"    : "text",
        "default" : ""
    },
    {
        "tab"     : "Settings",
        "key"     : "shippingProfileId",
        "label"   : "Shipping profile ID",
        "type"    : "text",
        "default" : ""
    }
]

Code for the ServiceProvider

PayUponPickup/src/Providers/PayUponPickupServiceProvider.php
<?php

namespace PayUponPickup\Providers;

use Plenty\Plugin\ServiceProvider;
use Plenty\Plugin\Events\Dispatcher;
use Plenty\Modules\Payment\Events\Checkout\ExecutePayment;
use Plenty\Modules\Payment\Events\Checkout\GetPaymentMethodContent;
use Plenty\Modules\Basket\Events\Basket\AfterBasketCreate;
use Plenty\Modules\Basket\Events\Basket\AfterBasketChanged;
use Plenty\Modules\Basket\Events\BasketItem\AfterBasketItemAdd;
use Plenty\Modules\Payment\Method\Contracts\PaymentMethodContainer;
use PayUponPickup\Helper\PayUponPickupHelper;
use PayUponPickup\Methods\PayUponPickupPaymentMethod;

/**
 * Class PayUponPickupServiceProvider
 * @package PayUponPickup\Providers
 */
class PayUponPickupServiceProvider extends ServiceProvider
{
    public function register()
    {

    }

    /**
     * Boot additional services for the payment method
     *
     * @param PayUponPickupHelper $paymentHelper
     * @param PaymentMethodContainer $payContainer
     * @param Dispatcher $eventDispatcher
     */
    public function boot( PayUponPickupHelper $paymentHelper,
                          PaymentMethodContainer $payContainer,
                          Dispatcher $eventDispatcher)
    {
        // Create the ID of the payment method if it doesn't exist yet
        $paymentHelper->createMopIfNotExists();

        // Register the Pay upon pickup payment method in the payment method container
        $payContainer->register('plenty_payuponpickup::PAYUPONPICKUP', PayUponPickupPaymentMethod::class,
                              [ AfterBasketChanged::class, AfterBasketItemAdd::class, AfterBasketCreate::class ]
        );

        // Listen for the event that gets the payment method content
        $eventDispatcher->listen(GetPaymentMethodContent::class,
                function(GetPaymentMethodContent $event) use( $paymentHelper)
                {
                    if($event->getMop() == $paymentHelper->getPaymentMethod())
                    {
                       $event->setValue('');
                       $event->setType('continue');
                    }
                });

        // Listen for the event that executes the payment
        $eventDispatcher->listen(ExecutePayment::class,
           function(ExecutePayment $event) use( $paymentHelper)
           {
               if($event->getMop() == $paymentHelper->getPaymentMethod())
               {
                   $event->setValue('<h1>Pay upon pickup<h1>');
                   $event->setType('htmlContent');
               }
           });
   }
}

Code for the Helper

PayUponPickup/src/Helper/PayUponPickupHelper.php
<?php

namespace PayUponPickup\Helper;

use Plenty\Modules\Payment\Method\Contracts\PaymentMethodRepositoryContract;
use Plenty\Modules\Payment\Method\Models\PaymentMethod;

/**
 * Class PayUponPickupHelper
 *
 * @package PayUponPickup\Helper
 */
class PayUponPickupHelper
{
    /**
     * @var PaymentMethodRepositoryContract $paymentMethodRepository
     */
    private $paymentMethodRepository;

    /**
     * PayUponPickupHelper constructor.
     *
     * @param PaymentMethodRepositoryContract $paymentMethodRepository
     */
    public function __construct(PaymentMethodRepositoryContract $paymentMethodRepository)
    {
        $this->paymentMethodRepository = $paymentMethodRepository;
    }

    /**
     * Create the ID of the payment method if it doesn't exist yet
     */
    public function createMopIfNotExists()
    {
        // Check whether the ID of the Pay upon pickup payment method has been created
        if($this->getPaymentMethod() == 'no_paymentmethod_found')
        {
            $paymentMethodData = array( 'pluginKey' => 'plenty_payuponpickup',
                                        'paymentKey' => 'PAYUPONPICKUP',
                                        'name' => 'Pay upon pickup');

            $this->paymentMethodRepository->createPaymentMethod($paymentMethodData);
        }
    }

    /**
     * Load the ID of the payment method for the given plugin key
     * Return the ID for the payment method
     *
     * @return string|int
     */
    public function getPaymentMethod()
    {
        $paymentMethods = $this->paymentMethodRepository->allForPlugin('plenty_payuponpickup');

        if( !is_null($paymentMethods) )
        {
            foreach($paymentMethods as $paymentMethod)
            {
                if($paymentMethod->paymentKey == 'PAYUPONPICKUP')
                {
                    return $paymentMethod->id;
                }
            }
        }

        return 'no_paymentmethod_found';
    }
}

Code for the PaymentMethod

PayUponPickup/src/Methods/PayUponPickupPaymentMethod.php
<?php

namespace PayUponPickup\Methods;

use Plenty\Plugin\ConfigRepository;
use Plenty\Modules\Payment\Method\Contracts\PaymentMethodService;
use Plenty\Modules\Basket\Contracts\BasketRepositoryContract;
use Plenty\Modules\Basket\Models\Basket;

/**
 * Class PayUponPickupPaymentMethod
 * @package PayUponPickup\Methods
 */
class PayUponPickupPaymentMethod extends PaymentMethodService
{
    /**
     * Check the configuration if the payment method is active
     * Return true if the payment method is active, else return false
     *
     * @param ConfigRepository $configRepository
     * @param BasketRepositoryContract $basketRepositoryContract
     * @return bool
     */
    public function isActive( ConfigRepository $configRepository,
                              BasketRepositoryContract $basketRepositoryContract):bool
    {
        /** @var bool $active */
        $active = true;

        /** @var Basket $basket */
        $basket = $basketRepositoryContract->load();

        /**
         * Check the shipping profile ID. The ID can be entered in the config.json.
         */
        if( $configRepository->get('PayUponPickup.shippingProfileId') != $basket->shippingProfileId)
        {
            $active = false;
        }

        return $active;
    }

    /**
     * Get the name of the payment method. The name can be entered in the config.json.
     *
     * @param ConfigRepository $configRepository
     * @return string
     */
    public function getName( ConfigRepository $configRepository ):string
    {
        $name = $configRepository->get('PayUponPickup.name');

        if(!strlen($name))
        {
            $name = 'Pay upon pickup';
        }

        return $name;

    }

    /**
     * Get the path of the icon. The URL can be entered in the config.json.
     *
     * @param ConfigRepository $configRepository
     * @return string
     */
    public function getIcon( ConfigRepository $configRepository ):string
    {
        if($configRepository->get('PayUponPickup.logo') == 1)
        {
            return $configRepository->get('PayUponPickup.logo.url');
        }
        return '';
    }

    /**
     * Get the description of the payment method. The description can be entered in the config.json.
     *
     * @param ConfigRepository $configRepository
     * @return string
     */
    public function getDescription( ConfigRepository $configRepository ):string
    {
        if($configRepository->get('PayUponPickup.infoPage.type') == 1)
        {
            return $configRepository->get('PayUponPickup.infoPage.intern');
        }
        elseif ($configRepository->get('PayUponPickup.infoPage.type') == 2)
        {
            return $configRepository->get('PayUponPickup.infoPage.extern');
        }
        else
        {
          return '';
        }
    }
}

Step 4: Setting up a shipping profile

We have to get a few things done in the plentymarkets back end, before our customers can actively use the payment method. In the PayUponPickupPaymentMethod.php file, we included checking the shipping profile ID. For this purpose, we have to set up a suitable shipping profile.

Creating the shipping provider

  1. Go to System » Orders » Shipping » Settings » Tab: Shipping service provider.
  2. Click on New.
    → A new line will be added at the bottom of the overview.
  3. Enter the name.
    → Enter both front end and back end names, e.g. Picked up by customer.
  4. Select Selbstabholer (Picked up by customer) from the Shipping service provider drop-down menu.
  5. Save the settings.

Creating the shipping profile

  1. Go to System » Orders » Shipping » Settings » Tab: Shipping profiles.
  2. Click on New.
  3. Select the shipping service provider that you have just created from the drop-down menu.
  4. Enter the name.
    → Enter both front end and back end names, e.g. Pickup.
  5. Activate the client (store).
  6. Activate the order referrer Client (store).
  7. Save the settings.
    → The shipping profile is created. The ID is shown in the overview.

Pocketing the profits

After creating the plugin and setting up everything in the plentymarkets back end, we have to add our new plugin to the plentymarkets inbox. Then, we enter the shipping profile ID in the plugin config.

  1. Go to Plugins » Plugin overview.
  2. Select your plugin set.
  3. In the list of plugins, click on PayUponPickup.
    → The plugin config file will open.
  4. Enter the shipping profile ID.
  5. Save the settings.

And finally, we deploy the plugin in a plugin set. The payment method Pay upon pickup is displayed in the checkout. Our customers can now select this payment method for the Picked up by customer shipping method and pay in cash when picking up an item.