Stripe Subscription Trial Periods — Offering Free Trials Without Immediate Payment
In this tutorial, you will learn about Stripe Subscription Trial Periods. We cover key concepts, practical examples, and best practices to help you master this topic.
Stripe subscription trial periods let customers use your service for free before being charged, with automatic conversion to paid subscriptions at trial end and grace periods for payment failures.
What You'll Learn
- How to set up trial periods on subscriptions
- How to handle trial ending and payment collection
- How to use trial_settings for payment behavior
Why It Matters
Free trials are the most effective customer acquisition Strategy for SaaS products. Stripe handles the trial lifecycle: creating the subscription with trial days, sending trial-ending notifications, attempting payment at trial end, and handling failures gracefully.
Real-World Use
DodaTech offers a 14-day free trial for Pro plans. Users sign up with or without a card. At day 7, Stripe sends a trial-ending email. At day 14, Stripe attempts payment. If payment fails, the subscription enters past_due status and DodaTech degrades access after a 3-day grace period.
import stripe
stripe.api_key = 'sk_test_...'
# Create subscription with trial
subscription = stripe.Subscription.create(
customer='cus_abc123',
items=[{'price': 'price_pro_monthly'}],
trial_period_days=14,
trial_settings={
'end_behavior': {
'missing_payment_method': 'cancel' # or 'pause'
}
},
metadata={'trial_source': 'website_signup'}
)
print(f"Subscription: {subscription.id}")
print(f"Trial end: {subscription.trial_end}")
print(f"Status: {subscription.status}")
Trial Without Payment Method
def create_trial_without_payment(customer_id, price_id, trial_days=14):
"""Create a trial subscription without collecting payment method"""
try:
subscription = stripe.Subscription.create(
customer=customer_id,
items=[{'price': price_id}],
trial_period_days=trial_days,
trial_settings={
'end_behavior': {
'missing_payment_method': 'pause'
}
},
payment_settings={
'save_default_payment_method': 'on_subscription'
},
metadata={'trial_type': 'no_payment_required'}
)
return subscription
except stripe.error.StripeError as e:
print(f"Error creating trial: {e}")
return None
Handling Trial End
def handle_trial_ending(subscription_id):
"""Called when trial is ending - send reminder to customer"""
subscription = stripe.Subscription.retrieve(subscription_id)
# Check if customer has payment method
payment_methods = stripe.PaymentMethod.list(
customer=subscription.customer,
type='card'
)
if not payment_methods.data:
# Customer needs to add payment method
send_payment_reminder_email(
customer=subscription.customer,
days_remaining=3
)
# Create a SetupIntent for the customer
setup_intent = stripe.SetupIntent.create(
customer=subscription.customer,
metadata={'subscription_id': subscription_id}
)
return {
'needs_payment_method': True,
'setup_intent_client_secret': setup_intent.client_secret
}
return {'needs_payment_method': False}
Common Mistakes
1. Not Setting trial_settings.end_behavior
Without end_behavior, the subscription cancels immediately if the customer has no payment method at trial end. Set it to pause to keep the subscription but pause billing.
2. Too Short Trial Periods
Trials under 7 days don't give users enough time to evaluate. 14-30 days is standard for SaaS products.
3. Not Sending Trial-Ending Notifications
Customers forget trials end. Send reminders at day 7 and day 12 for a 14-day trial. Stripe can send these automatically.
4. Collecting Payment Method Too Early
Asking for payment method at signup reduces conversion rates. Allow trials without payment method and collect it later.
5. Forgetting to Handle Past Due
After trial ends, if payment fails, the subscription becomes past_due. Implement Webhook handling for invoice.payment_failed.
Practice Questions
- How do you set trial days on a subscription?
- What happens if a trial ends without a payment method?
- How do you allow trials without collecting payment?
- When should you send trial-ending reminders?
- What subscription status indicates a failed payment after trial?
Answers
- Set trial_period_days in Subscription.create(). 2. It depends on end_behavior: cancel or pause. 3. Create the subscription with trial_period_days but no payment method. 4. At 50% and 80% of the trial period. 5. past_due.
Challenge
Build a trial management system that: creates subscriptions with configurable trial periods, handles both with and without payment method signups, sends trial-ending notifications, manages trial-to-paid conversion, and handles payment failures with grace periods.
FAQ
Mini Project
Build a trial subscription flow: signup page with trial offer, subscription creation with trial_period_days and end_behavior, SetupIntent for collecting payment method during trial, webhook handling for trial-ending events, and a customer-facing page showing trial status and days remaining.
What's Next
- Learn about subscription proration for mid-cycle plan changes
- Explore upcoming invoices and previewing charges
- Continue to pause collection for subscription billing holidays
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro