## ADDED Requirements

### Requirement: Renewal date and lazy expiry
Orders SHALL have a `renews_at` date. Gating SHALL treat a `paid` order with `renews_at` in the past as lapsed.

#### Scenario: Past renewal date
- **WHEN** a scan arrives on a tag whose order is `paid` but `renews_at` is in the past
- **THEN** the order is treated as lapsed (alerts blocked)

#### Scenario: Future renewal date
- **WHEN** `renews_at` is in the future
- **THEN** normal paid gating applies

### Requirement: Unlock notification
When a scan is blocked because the order is lapsed or SMS credits are exhausted, the owner SHALL receive a notification stating their plan is lapsed or out of credits, with the tag link and a call to renew. The notification SHALL be sent via the configured channel (ntfy by default; SMS optional) and SHALL NOT consume SMS credits.

#### Scenario: Lapsed-order scan
- **WHEN** a scan is blocked by a lapsed order
- **THEN** the owner receives the unlock notice (one per scan)

#### Scenario: Credits-exhausted scan
- **WHEN** a scan is blocked by exhausted credits
- **THEN** the owner receives the unlock notice

### Requirement: Configurable channel
The unlock notification channel SHALL be configurable (`NOTIFY_CHANNEL`): `ntfy`, `sms`, or `both` (default `ntfy`).

#### Scenario: ntfy default
- **WHEN** `NOTIFY_CHANNEL` is unset
- **THEN** notices go to the configured ntfy topic
