Skip to main content
A tax engine calculates the tax lines for an order at checkout. Aikeedo ships a null engine that charges nothing, and administrators select an engine under Settings → Tax engines.

When it runs

Tax is calculated once, while the order is created, and the resulting lines are stored on the order. They’re included in getTotalPrice(), so every payment gateway charges the taxed amount without doing anything extra. If the configured engine can’t be resolved, Aikeedo falls back to the null engine, so a missing plugin never blocks checkout.

The interface

TaxResult is a list of Billing\Domain\ValueObjects\TaxLine objects:
TaxResult::getTaxTotal() sums the lines, so return several when a jurisdiction has more than one component, such as a state and a city tax.

Implementation

src/FlatTaxEngine.php

Rules to follow

  • Return an empty TaxResult() when you can’t calculate, including when an external service fails. Throwing blocks checkout entirely.
  • Work in minor units. Round once, at the end.
  • Decide your base. Tax the discounted amount, or the pre-discount amount, according to the rules you’re implementing, and document which you chose.
  • Handle a missing address. Many workspaces have none, and a plan may be sold without one.
  • Don’t call a slow API without a timeout. Order creation waits for you.

Register it

src/Plugin.php
The engine appears under Settings → Tax engines, where an administrator selects it. The selected key is stored in option.billing.tax_engine.

The settings page

The tax engines list links each engine to /admin/settings/tax-engines/{key}, so declare that route:
Set extra.default_url to the same path. For the form itself, see Admin settings pages.
Shared\Infrastructure\CountryDataProvider gives you the country list Aikeedo already uses, so your rules editor matches the rest of the admin panel.

Using an external tax service

For a service such as a rate API, keep the network call tight:
Cache rates that rarely change with the PSR-6 pool, and never let a provider outage stop a sale.

Testing

Checkout shows your tax lines, and the total includes them.
A workspace without an address still reaches checkout.
A zero or missing rate produces no tax line at all.
A discounted order taxes the amount you intended.
With the service unreachable, checkout still completes.

Official tax engines

If you don’t need a custom engine, these official ones are available on the Aikeedo Marketplace: