Credits
Payments
Purchase credits
Initiates credit purchase via Stripe Checkout Session.
Purchase Process
┌─────────────────────────────────────────────────────────────┐
│ 1. Client calls POST /credits/purchase │
│ with package_id, success_url, cancel_url │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────┐
│ Verify package │
│ - Exists? │
│ - Active? │
│ - stripe_price_id? │
└─────────────────────┘
│ │
VALID │ │ INVALID
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Retrieve │ │ Error 404/400 │
│ stripeCustomerId │ │ │
│ from Better │ │ │
│ Auth │ │ │
└──────────────────┘ └──────────────────┘
│
▼
┌──────────────────────────────┐
│ Create Stripe Checkout │
│ Session with: │
│ - customer_id │
│ - price_id │
│ - metadata (tenant_id, │
│ user_id, package_id) │
│ - success_url │
│ - cancel_url │
└──────────────────────────────┘
│
▼
┌──────────────────────────────┐
│ Return checkout_url │
│ │
│ Client redirects to │
│ Stripe Checkout │
└──────────────────────────────┘
│
▼
┌──────────────────────────────┐
│ User pays on Stripe │
│ │
│ Stripe sends webhook │
│ checkout.session.completed │
└──────────────────────────────┘
│
▼
┌──────────────────────────────┐
│ Backend credits the credits │
│ via webhook handler │
└──────────────────────────────┘
Prerequisites
- The user must have the owner role (no Stripe account for tenants)
- The user must have a stripeCustomerId in Better Auth
- If absent, error 400: "You must have a Stripe account to purchase credits"
- The package must be active and have a stripe_price_id configured
Validations
- ✅ Validation of package_id (valid UUID)
- ✅ URL validation (success_url and cancel_url must be valid URLs)
- ✅ Verification that the package exists and is active
- ✅ Verification that the package has a stripe_price_id
- ✅ Retrieval of stripeCustomerId from Better Auth
- ✅ Creation of Stripe Checkout Session with complete metadata
Stripe Metadata
The Stripe Checkout Session includes the following metadata for webhook processing:
{
"tenant_id": "tenant_123",
"user_id": "user_456",
"package_id": "550e8400-e29b-41d4-a716-446655440000"
}
This metadata allows the webhook to credit the right user in the correct tenant after successful payment.
Error Handling
- 400 Bad Request: Invalid package, invalid URLs, or no Stripe account
- 401 Unauthorized: Invalid or expired API key
- 403 Forbidden: User is not an owner
- 404 Not Found: Package not found or inactive
- 500 Internal Server Error: Error creating the Checkout Session
Usage Example
curl -X POST https://api.faireplace.com/v1/credits/purchase \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"package_id": "550e8400-e29b-41d4-a716-446655440000",
"success_url": "https://app.faireplace.com/credits/success?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://app.faireplace.com/credits/cancel"
}'
Response:
{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4e5f6...",
"package_id": "550e8400-e29b-41d4-a716-446655440000",
"package_name": "Pack Starter",
"credits_amount": 1000,
"price_cents": 2990
}
The user must then be redirected to checkout_url to complete payment.
post/credits/purchase
Request
- Base URL: https://api.faireplace.com/api
- URL: https://api.faireplace.com/api/credits/purchase
- Auth: HTTP bearer
Request body
Example request
{
"package_id": "550e8400-e29b-41d4-a716-446655440000",
"success_url": "https://app.fairplace.com/credits/success?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://app.fairplace.com/credits/cancel"
}Response
Purchase session created successfully.
The user must be redirected to checkout_url to complete payment. Credits will be automatically credited after successful payment via webhook.
Example response
{
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4e5f6...",
"package_id": "550e8400-e29b-41d4-a716-446655440000",
"package_name": "Pack Starter",
"credits_amount": 1000,
"price_cents": 2990
}Changes
No recorded changes to this operation across all 1 revision of this API.