This guide explains how to configure your products and prices in Stripe to work seamlessly with iaptic.
Define Product Types
Iaptic supports three product types:
- Subscriptions (recurring payments)
- Consumables (one-time purchases)
- Non-consumables (permanent one-time purchases)
Set the product type using Stripe metadata:
{
"product_type": "paid subscription" | "consumable" | "non consumable"
}
If no type is specified:
- Products with recurring prices default to "paid subscription"
- Products with one-time prices default to "consumable"
Important: A product must be either subscription-only or one-time-only. Mixed pricing types are not supported.
Add Product Information
Use metadata to store product-specific information:
{
"tier": "basic" | "premium" | "enterprise",
"max_users": "5" | "unlimited",
"features": "backup,api,support",
"can_purchase": "true" | "false"
}
This metadata is available to your application through the iaptic API:
const { products } = await iaptic.getProducts();
const premiumPlan = products.find(p =>
p.metadata?.tier === 'premium'
);
Configure Prices
Subscription Prices
// In Stripe Dashboard:
{
"recurring": {
"interval": "month" | "year",
"interval_count": 1,
},
"currency": "usd",
"unit_amount": 999 // $9.99
}
One-time Prices
// In Stripe Dashboard:
{
"currency": "usd",
"unit_amount": 499 // $4.99
}
Control Visibility
Products can be hidden from the catalog in several ways:
-
Archive in Stripe:
await stripe.products.update('prod_xyz', { active: false });
-
Use metadata:
{ "can_purchase": "false" }
-
Filter client-side:
const availableProducts = products.filter(p => p.metadata?.can_purchase === 'true' && p.metadata?.tier !== 'enterprise' );
Example Configurations
Premium Subscription
// Product
{
"name": "Premium Plan",
"metadata": {
"product_type": "paid subscription",
"tier": "premium",
"features": "all",
"max_users": "unlimited",
"can_purchase": "true"
}
}
// Prices
[
{
"recurring": { "interval": "month" },
"currency": "usd",
"unit_amount": 999
},
{
"recurring": { "interval": "year" },
"currency": "usd",
"unit_amount": 9990
}
]
Credit Pack (Consumable)
// Product
{
"name": "1000 Credits",
"metadata": {
"product_type": "consumable",
"credits": "1000",
"can_purchase": "true"
}
}
// Price
{
"currency": "usd",
"unit_amount": 499
}
Best Practices
-
Product Types
- Keep product types consistent
- Don't mix subscription and one-time prices
- Use explicit types in metadata
-
Metadata
- Use consistent keys across products
- Document metadata schema for your team
- Keep values as strings
-
Prices
- Use consistent currency formatting
- Consider regional pricing
- Plan trial periods carefully
-
Visibility
- Archive obsolete products instead of deleting
- Use
can_purchase
to temporarily disable products - Test visibility controls in development
Troubleshooting
Product Not Appearing
- Check product is active in Stripe
- Verify
can_purchase
metadata - Ensure price is active
- Check product type is valid
- Verify no mixed price types
Invalid Product Type
- Check metadata spelling
- Verify no mixed price types
- Archive and recreate if needed
Price Issues
- Verify currency code is valid
- Check amount formatting
- Ensure price is active
- Verify recurring settings