Stripe Payment Integration Troubleshooting
Real-world solutions to the most common Stripe integration issues encountered when building payment systems in Manus projects. Learn from actual debugging sessions that solved critical payment flow problems.
Critical payment blockers
Average debugging time
When following this guide
Root Cause
Stripe API keys are long alphanumeric strings that are extremely easy to mistype when copying manually. Even a single character error makes the entire key invalid. In our case, we discovered two critical typos in the secret key that prevented all payment operations.
❌ Incorrect (what was in code):
sk_test_51SyNhv4gIi3979acS70xTjNnyt5vgHmGrJW6kABTYdiBdcCG5yLqrCqkjR2Ffpfvx7J4nf2hdnDNJ567rSl0C5E800DY3ktfBI✅ Correct (from Stripe Dashboard):
sk_test_51SyNhv4gIi3979acS7OxTjNnyt5vgHmGrJW6kABTYdiBdcCG5yLqrCqkjR2Ffpfvx7J4nf2hdnDNJ567rSl0C5E800DY3kfBpI- Position 28:
S70should beS7O(zero → capital O) - Position 108-110:
3ktfBIshould be3kfBpI
Solution
Step 1: Verify Your API Keys Character-by-Character
- Go to Stripe Dashboard → Developers → API Keys
- Click "Reveal test key" for your Secret Key
- Copy the ENTIRE key (starts with
sk_test_) - Compare character-by-character with your code - don't trust your eyes alone!
- Watch out for lookalike characters:
0(zero) vsO(capital O),1(one) vsl(lowercase L)
Step 2: Update Keys in All Locations
Stripe keys may be referenced in multiple files. Search your entire project and update ALL occurrences:
Step 3: Use Environment Variables (Best Practice)
Never hardcode API keys. Use Manus's built-in secret management:
Root Cause
Price IDs in your code don't match the actual Price IDs in your Stripe account. This happens when you copy example code, use placeholder IDs, or create new products without updating your application code. Each Stripe Price has a unique ID that must match exactly.
Common scenarios:
- Using Price IDs from tutorial code or documentation examples
- Deleting and recreating products in Stripe (generates new IDs)
- Switching between test and live mode without updating IDs
- Typos in Price IDs (similar to API key typos)
Solution
Option A: Find Existing Price IDs (Recommended)
- Go to Stripe Dashboard → Products
- Click on your product (e.g., "Pro Subscription")
- Under "Pricing", find the price you want to use
- Copy the Price ID (starts with
price_) - Update your code with the correct ID
Option B: Create Products via Stripe API (Advanced)
Automate product creation to guarantee matching IDs:
Step 3: Update products.ts Configuration
Centralize all Price IDs in one file for easy management:
Root Cause
Modern browsers block popups that aren't triggered directly by user interaction. When you use window.open() inside an async callback (like after an API call), browsers treat it as an unwanted popup and block it silently. This is especially problematic on mobile devices where popup blockers are more aggressive.
❌ Problematic pattern:
Solution
Use Same-Window Redirect Instead
Replace window.open() with window.location.href to redirect in the same window. This works reliably across all browsers and devices.
Benefits of Same-Window Redirect
- No popup blockers: Works on all browsers without permission
- Mobile-friendly: Better UX on phones and tablets
- Stripe's recommendation: Official Stripe docs suggest this approach
- Proper flow: User completes payment, then returns to your success page
Configure Return URLs
Make sure your Stripe checkout session includes proper return URLs:
Use environment variables for all API keys
Never hardcode credentials in your source code
Copy API keys directly from Stripe Dashboard
Don't type them manually or copy from documentation
Create products via Stripe API in your setup script
Guarantees Price IDs match between Stripe and your code
Use window.location.href for checkout redirects
Avoid popup blockers by redirecting in the same window
Test with Stripe test card before going live
Use 4242 4242 4242 4242 to verify the complete flow
Test on both desktop and mobile devices
Mobile browsers have stricter popup blocking