The payment module handles payments for arbitrary models like orders, subscriptions, etc, commonly referred to as "payables".
Payable is an interface defined in the
vanilo/contracts package. Any Eloquent model can implement
this interface and becomes.. guess what.. payable ;)
Payable interface enforces classes to define the following information:
- payable id: order id, subscription id, etc
- payable type: the type of the payable eg
order- The two fields define the polymorphic relationship
- amount: the amount to be paid for the order, subscription, etc. Eg.
- currency: the 3 letter ISO currency code, like
- billpayer: a
Billpayerobject that contains the billing information (name, address, tax information, etc)
Payments in the system are separate entities and are stored in the
Each record/entity represents a single payment transaction. Such a transaction (not in the technical
but in its trivial meaning) can represent various forms of payments:
- A single online payment attempt - can be pending, successful, failed, etc
- A single bank transfer payment - can be pending, paid, timed out, etc
- A single cash payment
- A single refund - partial or complete refund
All payments have a status, and they have a lifecycle - from start until finish. This lifecycle can span from as low as a few seconds (eg. one click payments) until as high as months, for example B2B Wire Transfer payments.
Payments are always bound to payables - typically orders - via a polymorphic relationship, therefore you can handle payments of any eloquent model that implements the payable interface.
Payables can have one or more payments, depending on the course of the event.
amount_paid fields. The amount is the amount intended to
be paid, whereas the
amount_paid is the amount that has actually been captured. Amount paid is
typically 0 initially and in case of a successful payment it gets set to the actually settled amount.
The settled amount is the intended
amount in most of the cases, but depending on the channel, it
can happen that the actual amount differs from the intended amount. This fact can be recorded by
storing the actual amount in a separate field.
Each payment has a payment method associated that facilitates the initiation and the tracking of the payment.
PaymentMethod is an eloquent model and is defined by the users of the
shop, typically at the admin area. A payment method consists of the
combination of a payment gateway and a unique configuration.
The vast majority of online payments happens through payment gateways like PayPal, Adyen, Stripe, Klarna just to name a few. The Payment module was implemented so that new payment gateway drivers can be implemented as plugins.
The Vanilo Payment package contains a single gateway implementation and
that is the
NullGateway - to be used for offline payments.
The rest of the gateways are implemented as separate packages:
Implementing New Payment Gateways
The payment module was designed to be able to handle payment gateways implemented independently by developers.
To create a new payment gateway the following steps are required:
- Implement a
PaymentGateway(based on the interface)
- Register the new gateway with
use Vanilo\Payment\PaymentGateways; use Vanilo\Paypal\PaypalPaymentGateway; PaymentGateways::register('paypal', PaypalPaymentGateway::class);