Stripe
The Stripe integration enables payment processing, subscription management, and invoicing in your ContractSpec applications. All Stripe operations are type-safe, policy-enforced, and automatically logged.
Setup
Add your Stripe credentials to your environment variables:
# .env STRIPE_SECRET_KEY=sk_test_... STRIPE_PUBLISHABLE_KEY=pk_test_... STRIPE_WEBHOOK_SECRET=whsec_...
Get your API keys from the Stripe Dashboard.
Available capabilities
Payment Intents
capabilityId: stripe-create-payment-intent
provider:
type: stripe
operation: createPaymentIntent
inputs:
amount:
type: number
description: "Amount in cents"
currency:
type: string
default: "usd"
customerId:
type: string
optional: true
metadata:
type: object
optional: true
outputs:
paymentIntentId:
type: string
clientSecret:
type: string
status:
type: stringCustomers
capabilityId: stripe-create-customer
provider:
type: stripe
operation: createCustomer
inputs:
email:
type: string
name:
type: string
optional: true
metadata:
type: object
optional: true
outputs:
customerId:
type: string
email:
type: stringSubscriptions
capabilityId: stripe-create-subscription
provider:
type: stripe
operation: createSubscription
inputs:
customerId:
type: string
priceId:
type: string
trialDays:
type: number
optional: true
outputs:
subscriptionId:
type: string
status:
type: string
currentPeriodEnd:
type: timestampWebhooks
ContractSpec automatically handles Stripe webhooks. Configure your webhook endpoint in the Stripe Dashboard:
https://your-app.com/api/webhooks/stripe
Subscribe to these events:
payment_intent.succeededpayment_intent.payment_failedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
Example workflow
Here's a complete payment workflow using Stripe:
workflowId: process-payment
version: 1.0.0
steps:
- id: create-customer
capability: stripe-create-customer
inputs:
email: ${input.customerEmail}
name: ${input.customerName}
onSuccess: create-payment-intent
onFailure: notify-error
- id: create-payment-intent
capability: stripe-create-payment-intent
inputs:
amount: ${input.amount}
currency: "usd"
customerId: ${steps.create-customer.output.customerId}
onSuccess: send-payment-link
onFailure: notify-error
- id: send-payment-link
capability: send-email
inputs:
to: ${input.customerEmail}
template: "payment-link"
data:
clientSecret: ${steps.create-payment-intent.output.clientSecret}
amount: ${input.amount}
- id: notify-error
capability: send-email
inputs:
to: "admin@example.com"
template: "payment-error"
data:
error: ${error.message}Testing
Use Stripe's test cards for development:
| Card Number | Scenario |
|---|---|
| 4242 4242 4242 4242 | Successful payment |
| 4000 0000 0000 9995 | Insufficient funds |
| 4000 0000 0000 0002 | Card declined |
Best practices
- Always use test mode during development
- Verify webhook signatures to prevent fraud
- Handle idempotency for payment operations
- Store customer IDs for recurring payments
- Use metadata to link Stripe objects to your application records
- Monitor failed payments and retry logic