Skip to main content
This walkthrough covers the full payment lifecycle: card payment via Stripe checkout, payment reconciliation via webhook, refund, and the parallel bank-transfer flow with invoice generation. It uses the Product, ProductPayment, and Invoice resources. Who is this for: backend integrations that drive the membership fee collection, ticket sales, or donation campaigns; finance-ops tools that automate refunds and reconcile against accounting systems.

Architecture

Orgo doesn’t process card data directly — that’s Stripe’s job. Orgo orchestrates the flow:
Bank-transfer flow is parallel:
Same downstream event from your system’s perspective. That’s deliberate — your reconciliation code handles both cases identically.

Card payment — Stripe checkout

Step 1 — Generate a checkout URL

For a membership product the member is buying:
For event-ticket purchases, the checkout URL comes back automatically inside the EventAttend response when the event has paid tickets — see Create and sell event tickets. Response includes a checkoutUrl:
Redirect the user to checkoutUrl. Stripe handles the card collection.

Step 2 — Stripe completes the charge

On Stripe’s side, the charge succeeds (or fails). Stripe POSTs to Orgo’s webhook at /api/v1/stripe-webhook. This is invisible to your integration — Orgo handles it. Internally, Orgo creates a ProductPayment record with status: SUCCESS (or FAILED).

Step 3 — React via webhook

Subscribe to product_payment.updated:
In your handler:
See Handle webhooks for the full receiver pattern.

Refunding a paid charge

When a member requests a refund (cancelled event, mistaken purchase, dispute settlement), call the refund endpoint:
amount in cents. Omit for a full refund. reason is passed through to Stripe — common values: duplicate, fraudulent, requested_by_customer. Used for Stripe’s dispute analytics. The refund returns immediately with the updated ProductPayment showing status: REFUNDED. Stripe processes the actual transfer over the following 5-10 business days. For partial refunds, call repeatedly until cumulative amount equals the original charge.
Refunds are not reversible. Once issued, the funds are returned to the cardholder. To re-charge, the cardholder must complete a new checkout.

Bank transfer with invoice

For members who pay by bank transfer (corporate memberships, multi-thousand-dollar annual fees, regions where cards are uncommon), the flow is:

Step 1 — Issue an invoice

Response:
A PDF is generated and emailed to billingEmail. The member transfers funds to the account printed on the invoice.

Step 2 — Mark as paid

When you see the transfer hit the bank, mark the invoice:
This creates the linked ProductPayment with status: SUCCESS and method: BANK_TRANSFER. Your webhook receiver sees the same product_payment.updated event it sees for card payments.

Cancellation, void, refund

Resending the invoice email

Useful when the member’s accounts-payable department asks for a copy.

Reporting and reconciliation

All payments in a date range

hydra:totalItems gives you the count, the array gives you the data. Paginate as usual.

Sum of successful payments

There’s no aggregation endpoint — fetch the page and sum locally. For monthly reporting, this is fine. For dashboards refreshing every minute, cache the result.

Stuck-pending invoices

Returns invoices past their due date but still unpaid — your dunning list.

Common gotchas

Stripe is connected at the local-center level (preferred) or the tenant level. The product’s unit determines which Stripe account is used. If the unit doesn’t have Stripe connected, checkout creation fails. Check Settings → Local Centers → [Center] → Payments.
Two causes: (1) the subscription wasn’t active at the time of the event — check the subscription state; (2) the receiver returned non-2xx 3 times in a row, so delivery is in the failed log. Hit GET /api/v1/webhook_subscriptions/{id}/delivery_logs and replay.
Stripe processes refunds asynchronously — typically 5-10 business days for cards, longer for some debit cards and most international cards. Check the refund status in Stripe’s dashboard for the authoritative answer.
No. Invoices are immutable once issued (legal requirement). Void the existing invoice and issue a corrected one. The void preserves the audit trail; the new invoice carries a new number.
Not via this endpoint. Orgo’s payment surface routes everything through Stripe’s hosted checkout. For card-on-file MOTO/subscription charges, use the SubscriptionProfile resource — Stripe handles the recurring billing.

What to do next