Overview
This implementation enables a dual-payment system where:- Stripe handles traditional payment methods (cards, Apple Pay, etc.) with embedded processing
- Flex handles HSA/FSA payments with a hosted checkout redirect flow
Implementation Steps
1
Create Server Actions
Server actions handle payment processing on the backend, ensuring API keys remain secure.
2
Build the Checkout Form Component
The checkout form integrates the Stripe Payment Element and handles payment routing.
3
Create Success Page
Display order confirmation after successful payment.
4
Configure Validation Schemas
Set up form validation using Zod for type safety and error handling.
1. Server Actions
Stripe Payment Intent Creation
Create a server action to generate Stripe PaymentIntents:app/actions/stripe.ts
The
automatic_payment_methods setting allows Stripe to automatically display all enabled payment methods, including cards, digital wallets, and bank transfers.Flex Checkout Session Creation
Create a server action to generate Flex checkout sessions:app/actions/flex.ts
2. Checkout Form Component
The checkout form is the heart of the integration, rendering the Payment Element and routing payments appropriately.Form Wrapper Component
components/checkout-form.tsx
The
customPaymentMethods configuration registers Flex as a payment option. The type: "static" setting displays Flex as a selectable option without embedded interactive elements.Main Checkout Form
components/checkout-form-inner.tsx
Key Implementation Details
Payment Method Detection:elements.submit() method returns the selected payment method ID, allowing you to route to the appropriate processor.
Conditional Routing:
This pattern keeps the payment logic clean and maintainable. The form doesn’t need to know about the specifics of each payment processor—it simply routes based on selection.
3. Validation Schemas
Use Zod for type-safe form validation:lib/schemas.ts
4. Utility Functions
Amount Formatting
Convert amounts to cents for Stripe:lib/utils.ts
Plan Details Retrieval
Fetch plan information from your data source:lib/utils.ts
In production, replace this with a database query or API call to fetch plan details dynamically.
5. Success Page
Display order confirmation after payment:app/success/page.tsx
6. Checkout Page Integration
Create your checkout page that uses the form:app/checkout/page.tsx
Payment Flow Diagram
Testing Your Integration
Test Mode Setup
- Stripe Test Mode: Use test API keys (starting with
sk_test_andpk_test_) - Flex Test Mode: Ensure you’re using Flex test credentials
- Test Cards: Use Stripe test cards
Testing Checklist
- Flex appears as a payment option in the Payment Element
- Selecting Flex redirects to Flex hosted checkout
- Selecting card payment processes inline with Stripe
- Success page displays correct order information
- Error messages display appropriately
- Form validation works as expected
- Payment confirmation emails are sent (if configured)
Common Test Scenarios
Test Stripe Payment Flow:Production Considerations
Security
Error Handling
Implement comprehensive error handling:Webhook Integration
For production deployments, implement webhooks to handle payment events: Stripe Webhooks:payment_intent.succeededpayment_intent.payment_failedcharge.refunded
- Configure in your Flex Dashboard
- Handle success/failure events
- Update order status in your database
Performance Optimization
- Lazy load Stripe.js to improve initial page load
- Cache plan details to reduce database queries
- Implement loading states for better UX
- Monitor payment processing times
Troubleshooting
Flex Not Appearing in Payment Element
Problem: Custom payment method doesn’t show up. Solutions:- Verify
FLEX_CUSTOM_PAYMENT_METHOD_IDis correct - Check that the custom payment method is enabled in Stripe Dashboard
- Ensure the ID is properly passed to Elements configuration
- Clear browser cache and reload
Payment Intent Creation Fails
Problem: Stripe returns an error when creating payment intent. Solutions:- Verify Stripe secret key is correct and not expired
- Check that the amount is in the correct format (cents)
- Ensure currency is supported
- Review Stripe Dashboard for API errors
Redirect Not Working After Flex Payment
Problem: User isn’t redirected back after Flex checkout. Solutions:- Verify
success_urlandcancel_urlare correct - Check that URLs are publicly accessible (not localhost in production)
- Ensure Flex API credentials are valid
- Review Flex Dashboard for session details
Form Validation Errors
Problem: Form submission fails with validation errors. Solutions:- Check Zod schema matches form fields
- Verify all required fields are included
- Review browser console for validation errors
- Test with minimal valid data first
Next Steps
- Implement webhook handlers for payment events
- Add payment status verification on the success page
- Set up error tracking and monitoring
- Configure production environment variables
- Test thoroughly in production mode before going live
- Review Stripe and Flex production checklists
Additional Resources
- Stripe Custom Payment Methods Documentation
- Stripe Payment Element Documentation
- Flex API Documentation
- Flex Checkout Sessions
Support
If you encounter issues:- Review this documentation thoroughly
- Check Stripe and Flex Dashboard logs
- Review browser console for errors
- Contact Flex support with specific error messages and request IDs