CommunityPro / CommunityPro/community-pro-api

Sponsorship: Stripe Checkout endpoint (Phase 7.2)

Open
#15 0 comments 0 reactions 0 assignees View on GitHub
sponsorship
Dominant language
C#
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

## Scope
`POST /sponsorship/checkout` — **anonymous** (sponsors are not members). Creates a Stripe Checkout Session and returns its URL for redirect.

## Request
```json
{ "tierId": "…", "billingPeriod": "monthly|annual", "orgName": "…", "contactEmail": "…" }
```
or, for a custom one-off contribution:
```json
{ "customAmountCents": 50000, "currency": "usd", "orgName": "…", "contactEmail": "…" }
```

## Rules
- Tier path: `mode=subscription` with the tier's monthly/annual price id. Custom path: `mode=payment` with an ad-hoc price-from-amount (sane min/max bounds).
- `customer_creation=always`; prefill org name + email; success URL → `{frontend}/sponsors/thanks`, cancel URL → `/sponsors`.
- **No Sponsor row is created here** — activation happens in the webhook ticket {{S3}} on `checkout.session.completed` (pass tierId/orgName through Checkout `metadata`).
- Endpoint is unauthenticated → validate inputs hard and rate-limit-friendly (no DB writes, no email sends).

## Error codes
`sponsorship.tier_not_found`, `sponsorship.invalid_amount`, `sponsorship.invalid_request`

## Dependencies
Blocked by #14 (tiers + price ids).

## Acceptance criteria
- [ ] Subscription session built with correct price id per billing period
- [ ] Custom amount bounds enforced
- [ ] Metadata carries everything {{S3}} needs to build the Sponsor
- [ ] Fake-Stripe tests for both modes

### Conventions (project-wide, non-negotiable)
- .NET 9, records for immutable shapes, file-scoped namespaces, primary constructors where they read well. Minimal-API endpoints grouped per module via `IEndpointModule.MapEndpoints`.
- `Result` (SharedKernel) instead of exception-driven control flow. Endpoint results map failures to ProblemDetails with the stable error codes listed above — the frontend keys off them.
- Module owns its EF Core `DbContext` mapped to its own Postgres schema. Modules never reference each other's internals — cross-module needs go through a public contract interface or an in-process domain event (`IEventPublisher`).
- All external calls (GitHub, Stripe, Brevo, Cloudinary, Meilisearch) behind interfaces owned by the consuming module.
- Every list endpoint paginated (offset is fine). xUnit tests in `tests/CommunityPro.Tests//` following the existing harness patterns (see `Members/MembersTestHarness.cs`).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.