feat(payment): FlatRender Pay (ZarinPal broker) checkout + webhook
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m3s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 37s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m10s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 53s
CI/CD / Deploy · all services (push) Successful in 1m41s
CI/CD / CI · API (dotnet build + test) (push) Successful in 1m3s
CI/CD / CI · Admin API (dotnet build) (push) Successful in 37s
CI/CD / CI · Dashboard (tsc) (push) Successful in 1m10s
CI/CD / CI · Admin Web (tsc) (push) Successful in 37s
CI/CD / CI · Website (tsc) (push) Successful in 44s
CI/CD / CI · Koja (tsc) (push) Successful in 53s
CI/CD / Deploy · all services (push) Successful in 1m41s
Adds a signed broker integration for online plan purchases:
- FlatPayService: POST /v1/pay/request with X-Api-Key + X-Signature =
hex(HMAC-SHA256(secret, raw JSON bytes)); the exact serialized bytes are both
signed and sent. VerifyWebhook does a fixed-time compare of the digest, plus an
in-memory first-seen idempotency set.
- POST /api/payment/request (auth, ManageBilling): parses a "Tier:Months" product
(e.g. "Pro:12"), prices it via the plan catalog, creates a Pending SubscriptionPayment
(provider=FlatPay) as the order, and returns the broker payment URL. The order id is
the client_ref / metadata.payment_id.
- POST /api/payment/webhook (anonymous; HMAC is the auth — 401 on bad signature):
on status=Paid + first-seen id, grants the order via the shared plan-activation
path (extracted ActivatePaymentAsync, reused by all providers). Always 200 after a
valid signature so the broker won't retry an accepted job.
- Config FlatPay__{ApiKey,Secret,BaseUrl,ReturnUrl} (env-supplied; secrets stay out
of git), compose + .env.example wiring. PaymentProvider.FlatPay appended (int, no
migration).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
namespace Meezi.API.Models.Payments;
|
||||
|
||||
/// <summary>Body for POST /api/payment/request. ProductId is a "Tier:Months" bundle, e.g. "Pro:12".</summary>
|
||||
public record PaymentRequestDto(string ProductId);
|
||||
|
||||
public record PaymentRequestResponse(string Url, string PaymentId);
|
||||
Reference in New Issue
Block a user