Overview
Users acquire credits via one-off purchases or (future) subscription packs. Stripe Payment Intents are used to ensure strong idempotency and accurate post-payment credit allocation.Purchase Flow
- User selects credit pack (e.g., 500, 1k, 5k)
- Frontend creates Payment Intent via
/api/payments/create-intent - User completes card authentication
- Webhook listens for
payment_intent.succeeded - Credits added to user balance transactionally
Webhook Handling (Conceptual)
Idempotency & Safety
| Concern | Mitigation |
|---|---|
| Double credit allocation | Store processed intent IDs |
| Failed payment after UI success | Rely solely on webhook event |
| Currency mismatches | Validate amount vs pack definition |
| Refund adjustments | Implement reverse credit transactions |
Credit Packs Example
| Pack | Credits | Price (USD) | Effective / Credit |
|---|---|---|---|
| Starter | 500 | $10 | $0.020 |
| Creator | 1000 | $18 | $0.018 |
| Scale | 5000 | $80 | $0.016 |
| Custom | Negotiated | Varies | As agreed |
Balance Endpoint
UI Patterns
- Real-time balance badge near generation actions
- Pre-flight cost preview vs available balance
- Post-purchase toast with new balance & usage suggestions
Failure Scenarios
| Scenario | Result | User Feedback |
|---|---|---|
| Payment incomplete | No credit change | Show retry CTA |
| Webhook delayed | Temporary UI mismatch | Poll balance after short delay |
| Refund issued | Negative credit adjustment | Email + dashboard log |
Audit Logging
Store credit allocation events:{ id, userId, delta, source, referenceId, createdAt } for reconciliation.
Related Pages
- [/percify/credits]
- [/percify/faq]
Next: Platform safety at [/percify/security].