Introduces bober_bbq/payments/base.py as the shared provider contract
(ProviderNotConfigured/ProviderError, the atomic claim_order_paid race
guard, and a documented function-shape convention) and
bober_bbq/payments/registry.py for provider selection/dispatch, so
checkout.py, orders.py, and reconciliation.py no longer hardcode
Monobank. monobank.py's public names/behavior are unchanged -- its
exceptions now subclass the generic ones and claim_order_paid is
re-exported from base.py, but every existing import keeps working.
Adds liqpay.py (Checkout/CNB API: base64(JSON)+sha1 signing, form-encoded
webhook, status polling, a local checkout-redirect bridge page since
LiqPay has no server-side "create invoice" call) and
api/payments_liqpay.py for its webhook + redirect routes. Wires a
"payment_provider" setting (admin-configurable, env fallback) and adds
matching LiqPay admin settings fields/test button.
No live LiqPay credentials were available to test against; verification
is a re-derived payment-race regression test (webhook/poll/reconciliation
racing to mark an order paid, for both providers) plus mocked-HTTP
structural checks. Uncertain LiqPay details (verify_token's error-code
heuristic) are flagged in liqpay.py and docs/PAYMENTS.md, which also
documents adding a third provider (Fondy, not implemented).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>