BaryoDev / BaryoDev/barakoCMS

Payments: a module for checkout, verified provider webhooks, refunds and reconciliation, PayMongo first

Open
#838 0 comments 0 reactions 0 assignees View on GitHub
module
Dominant language
C#
Stars
6
Forks
7
Avg merge
4h 42m
Merged PRs (30d)
307

Description

Comes up with almost every client: a registration fee (Color Me Fun, #814), a donation (rckoronadal.org), tuition, an order. Today a site either links to a payment page by hand and someone marks entries paid, or it is custom code.

## Change

A `BarakoCMS.Payments` module with provider adapters. PayMongo first (GCash, Maya, cards, bank transfer in the Philippines), Stripe second.

**Paying for an entry.**
- A content type declares what is payable: the amount field (money, or computed), currency, description, and the transition to run when paid (for example `Pending` to `Paid`) and when it fails or expires.
- `POST /api/public/payments/checkout` with the entry id returns the provider's hosted checkout URL. Card and wallet details never touch barakoCMS or barakoPress.
- The amount is read from the entry on the server, never taken from the request.

**Being told it was paid.**
- `POST /api/payments/webhooks/{provider}` verifies the provider's signature, is idempotent by the provider's event id, and runs the paid transition. A payment is only ever confirmed by the webhook or by asking the provider, never by the browser returning to a success page.
- A payment record per attempt (provider, reference, amount, status, time), Sensitive by default, linked to the entry.
- A daily reconciliation job asks the provider about attempts still pending and settles them, so a lost webhook does not leave an entry unpaid forever.

**After.**
- Workflows on the paid transition send the receipt (#829), post the journal entry to Accounting, or publish to a service (#831).
- Refunds through `POST /api/payments/{id}/refund`, gated by a capability and audited, running a refunded transition.
- Keys in the secret store (#785), never in configuration files.

**barakoPress:** a `payButton` block and the `form` block's "pay after submit" option. **barakoBrew:** payments list per entry, refund, and provider settings. Follow-up issues in those repositories.

## Done when

- A test with a fake provider: checkout for an entry returns a URL, a signed paid webhook runs the paid transition once, the same webhook again changes nothing, and an unsigned or tampered one is refused.
- A checkout request with a changed amount still charges the entry's amount.
- A pending attempt whose webhook never arrives is settled by reconciliation.

## Where it lives

Module: `BarakoCMS.Payments`, with each provider (PayMongo, Stripe) as an adapter inside it. It runs transitions and reads amounts through core services; the core gains nothing payment specific.

Contributor guide

Open the contributing guide

Research direction

Start by locating the BarakoCMS.Payments module and the core services used for transitions and amount reads. Review the checkout, webhook, refund, and reconciliation entry points, then run or add the fake-provider test described in Done when: checkout returns a URL, signed events are idempotent, tampering is refused, amounts come from the entry, and pending attempts reconcile.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend-api-design, payments
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.