# Testing and production

> By default Merx is in *testing* mode.

Merx has one switch for the whole shop. While [`production`](https://merx2.wagnerwagner.de/reference/options/config-options/production.md) is `false`, every payment runs against the test environment of your payment provider and no money moves. Setting it to `true` is what turns the shop into a real one.

```php title="/site/config/config.php"
<?php

return [
  'wagnerwagner.merx.production' => true,
];
```

## What the switch changes

`production` swaps the test keys for the live ones. Nothing else moves — blueprints, [pricing rules](https://merx2.wagnerwagner.de/guide/configuration/currencies.md), [tax rules](https://merx2.wagnerwagner.de/guide/configuration/taxes.md), hooks and templates behave the same either way, so a shop that works in testing works in production.

> [!IMPORTANT]
> One key is the exception. Merx picks the Stripe *secret* key itself, but the *publishable* key goes into your own checkout template, where Merx cannot switch it for you. The [Stripe Elements guide](https://merx2.wagnerwagner.de/guide/payment-gateways/stripe-elements.md) reads it from the same option — if you hard-coded the test key instead, the live shop will keep talking to Stripe’s test mode.

## Test before you switch

A test payment goes through the same gateway, the same hooks and the same [order page](https://merx2.wagnerwagner.de/guide/getting-started/displaying-order.md) as a real one. It’s worth running one per gateway you offer.

- **Stripe** takes its [test cards](https://docs.stripe.com/testing) — `4242 4242 4242 4242` with any future expiry succeeds, and there are numbers for declines and for authentication prompts.
- **PayPal** needs a sandbox account from the [developer dashboard](https://developer.paypal.com/dashboard/applications/sandbox) to pay with. See the [PayPal guide](https://merx2.wagnerwagner.de/guide/payment-gateways/paypal.md).
- **Invoice** involves no provider at all, so it behaves identically in both modes.

Check that the order page is written, the order number is what you expect, and your confirmation mail arrives.

## Going live

`production` is the last thing you change, not the first. Before you flip it:

1. Put the live keys on the server, in `/site/config/env.php` — the live Stripe secret and publishable key, the live PayPal client ID and secret. See [Stripe/PayPal secrets](https://merx2.wagnerwagner.de/guide/configuration/stripe-paypal-secrets.md).
2. Set `production` to `true` **on the server only**, so your local install keeps using the test keys.
3. Create the Stripe webhook again on the live side and replace [`stripe.webhook_signing_secret`](https://merx2.wagnerwagner.de/reference/options/config-options/stripe-webhook-signing-secret.md) with the live one. There’s only one of those options, and a test secret rejects every live webhook. See [Stripe webhooks](https://merx2.wagnerwagner.de/guide/configuration/stripe-webhooks.md).
4. Set your [`license`](https://merx2.wagnerwagner.de/reference/options/config-options/license.md) key.
5. Make sure order pages are not reachable by search engines or listed anywhere. See [Security](https://merx2.wagnerwagner.de/guide/security.md).

Then buy something from your own shop with a real card, check that it arrives in the Stripe or PayPal dashboard, and refund it.

## License

Merx is commercial software, and a shop in production needs a license. Set it with the [`license`](https://merx2.wagnerwagner.de/reference/options/config-options/license.md) option and the Panel will show it under the plugin.

```php title="/site/config/env.php"
<?php

return [
  'wagnerwagner.merx.license' => 'MERX2-XXXXXXX-XXXXXXX',
];
```

You can [buy a license](https://merx2.wagnerwagner.de/buy) for each domain you run Merx on.
