Stripe
Stripe integration supports one-time payments (PaymentIntents), saved cards for recurring billing, and refunds.
Getting Started — Step by Step
flowchart TB
A["1. Create Stripe Account"] --> B["2. Get API Keys"]
B --> C["3. Get API Key from Payments Service"]
C --> D["4. Configure Stripe Credentials"]
D --> E["5. Set Webhook URL"]
E --> F["6. Make Your First Payment"]
style A fill:#e3f2fd
style F fill:#e8f5e9
Step 1: Create a Stripe Account
- Go to Stripe Dashboard
- Create an account and verify your email
Step 2: Get API Keys
- Go to Developers → API Keys
- Copy your Secret key (
sk_test_...for sandbox,sk_live_...for production) - Optionally, set up a webhook endpoint in Stripe Dashboard → Webhooks to get a Webhook signing secret (
whsec_...)
Test mode
Use sk_test_ keys and Stripe test cards for development.
Step 3: Get an API Key from Payments Service
Step 4: Configure Stripe Credentials
{
"provider": "stripe",
"stripe": {
"secret_key": "sk_test_your_stripe_secret_key",
"webhook_secret": "whsec_your_webhook_signing_secret"
}
}
Step 5: Set Your Webhook URL
Step 6: Make Your First Payment
Test payment methods
In test mode, use pm_card_visa, pm_card_mastercard, or pm_card_declined to simulate different outcomes.
Payment Flow
sequenceDiagram
participant Merchant
participant API as Payments API
participant Stripe
participant Webhook as Merchant Webhook
Merchant->>API: POST /v1/payments<br/>{ provider: "stripe", amount: 50.00 }
API->>Stripe: POST /v1/payment_intents<br/>(with merchant's secret_key)
Stripe-->>API: { id: "pi_...", status: "succeeded" }
API-->>Merchant: { status: "completed", provider_ref: "pi_..." }
Note over Stripe,API: Stripe also sends webhook callback
Stripe->>API: POST /v1/webhooks/stripe<br/>(Stripe-Signature header)
API->>API: Verify signature + dedup
API->>Webhook: POST merchant_url<br/>{ type: "payment.completed" }
Create Payment
Request
{
"amount": 50.00,
"currency": "USD",
"provider": "stripe",
"payment_method": "pm_card_visa",
"return_url": "https://merchant.com/return"
}
| Field | Type | Required | Description |
|---|---|---|---|
amount |
decimal | ✅ | Amount to charge (> 0) |
currency |
string | ✅ | 3-letter ISO code (e.g. USD, KES) |
provider |
string | ✅ | Must be stripe |
payment_method |
string | ❌ | Stripe pm_ token from client-side |
return_url |
string | ❌ | Redirect URL after 3DS authentication |
saved_card_id |
UUID | ❌ | Use a previously saved card |
Response
{
"success": true,
"data": {
"id": "a1b2c3d4-...",
"merchant_id": "m1m2m3-...",
"amount": "50.00",
"currency": "USD",
"provider": "stripe",
"status": "completed",
"provider_ref": "pi_3abc...",
"idempotency_key": "order-123",
"created_at": "2025-01-01T12:00:00Z"
}
}
Status Values
| Status | Meaning |
|---|---|
completed |
Payment succeeded (succeeded on Stripe) |
pending |
Requires action (3DS) or processing |
failed |
Payment method declined or error |
Saved Cards (Recurring)
Save a Card
sequenceDiagram
participant Frontend
participant API as Payments API
participant Stripe
Frontend->>Stripe: Stripe.js collects card<br/>→ pm_card_visa
Frontend->>API: POST /v1/payments/cards<br/>{ payment_method_id: "pm_..." }
API->>Stripe: POST /v1/customers
Stripe-->>API: { id: "cus_..." }
API->>Stripe: POST /v1/payment_methods/pm_.../attach
API-->>Frontend: { last4: "4242", brand: "visa" }
Request
{
"payment_method_id": "pm_1abc...",
"customer_email": "user@example.com",
"customer_name": "Jane Doe"
}
Response
{
"success": true,
"data": {
"id": "card-uuid-...",
"provider": "stripe",
"brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2027,
"is_default": true,
"created_at": "2025-01-01T12:00:00Z"
}
}
Charge a Saved Card
The payment is processed off-session — no customer interaction needed.
List & Delete Cards
GET /v1/payments/cards # List all saved cards
DELETE /v1/payments/cards/{id} # Detach from Stripe + deactivate
Refund
| Field | Type | Required | Description |
|---|---|---|---|
payment_id |
UUID | ✅ | Original payment to refund |
amount |
decimal | ❌ | Partial refund amount. Omit for full refund |
Response
{
"success": true,
"data": {
"id": "refund-uuid-...",
"payment_id": "a1b2c3d4-...",
"status": "completed",
"provider_ref": "re_1abc...",
"amount": "25.00",
"created_at": "2025-01-01T12:00:00Z"
}
}
Inbound Webhook (Stripe → Us)
Stripe sends events to POST /v1/webhooks/stripe with a Stripe-Signature header.
Verification: t=timestamp,v1=hmac — timestamp must be within 5 minutes.
Events handled:
| Stripe Event | Our Status |
|---|---|
payment_intent.succeeded |
completed |
payment_intent.payment_failed |
failed |
charge.refunded |
refunded |
Viewing Stripe Transactions
List and filter all Stripe transactions:
GET /v1/payments?provider=stripe&status=completed
GET /v1/payments?provider=stripe&min_amount=100¤cy=USD
GET /v1/payments?provider=stripe&since=2025-06-01T00:00:00Z
See Payments API → List & Filter for all available filters.