8.1 KiB
8.1 KiB
Stripe Integration Guide
Overview
This guide covers the Stripe live API integration for ShieldAI subscription management. The implementation includes webhook handlers, subscription management endpoints, and tier-based feature gating.
Environment Variables
Add the following to your .env file:
# Stripe Configuration
STRIPE_API_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_FREE_TIER_PRICE_ID=price_...
STRIPE_BASIC_TIER_PRICE_ID=price_...
STRIPE_PLUS_TIER_PRICE_ID=price_...
STRIPE_PREMIUM_TIER_PRICE_ID=price_...
Getting Stripe Live API Keys
1. Get Live API Key
- Go to Stripe Dashboard
- Navigate to Developers → API keys
- Toggle Live mode (top right corner)
- Copy the Secret key (starts with
sk_live_)
2. Get Webhook Signing Secret
- In Stripe Dashboard, go to Developers → Webhooks
- Click Add endpoint
- Add your webhook URL:
https://your-api-domain.com/api/v1/billing/webhooks/stripe - Select these events to listen for:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeededinvoice.payment_failed
- Click Add endpoint
- Copy the Signing secret (starts with
whsec_)
3. Create Price IDs for Subscription Tiers
- Go to Products in Stripe Dashboard
- Create products for each tier:
- Free Tier ( $0/month)
- Basic Tier ($9.99/month)
- Plus Tier ($19.99/month)
- Premium Tier ($49.99/month)
- For each product, create a recurring price
- Copy the Price IDs (start with
price_)
API Endpoints
Subscription Management
Get Current Subscription
GET /api/v1/billing/subscription
Authorization: Bearer <JWT_TOKEN>
Response:
{
"subscription": {
"id": "sub_123",
"status": "active",
"currentPeriodStart": "2026-05-01T00:00:00.000Z",
"currentPeriodEnd": "2026-06-01T00:00:00.000Z",
"cancelAtPeriodEnd": false
},
"customer": {
"id": "cus_123"
}
}
Create Subscription
POST /api/v1/billing/subscription/create
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"tier": "basic",
"customerId": "cus_123"
}
Update Subscription Tier
PUT /api/v1/billing/subscription/:subscriptionId/tier
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"tier": "plus"
}
Cancel Subscription
DELETE /api/v1/billing/subscription/:subscriptionId
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"cancelAtPeriodEnd": true
}
Get User Tier
GET /api/v1/billing/user/tier
Authorization: Bearer <JWT_TOKEN>
Response:
{
"tier": "basic",
"limits": {
"callMinutesLimit": 500,
"smsCountLimit": 2000,
"darkWebScans": 12
}
}
Create Customer Portal Session
POST /api/v1/billing/customer/portal
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
{
"customerId": "cus_123",
"returnUrl": "https://yourapp.com/billing"
}
Response:
{
"url": "https://billing.stripe.com/p/login/...",
"expiresAt": "2026-05-14T14:00:00.000Z"
}
Get Invoice History
GET /api/v1/billing/invoices?customerId=cus_123
Authorization: Bearer <JWT_TOKEN>
Webhook Handler
Stripe Webhook
POST /api/v1/billing/webhooks/stripe
Stripe-Signature: <SIGNATURE>
Content-Type: application/json
<Raw Stripe Event Body>
Webhook Events Handled
customer.subscription.created
Triggered when a new subscription is created.
customer.subscription.updated
Triggered when subscription details change (tier upgrade/downgrade, payment method update).
customer.subscription.deleted
Triggered when a subscription is cancelled.
invoice.payment_succeeded
Triggered when a payment is successfully processed.
invoice.payment_failed
Triggered when a payment fails.
Testing
Test with Stripe CLI
- Install Stripe CLI
- Login:
stripe login - Forward webhooks:
stripe listen --forward-to localhost:3000/api/v1/billing/webhooks/stripe
Test Events
# Trigger a subscription created event
stripe trigger customer.subscription.created
# Trigger a payment succeeded event
stripe trigger invoice.payment_succeeded
Mobile App Integration
React Native Example
import { API } from '@shieldai/api-client';
// Get current subscription
const getSubscription = async () => {
try {
const response = await API.get('/billing/subscription');
return response.data;
} catch (error) {
console.error('Failed to fetch subscription:', error);
}
};
// Create subscription
const createSubscription = async (tier, customerId) => {
try {
const response = await API.post('/billing/subscription/create', {
tier,
customerId,
});
return response.data;
} catch (error) {
console.error('Failed to create subscription:', error);
}
};
// Upgrade subscription
const upgradeSubscription = async (subscriptionId, newTier) => {
try {
const response = await API.put(
`/billing/subscription/${subscriptionId}/tier`,
{ tier: newTier }
);
return response.data;
} catch (error) {
console.error('Failed to upgrade subscription:', error);
}
};
// Cancel subscription
const cancelSubscription = async (subscriptionId) => {
try {
const response = await API.delete(
`/billing/subscription/${subscriptionId}`,
{ data: { cancelAtPeriodEnd: true } }
);
return response.data;
} catch (error) {
console.error('Failed to cancel subscription:', error);
}
};
Feature Gating
Use the middleware to protect routes based on subscription tier:
import { requireTier } from '@shieldai/shared-billing';
import { SubscriptionTier } from '@shieldai/shared-billing';
// Require minimum tier
fastify.get(
'/premium-feature',
{
preHandler: requireTier([SubscriptionTier.BASIC, SubscriptionTier.PLUS, SubscriptionTier.PREMIUM])
},
async (request, reply) => {
// Only accessible to BASIC tier and above
}
);
// Require specific tier
fastify.get(
'/exclusive-feature',
{
preHandler: requireTier([SubscriptionTier.PREMIUM])
},
async (request, reply) => {
// Only accessible to PREMIUM tier
}
);
Deployment Checklist
- Set
STRIPE_API_KEYto live key (not test key) - Set
STRIPE_WEBHOOK_SECRETto live webhook secret - Configure webhook endpoint in Stripe Dashboard
- Verify webhook events are being received
- Test subscription creation flow
- Test tier upgrade/downgrade flow
- Test cancellation flow
- Verify feature gating works correctly
- Monitor Stripe dashboard for errors
- Set up alerts for failed payments
Production Considerations
Security
- Never expose secret keys in client-side code
- Always verify webhook signatures on the server
- Use HTTPS for all API endpoints in production
- Implement rate limiting on webhook endpoints
Error Handling
- Idempotency: Webhook events may be delivered multiple times
- Retry logic: Stripe will retry failed webhook deliveries
- Logging: Log all webhook events for debugging
- Alerts: Set up alerts for payment failures
Compliance
- PCI DSS: Use Stripe Elements for payment collection
- GDPR: Handle customer data according to regulations
- Tax: Consider tax calculation for different regions
Troubleshooting
Webhook Signature Verification Fails
- Ensure
STRIPE_WEBHOOK_SECRETis correctly set - Verify the webhook URL matches what's configured in Stripe
- Check that raw body is being captured (not parsed JSON)
Subscription Creation Fails
- Verify
STRIPE_API_KEYis valid - Check that price IDs exist and are active
- Ensure customer ID is valid
Tier Not Updating
- Verify the new tier's price ID exists
- Check for active subscriptions on the customer
- Review Stripe dashboard for error messages
Support
For issues or questions:
- Stripe Dashboard: https://dashboard.stripe.com/
- Stripe Docs: https://stripe.com/docs
- Stripe Support: https://support.stripe.com/