# taler-merchant (container `taler-hacktivism`)

Image: `localhost/taler-hacktivism-live:landing`  
Publish: **9010/tcp only**  
Labels: `org.hacktivism.service=taler-merchant`, `host_port=9010`, `site=taler.hacktivism.ch`

## Config layout (same pattern as exchange)

| Path in container | Mirror in this dir |
|-------------------|--------------------|
| `taler-merchant.conf` | includes documented in `taler-merchant.conf.includes.txt` |
| `overrides.conf` | tooling — do not edit (not mirrored) |
| **`merchant-overrides.conf`** | **`merchant-overrides.conf`** |
| `conf.d/merchant.conf` | `conf.d-merchant.conf` |
| nginx `sites-available/taler-merchant` | `nginx-taler-merchant.conf` |

Secrets (`secrets/*.secret.conf`, SMTP password) are **not** mirrored.

## Manual start (merchant model)

| Path | User | Role |
|------|------|------|
| `/root/start_base_services_for_taler.sh` | **root** | logs, SMS env, postgres → shell as `taler-merchant-httpd` |
| `/usr/local/bin/start_merchant.sh` | **taler-merchant-httpd** | start / `--restart` httpd + helpers |
| `/usr/local/bin/check_merchant-health.sh` | any | health (socket + nginx) |

Also under `/usr/local/bin/`: email/SMS helpers, `stats--merchant-payments.sh`.  
Certbot loop: `/root/scripts/certbot_renew.sh` (started from base script).

Git scripts: `scripts/taler-merchant/`.

## Site settings (overrides)

- **Default currency:** CHF (`[taler]` / `[merchant]`)
- **Exchanges (multi-currency):**
  - CHF → `exchange.taler-ops.ch` (package default `[merchant-exchange-chf]` in `tops.conf` — do not redeclare as `merchant-exchange-tops`)
  - GOA → `exchange.hacktivism.ch` (`[merchant-exchange-goa]` in `merchant-overrides.conf`)
- **SERVE:** unix socket → nginx :9010 SSL → Caddy :9001
- **Self-provisioning:** YES; **no mandatory TAN** (SMS off)
- **Terms:** `TERMS_ETAG = merchant-tos-dual-v0` — short dual-currency notice (GOA explorational + CHF real). Sources in `terms-src/`; install with `scripts/taler-merchant/install_dual_terms.sh` inside the container, then restart `taler-merchant-httpd`. Public: `https://taler.hacktivism.ch/terms`

Wire status is **per account × exchange**: an `x-taler-bank` GOA payto shows `ready` for hacktivism and `unsupported` for taler-ops (expected). CHF/IBAN accounts use taler-ops.

### Container → public exchange (pasta)

Inside pasta, `exchange.hacktivism.ch` must not resolve to **127.0.0.1** (merchant nginx self-signed). Pin public A in container `/etc/hosts`:

```
212.51.151.254 exchange.hacktivism.ch bank.hacktivism.ch taler.hacktivism.ch
```

After conf/hosts changes: `taler-merchant-exchangekeyupdate -t` and `taler-merchant-kyccheck -t`.## Ports

| Port | Role |
|------|------|
| 9010 | nginx TLS in container (podman) |
| unix sock | `taler-merchant-httpd` |

## Merchant portal (SPA `/webui/`) — instance IDs **lowercase only**

The merchant **webui** (and private API paths under `/instances/{id}/…`) must use
**only lowercase** instance ids (`a-z`, digits, hyphens).

| Do | Do not |
|----|--------|
| `goa-shop`, `goa-demo-cp4zqk`, `fermes-des-collines` | `Goa-Shop`, `GOA-DEMO`, mixed case |

**Why:** uppercase (or mixed-case) ids produce **odd HTTP 401** failures on
login / private API even when the password/token is correct. Auth looks like
“wrong secret” but the real issue is path / instance string case.

Create instances, login fields, `Authorization` targets, and `taler://pay…`
paths with the **exact lowercase** id. Display names may use capitals;
**ids must not**.

## Demo instance (2026-07-09)

Self-provisioned shop **`goa-demo-cp4zqk`**, bank account same username, payto linked, seed **GOA:5000**.

Details + credential paths: **`demo-instance-goa-demo-cp4zqk.md`**.
