d05cce6550
ZarinPal only accepts callbacks on pay.flatrender.ir, so bargevasat pays through the shared broker and is credited via a signed webhook. - FlatPayService: broker client (HMAC-signed /v1/pay/request) + webhook signature verification + in-memory idempotency guard. - Program.cs: /api/coins/pay/request prefers the broker when configured (FlatPay__ApiKey/Secret set), else the legacy direct ZarinPal path; new public POST /api/coins/pay/webhook verifies the HMAC and credits coins from the echoed metadata (idempotent). - appsettings + docker-compose: FlatPay config (empty ⇒ legacy path). - web: recognise the broker's ?status=Paid return + re-refresh profile (coins are credited server-side via webhook). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>