Set Up Payments
This guide shows you how to enable credit purchases via Stripe so users can buy credits through a self-service checkout flow.
Prerequisites
- A Stripe account with API access
- A Stripe Price configured for credit purchases
- Platform Manager role (for testing)
Configure Stripe
Add your Stripe credentials to the configuration:
payment:
stripe:
api_key: "sk_live_..."
webhook_secret: "whsec_..."
price_id: "price_..."
host_url: "https://your-app.example.com"Or via environment variables:
DWCTL_PAYMENT__STRIPE__API_KEY=sk_live_...
DWCTL_PAYMENT__STRIPE__WEBHOOK_SECRET=whsec_...
DWCTL_PAYMENT__STRIPE__PRICE_ID=price_...
DWCTL_PAYMENT__STRIPE__HOST_URL=https://your-app.example.comConfiguration Options
| Option | Required | Description |
|---|---|---|
api_key | Yes | Your Stripe secret key (sk_live_... or sk_test_...) |
webhook_secret | Yes | Webhook signing secret (whsec_...) |
price_id | Yes | Stripe Price ID for credit purchases |
host_url | Yes | Your app's URL (for redirect after payment) |
enable_invoice_creation | No | Generate invoices for payments (default: false) |
Create a Stripe Price
In Stripe Dashboard:
- Go to Products → Add product
- Name it something like "API Credits"
- Set the price (e.g., $10.00 for 1000 credits)
- Copy the Price ID (starts with
price_)
The credit amount users receive is determined by the price amount. For example, if your price is $10.00, users receive 10 credits (1 credit = $1.00 by convention).
Set Up the Webhook
Stripe uses webhooks to notify your application when payments complete. This is more reliable than waiting for users to return to your site.
1. Create the webhook in Stripe
- Go to Developers → Webhooks
- Click Add endpoint
- Enter your webhook URL:
https://your-app.example.com/admin/api/v1/webhooks/payments - Select events to listen for:
checkout.session.completed
- Click Add endpoint
- Copy the Signing secret (starts with
whsec_)
2. Configure the webhook secret
Add the signing secret to your configuration:
DWCTL_PAYMENT__STRIPE__WEBHOOK_SECRET=whsec_...The webhook secret is used to verify that incoming webhook requests actually came from Stripe.
Test with Dummy Provider
For development and testing, use the dummy payment provider instead of Stripe:
payment:
dummy:
amount: 50
host_url: "http://localhost:3001"Or via environment variables:
DWCTL_PAYMENT__DUMMY__AMOUNT=50
DWCTL_PAYMENT__DUMMY__HOST_URL=http://localhost:3001The dummy provider:
- Skips actual payment processing
- Immediately grants the configured amount of credits
- Useful for testing the checkout flow without a Stripe account
Never use the dummy provider in production. It grants credits without collecting payment.
How Users Purchase Credits
Once configured, users can purchase credits from the dashboard:
- User navigates to Cost Management
- User clicks Buy Credits
- User is redirected to Stripe's hosted checkout page
- User enters payment details and completes purchase
- User is redirected back to your app
- Credits are added to their balance
The checkout flow is handled entirely by Stripe's pre-built checkout page. You don't need to build any payment UI.
Admin Credit Grants
Platform Managers can grant credits to users without requiring payment:
- Go to Cost Management
- Select a user
- Click Grant Credits or Remove Credits
- Enter the amount and confirm
This creates an AdminGrant or AdminRemoval transaction in the ledger.
Via API:
curl -X POST "https://your-instance/admin/api/v1/transactions" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user-uuid",
"transaction_type": "admin_grant",
"amount": 100,
"description": "Welcome bonus"
}'Initial Credits for New Users
To automatically grant credits to new users on signup, configure:
credits:
initial_credits_for_standard_users: 10Or:
DWCTL_CREDITS__INITIAL_CREDITS_FOR_STANDARD_USERS=10This creates an AdminGrant transaction when a new StandardUser account is created.
Troubleshooting
Payments complete but credits don't appear
Check that:
- The webhook is configured correctly in Stripe
- The webhook secret matches your configuration
- The webhook endpoint is accessible from the internet
- Check server logs for webhook processing errors
Webhook signature verification fails
The webhook secret must match exactly. Copy it again from Stripe Dashboard → Developers → Webhooks → your endpoint → Signing secret.
Users see "Payment not completed" error
The frontend may have tried to process the payment before Stripe sent the webhook. This is normal—the webhook will process the payment shortly. Users can refresh the page.
Related Topics
- How Billing Works — Understand credits and transactions
- Set Up Model Pricing — Configure per-token pricing
- Configuration Reference — All payment configuration options