# Commerce Gate for Drupal — Getting Started

This guide takes your team from installing Commerce Gate to seeing what your own store's last 90
days reveal. It takes about 30 minutes. Nothing is blocked until you choose to enforce, and the
first look runs entirely on your site.

## Before you start

**Initial beta availability**

Local Store X-ray and the existing Shadow journey are available. Enforcement trials, tuned-limit
publication, billing-contact confirmation and workspace ownership claims are not yet available in
this beta.

**Get the module**

Step 1 has the installation command. [commerce.decionis.com/downloads](https://commerce.decionis.com/downloads)
lists the current release and its requirements, with its ZIP, checksum and provenance. Use the file
names shown there; do not substitute an earlier private-beta ZIP.

The official [Decionis Commerce Gate project](https://www.drupal.org/project/decionis) is listed on
Drupal.org. Its machine name is `decionis` and its package is `drupal/decionis`. Beta releases are
not covered by Drupal's security advisory policy.

**Your team will need**

- Shell access to the server, with Composer and Drush. This guide runs Drush as `vendor/bin/drush`,
  which `composer require drush/drush` adds to your project; a global `drush` works the same where
  it is installed. Every step in this guide can also be run by your hosting provider's support team.
- Drupal 10.3 or later with Drupal Commerce 3.3.13 or later for this Fincra-store guide. The
  downloads page also lists supported Drupal 11 and Commerce 2 combinations.
- PHP with the `curl` and `sodium` extensions, which most hosts include.
- An administrator account on the store.
- A scheduled cron job. Most stores already have one; Step 4 shows how to check.

We recommend trying the steps on a staging copy of your store first. Commerce Gate recognises a
copied site and keeps it in Shadow Mode, so a copy can never act for your live store.

## Step 1: Install the module and add costs

About 10 minutes. Run these from your Drupal project's root folder. If your Drupal root is called
`docroot` rather than `web`, use that name instead.

1. Install the module with Composer, which also installs its dependencies:

   ```bash
   composer require 'drupal/decionis:^0.1@beta'
   ```

   Projects built from `drupal/recommended-project` already use `https://packages.drupal.org/8`. If
   yours does not, first run
   `composer config repositories.drupal composer https://packages.drupal.org/8`.

   If upgrading from the private ZIP, first remove its repository override with
   `composer config --unset repositories.decionis`. Keep the previous ZIP and `composer.lock`
   available for recovery.

   The [downloads page](https://commerce.decionis.com/downloads) has the ZIP alternative, its
   checksum and provenance. If you use the ZIP, follow that page's checksum and Composer steps;
   copying the ZIP alone does not install its dependencies.

2. Enable it and apply its recipe:

   ```bash
   vendor/bin/drush en decionis_commerce -y
   cd web
   php core/scripts/drupal recipe modules/contrib/decionis/recipes/decionis_commerce
   cd ..
   vendor/bin/drush cr
   ```

3. Commit your updated `composer.json` and `composer.lock`, so every deployment installs the same
   version. Include `packages/` only if you used the ZIP installation steps. When upgrading, run
   `vendor/bin/drush updb -y` before rebuilding caches.

**Add your costs.** Margin checks need to know what each product costs you. The recipe adds a
**Cost** field to every product variation type. You can fill it in three ways:

- Type costs into each variation as usual.
- Import a spreadsheet on the **Import variation costs** page
  (`/admin/commerce/decionis/cost-import`). Use the columns `sku,cost`, or `sku,cost,currency`. Up
  to 5,000 rows are checked before anything is saved.
- If you already record cost in another field, choose it under **Cost base** at
  `/admin/commerce/config/decionis`.

Enter each cost in the same currency the variation sells in. Products without a cost are shown as
**not covered**; Commerce Gate never guesses a margin.

## Step 2: Run the Store X-ray

About 2 minutes. This is where you see what Commerce Gate would mean for your store, using your own
history. No account is needed, and nothing leaves your site.

1. After installing, Drupal shows a message with a link to the **Store X-ray**. You can also open
   `/admin/commerce/decionis/x-ray` directly.
2. Choose a window. We suggest 90 days; anything from 30 to 365 works.
3. Select **Run Store X-ray** and wait for the progress bar to finish.

You get one headline per currency your store sells in. It shows:

- orders sold below the suggested margin floor, and how far below
- refunds above the suggested refund limit
- promotions that stack discounts past the suggested ceiling
- refunds made outside Drupal that your payment provider reported back
- how many of your products and order lines have a cost recorded

The page is labelled **estimate on your site, using suggested limits** and **nothing left this
site**. Read it as a starting point for review, not a final account of money lost:

- It uses today's costs and the promotion settings still on your site.
- Refunds are counted per payment, so two partial refunds on one order appear as one total.

If cost coverage is low, add costs and run the X-ray again; the margin figures will sharpen.

## Step 3: Review and tune your limits

About 5 minutes. Open the settings page at `/admin/commerce/config/decionis`. For each currency you
sell in, Commerce Gate suggests four limits, drafted from your own history:

| Limit               | What it checks                                                          | How it is suggested                                                                                   |
| ------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| Refund ceiling      | A refund above this amount should have a second person look at it       | 95th percentile of your refunds                                                                       |
| Margin floor        | An order should not sell below this margin after discounts and shipping | 10th percentile of your order margins, and never above the median; 12% if there is too little history |
| Stacking ceiling    | Combined discounts should not go past this depth                        | 95th percentile of your promotion depth; 30% if there is too little history                           |
| Repeat-refund limit | How many refunds one customer can receive in 90 days before a review    | One above the 95th percentile; 3 if there is too little history                                       |

Each suggestion shows the findings behind it, for example how many of your refunds fall below the
ceiling and what the ones above it add up to. Change a value and the counts update straight away. A
suggestion needs at least 20 past examples; with fewer, the page uses a stated starting value and
tells you so.

Select **Save configuration**, then run the X-ray again to see the result with your own limits.
Your limits are saved in Drupal's configuration, so they travel with your normal deployments.

These limits always drive the X-ray and the sandbox on your site. When connected, **Save
configuration** also requests publication to your workspace. Each currency says **Published as
version …** only after the service confirms it, or **Not yet published**. A confirmed version is
used for subsequent live checks. If publication is unavailable or needs owner review, your local
limits remain saved and the page explains why. Do not assume an unpublished local limit governs
a live action.

## Step 4: Connect and see your first decisions

About 5 minutes. Connecting creates your Commerce Gate workspace in **Shadow Mode**: every decision
is recorded, and every action still runs exactly as it does today.

**Review your allowance before connecting.** Connected historical replay is metered against your
workspace's governed-action allowance, even in Shadow Mode. The local Store X-ray is free and uses
none of that allowance. Check [Build pricing](https://decionis.com/pricing#drupal-replay) before
sending a large history.

**Check cron first.** Shadow checks are sent after each page has finished loading, so they never
slow down a shopper or an admin. Some of that work runs on cron. Make sure cron runs on a schedule,
not only when someone visits the site. For example, every 15 minutes:

```bash
*/15 * * * * cd /path/to/your/project && vendor/bin/drush cron
```

**Allow the connection check.** While you connect, Commerce Gate confirms the request really comes
from your site by reading a one-time code from `/.well-known/decionis-challenge` or
`/decionis/challenge`. If the site sits behind a password prompt or a firewall, allow those two
addresses for a few minutes. They work during maintenance mode too.

**Connect.**

1. Open `/admin/commerce/config/decionis/connect`.
2. Check your business name and billing email; both are filled in for you. The site address is shown
   for confirmation.
3. Accept the terms and select **Connect to Commerce Gate**. You never paste an API key.

If the service offers an emailed connection code, enter the six-digit code from Decionis before
it expires. Billing confirmation and approval messages come from Decionis services; the optional
weekly digest below uses your site's mail setup. A delivery or connection error is shown on the
page rather than treated as a successful email.

A progress bar then checks the first part of your last 90 days against your workspace, and opens the
**Decisions** page (`/admin/commerce/decionis/decisions`). Cron fills in the rest over the next few
runs.

**On the Decisions page you will see:**

- each action's current mode
- your largest catch in each currency, explained in plain words
- a **Verify** button that checks the decision's signature, shows the key that signed it, and tells
  you whether the record is complete
- **Download Dossier**, the full signed record of that decision, which anyone can check without
  asking us

If our service cannot be reached, the page says so plainly. It never shows a check as verified when
it was not.

## Every week

Shadow Mode works quietly. These tools make sure your team sees what it finds.

- **Nudges.** If someone saves a price, promotion or refund that your policy would have refused,
  they see a short note on their next page. For example: the new price now sells below cost.
- **Weekly digest.** An optional email to the admins you choose, on the day you choose. It sums up
  what would have been held or blocked that week, with a link to act on each. Turn it on in the
  settings page; it uses your site's own email setup.
- **Protection checklist** (`/admin/commerce/decionis/checklist`). A score out of 100 across seven
  checks: connected, checks active, cost coverage, limits tuned, one action enforced, payment key
  protected, and refunds made outside Drupal visible. Each missing check links to its fix. It is a
  setup guide, not a certification.
- **Owner and agency report** (`/admin/commerce/decionis/report/xray`, or `report/shadow` for the
  90-day Shadow view). A one-page summary you can print to PDF or export as CSV for an owner,
  finance team or client. The X-ray version is marked as an estimate; the Shadow version links to
  the signed records behind it.

Schedule a 15-minute review each week: open Decisions, look at the largest catches, and decide
whether any limit needs adjusting.

## Turning on enforcement

Your workspace starts in Shadow Mode. When the service offers an enforcement trial, open
**Enforce this one**, review the effect on that action and confirm. That confirmation starts the
server's 14-day trial and enables only the action you selected; opening the page does not start it.
Repeated confirmation does not restart the trial.

Review the publication status from Step 3 before enforcing. Live checks use the confirmed
workspace policy. If an entitlement or publication service is unavailable, the page explains the
remaining step. An absent or expired enforcement entitlement keeps actions in Shadow Mode.

When enforcement is on:

- You choose it **one action at a time**, starting wherever the Decisions page shows the most value.
  Each choice shows how many actions it would have stopped and how often an approver would be asked.
- **Shoppers are never kept waiting for a person.** At checkout, Commerce Gate either lets the order
  through or, for an order your policy blocks, stops it at the review step with a neutral message,
  before any payment.
- **Refunds and price changes your policy escalates** wait on the **Pending approvals** page
  (`/admin/commerce/decionis/approvals`) until an approver confirms that exact action. It then runs
  once.
- **You can switch any action back to Shadow** in settings at any time. Your history stays.

After the 14 days, an active Build subscription keeps enforcement available. If the trial expires
without one, your actions return to Shadow automatically and your policy, history and records are
kept. A server-confirmed payment grace period shows its own deadline; its expiry also returns
actions to Shadow. Follow the billing link when it is available for your workspace, or
[contact Decionis](https://decionis.com/contact) for setup. See [pricing](https://decionis.com/pricing).

## Notes for stores using Fincra

- **Fincra's refund service covers payment discrepancies.** Fincra Support confirmed on
  4 November 2026 that an underpayment refund returns the full amount received, while an
  overpayment refund returns only the excess. Other refund requests require a separate payout
  to the customer outside Drupal. No ordinary full or partial refund API for correctly paid
  purchases has been confirmed. This module does not execute these customer payouts, and they
  are not automatically reflected as Drupal refunds. Review who can authorize payouts in the
  separate payment workflow your team uses.
- **Outside refunds are visible only when your site records them.** Where a payment provider's
  integration updates the matching Drupal payment with a refund, the Decisions page can show it
  as **made outside Drupal**, with what your policy would have decided. A separate Fincra customer
  payout does not by itself create that record.
- **Start with margin.** For your store, the most useful first actions to enforce are orders, prices
  and promotions. The Decisions page offers those first.
- **The margin check happens before payment.** Fincra takes payment on its own page, so Commerce Gate
  checks the order when the customer confirms the review step, before they are sent to Fincra.
- **Failed payments are not counted as refunds,** even though Fincra can record them that way.
- **Protecting your Fincra key (optional, later).** Your team and hosting provider can move the
  Fincra secret key to a separate service, using three small patches to Commerce Fincra. Protection
  from a compromised Drupal account requires verified root or separate-user custody and enforced
  gateway rules. A service running as Drupal's own user provides a weaker boundary. Setup starts
  in Shadow Mode, which records what the rules would do; blocking requires enabling enforcement
  after verifying the host setup.

## Help us shape it, and where to get help

During your evaluation, we would value your team's answers to these:

1. Which hurts most today: refunds, pricing mistakes, or promotions that stack too far?
2. Who issues refunds today, and in which tool?
3. On your server, can your team use `sudo`, or create a separate system user? This decides how we
   protect your Fincra key later.
4. Does anything else write to your store, such as a headless front end, an ERP sync or a support
   chatbot?
5. Did the X-ray headline match what you expected, or surprise you? How long did it take from
   install to that first headline?

**If something does not work**

- **Connecting says it could not read the one-time code.** A password prompt, firewall or server
  rule is answering instead of Drupal. Allow `/.well-known/decionis-challenge` and
  `/decionis/challenge`, then try again.
- **Connecting says it could not use your site's address.** A public site must use HTTPS on the
  standard port. If you are behind a proxy or load balancer, ask your developer to set
  `reverse_proxy` in `settings.php`.
- **Your site cannot be reached from the internet,** for example staging behind a VPN. Use the
  emailed-code option when offered. If mail delivery is unavailable, contact us to confirm service
  setup; do not expose the whole store just to connect.
- **Decisions stay "pending".** Check that cron runs on a schedule (Step 4). The status report warns
  when queued Shadow checks are more than an hour old; it does not process them just by opening
  the page.
- **Anything else.** The status report at `/admin/reports/status` shows whether every check is
  active.

Reach us at [decionis.com/contact](https://decionis.com/contact). Include your site address and, if
you can, a screenshot of the status report.
