If you’re looking for a guide on how to create your own Payment Driver, or for a more in-depth look at how they work,
head over to the extending section.
Overview
Lunar takes a driver based approach with Payments, meaning you are free to use either add ons to support the provider you wish to use, or you can create your own to meet your exact needs.Configuration
All configuration for payments is located inconfig/lunar/payments.php. Here you can specify different types of
payments and the driver each one should use.
Usage
To use a payment driver, you need to pass the type of payment you wish to use, this will then return an instance of the driver.| Field | Description |
|---|---|
| id | |
| user_id | If this is not a guest order, this will have the users id |
| channel_id | Which channel this was purchased through |
| status | A status that makes sense to you as the store owner |
| reference | Your stores own reference |
| customer_reference | If you want customers to add their own reference, it goes here. |
| sub_total | The sub total minus any discounts, excl. tax |
| discount_total | Any discount amount excl. tax |
| shipping_total | The shipping total excl. tax |
| tax_breakdown | A json field for the tax breakdown e.g. [{"name": "VAT", "total": 123, "percentage": 20}] |
| tax_total | The total amount of tax applied |
| total | The grand total with tax |
| notes | Any additional order notes |
| currency_code | The code of the currency the order was placed in |
| compare_currency_code | The code of the default currency at the time |
| exchange_rate | The exchange rate between currency_code and compare_currency_code |
| placed_at | The datetime the order was considered placed. |
| meta | Any additional meta info you wish to store |
| created_at | |
| updated_at |
Create an order
You can either create an order directly, or the recommended way is via aCart model.
CartSession you can create a order via the facade, this will then handle removing the cart from the session if you want it to.
boolean parameter to the method:
createOrder on a cart, that’s so different from just creating an order manually? Well there’s a few steps Lunar takes to make sure data stays consistent and valid, it also means that a lot of the columns on an order will automatically be populated based on the cart.
Here’s the order things happen when you call createOrder:
- We check if the Cart has been calculated and it’s totals are populated, if not we calculate
- Validation happens on the cart to ensure we have all the data we need for the order, things like billing info etc.
- Creation is about to happen, so before that we get any modifiers that have been set up and pass through the
Cartso you can make any changes beforehand. - We create the order from the
CartincludingCartLinemodels and copyingCartAddressmodels across to the new order. - We associate the newly created order to the
Cart - The new order is then run through a series of post creation modifiers so you can make any adjustments to the new order.
CartException so it depends on how much control you need.
If you also want to check before you attempt this if the cart is ready to create an order, you can call the helper method:
Modifying Orders
If you need to programmatically change the Order values or add in new behaviour, you will want to extend the Order system. You can find out more in the Extending Lunar section for Orders.Order Lines
| Field | Description |
|---|---|
| id | |
| order_id | |
| purchasable_type | Class reference for the purchasable item e.g. Lunar\Models\ProductVariant |
| purchasable_id | |
| type | Whether digital,physical etc |
| description | A description of the line item |
| option | If this was a variant, the option info is here |
| identifier | Something to identify the purchasable item, usually an sku |
| unit_price | The unit price of the line |
| unit_quantity | The line unit quantity, usually this is 1 |
| quantity | The amount of this item purchased |
| sub_total | The sub total minus any discounts, excl. tax |
| discount_total | Any discount amount excl. tax |
| tax_breakdown | A json field for the tax breakdown e.g. [{"name": "VAT", "total": 123, "percentage": 20}] |
| tax_total | The total amount of tax applied |
| total | The grand total with tax |
| notes | Any additional order notes |
| meta | Any additional meta info you wish to store |
| created_at | |
| updated_at |
Create an order line
If you are using the
createOrder method on a cart, this is all handled for you automatically.Order Addresses
An order can have many addresses, typically you would just have one for billing and one for shipping.If you are using the
createOrder method on a cart, this is all handled for you automatically.Shipping Options
A Shipping Tables addon is planned to make setting up shipping in the admin hub easy for most scenarios.
Lunar\DataTypes\ShippingOption objects.
Adding the shipping option to the cart
Once the user has selected the shipping option they want, you will need to add this to the cart so it can calculate the new totals.Transactions
| Field | Description |
|---|---|
| id | |
| success | Whether the transaction was successful |
| refund | true if this was a refund |
| driver | The payment driver used e.g. stripe |
| amount | An integer amount |
| reference | The reference returned from the payment Provider. Used to identify the transaction with them. |
| status | A string representation of the status, unlinked to Lunar e.g. settled |
| notes | Any relevant notes for the transaction |
| cart_type | e.g. visa |
| last_four | Last 4 digits of the card |
| meta | Any additional meta info you wish to store |
| created_at | |
| updated_at |
Create a transaction
Just because an order has a transaction does not mean it has been placed. Lunar determines whether an order is considered placed when the
placed_at column has a datetime, regardless if any transactions exist or not.Payment Checks
Some providers return information based on checks that can occur before payment is validated and completed. This is usually related to 3DSecure but in some cases can relate to credit checks or anything the payment provider has deemed relevant to the transaction. You can get access to these checks via thepaymentChecks() method on the Transaction.
Payments
We will be looking to add support for the most popular payment providers, so keep an eye out here as we will list them all out. In the meantime, you can absolutely still get a storefront working, at the end of the day Lunar doesn’t really mind if you what payment provider you use or plan to use. In terms of an order, all it’s worried about is whether or not theplaced_at column is populated on the orders table, the rest is completely up to you how you want to handle that. We have some helper utilities to make such things easier for you as laid out above.
And as always, if you have any questions you can reach out on our Discord! —>