Redirect Users to Success Page After Payment
Redirection is the process of navigating users to a different page after completing a payment. In payment gateway integrations, redirection occurs after payment verification and checkout completion, sending users to success or failure pages with relevant order information. This page focuses on concepts and patterns for implementing post-payment redirection. Adapt the examples to your specific platform and payment gateway requirements. The examples use generic names (platformCheckout, storefrontDomain) that should be replaced with your actual implementations.
Connection to the flow: Redirection is the final step in the checkout flow. It's implemented in your Payment Handler after receiving a successful response from the Verify Endpoint. The redirect uses the platform order ID returned in the verification response, which was created by the checkoutCart mutation during verification.
Proper redirection ensures:
- Users see confirmation of successful payment
- Order details are accessible via URL parameters
- Failed payments don't redirect (allowing retry)
- Multi-tenant support (different domains)
- State synchronization with platform
When to Redirect
Redirection should only occur when:
- Payment is verified: Signature verification succeeds
- Checkout is completed: Platform order is created successfully
- All operations succeed: No errors in the payment flow
Redirect URL Structure
Success URLs typically follow this pattern:
https://{domain}/cart/order-status?success=true&order_id={order_id}
The URL includes:
- Domain: Storefront domain (from platform state)
- Path: Order status page (platform-specific)
- Query Parameters: Success flag and order ID
Platform State Integration
Redirection uses FPI to:
- Extract storefront domain
- Access application configuration
- Build dynamic URLs for multi-tenant support
- Optionally update frontend state before redirect
How Redirection Works
Redirection is implemented in your Payment Handler after receiving a successful response from the Verify Endpoint. The redirect uses the platform order ID from the verification response, which was created by the checkoutCart mutation during the verification process.
Verify Success Conditions
Before redirecting, verify all success conditions are met. Only redirect when all operations succeed. Missing order ID means checkout failed.
// Example: Verify success conditions
const paymentHandler = async function (response) {
// ... payment verification ...
const verification = await verifyPayment(paymentData);
// Extract results
// Response structure may vary: fynd_checkout (preferred) or platform_checkout
const platformCheckout = verification.data?.fynd_checkout ||
verification.data?.platform_checkout;
// Verify all conditions
const isSuccess =
verification.success && // Payment verified
platformCheckout?.success && // Checkout succeeded
platformCheckout?.order_id; // Order ID exists
if (isSuccess) {
// Proceed with redirect
} else {
// Handle failure (no redirect)
}
};
Extract Storefront Domain
Extract the storefront domain from platform state using a priority-based fallback strategy to ensure redirection works across different scenarios. Platform state provides tenant-specific domain information, but multiple fallbacks are essential when state is incomplete or unavailable. The fallback order should prioritize custom app hostname, then application domain from configuration, and finally use the current window hostname as the last resort.
// Example: Extract storefront domain
function getStorefrontDomain(state) {
// Try multiple sources in priority order
// 1. Custom app hostname (most reliable)
if (state.custom?.appHostName) {
return state.custom.appHostName;
}
// 2. Application domain from configuration
if (state.configuration?.application?.domain) {
return state.configuration.application.domain;
}
// 3. Current window hostname (fallback)
return window.location.hostname;
}
// Usage
const state = window.fpi.store.getState();
const storefrontDomain = getStorefrontDomain(state);
Build Success URL
Construct the success URL using the URL constructor to ensure proper encoding of query parameters and prevent issues with special characters. Include a success flag as a query parameter to enable the success page to display appropriate messaging and styling. The order ID must be included in the URL to enable order lookup and display order details on the success page.
// Example: Build success URL
function buildSuccessUrl(storefrontDomain, orderId) {
// Ensure protocol is included
const protocol = window.location.protocol || 'https:';
const domain = storefrontDomain.startsWith('http')
? storefrontDomain
: `${protocol}//${storefrontDomain}`;
// Build URL with query parameters
const url = new URL('/cart/order-status', domain);
url.searchParams.set('success', 'true');
url.searchParams.set('order_id', orderId);
return url.toString();
}
// Usage
const successUrl = buildSuccessUrl(storefrontDomain, platformCheckout.order_id);
Update Platform State (Optional)
Optionally update platform state before redirecting to improve user experience by clearing the cart and updating order tracking information. State updates should be wrapped in try-catch blocks to ensure that redirect failures never occur if state update operations fail. Remember that state updates are optional enhancements, while the redirect itself is critical for completing the payment flow.
// Example: Update platform state before redirect
function updatePlatformStateBeforeRedirect() {
try {
const fpi = window.fpi || window.__fpi__;
if (fpi?.store) {
// Clear cart after successful payment
// fpi.store.dispatch({ type: 'CLEAR_CART' });
// Update order state
// fpi.store.dispatch({
// type: 'SET_ORDER',
// payload: { orderId, status: 'completed' }
// });
console.log('Platform state updated');
}
} catch (error) {
// Don't fail redirect if state update fails
console.warn('Could not update platform state:', error);
}
}
// Call before redirect
updatePlatformStateBeforeRedirect();
window.location.href = successUrl;
Perform Redirect
Use a full page redirect with window.location.href to ensure complete page navigation and proper state cleanup, rather than using pushState which only updates the browser history. Alternatively, use window.location.replace() if you want to prevent users from navigating back to the payment page using the browser's back button. Keep the payment loader visible during the redirect to provide visual feedback, as it will be automatically removed when the new page loads.
// Example: Perform redirect
if (isSuccess) {
console.log('Redirecting to:', successUrl);
// Keep loader visible during redirect
// (loader will be removed when new page loads)
// Full page redirect
window.location.href = successUrl;
// Alternative: window.location.replace() prevents back button
// window.location.replace(successUrl);
}
Handle Failure (No Redirect)
Never redirect users on payment failure, as this prevents them from retrying the payment or navigating back to review their order. Hide the payment loader to restore user interaction capabilities and display a clear, actionable error message that explains what went wrong. Allow users to decide their next action, whether that's retrying the payment, going back to review their order, or contacting support.
// Example: Handle failure without redirect
else {
// Hide loader
hidePaymentLoader();
// Log failure details
console.error('Payment processing failed', {
verification_success: verification.success,
checkout_success: platformCheckout?.success,
error_message: verification.message || platformCheckout?.message
});
// Show error to user
alert(`Payment processing failed: ${verification.message || platformCheckout?.message || 'Unknown error'}`);
// Do NOT redirect - let user retry or go back
// User stays on current page
}
Complete Example: Redirection Implementation
Here's a complete example showing redirection in a payment handler:
// Example: Complete redirection implementation
// 1. Helper: Get storefront domain
function getStorefrontDomain(state) {
return state.custom?.appHostName ||
state.configuration?.application?.domain ||
window.location.hostname;
}
// 2. Helper: Build success URL
function buildSuccessUrl(domain, orderId) {
const protocol = window.location.protocol || 'https:';
const baseUrl = domain.startsWith('http')
? domain
: `${protocol}//${domain}`;
const url = new URL('/cart/order-status', baseUrl);
url.searchParams.set('success', 'true');
url.searchParams.set('order_id', orderId);
return url.toString();
}
// 3. Helper: Update platform state
function updatePlatformState() {
try {
const fpi = window.fpi || window.__fpi__;
if (fpi?.store) {
// Optional: Clear cart, update order state
console.log('Platform state updated');
}
} catch (error) {
console.warn('Could not update platform state:', error);
}
}
// 4. Main payment handler with redirection
const paymentHandler = async function (response) {
try {
// Show loader
showPaymentLoader('Processing payment...');
// Verify payment
const verification = await verifyPayment(response);
if (!verification.success) {
throw new Error(verification.message || 'Payment verification failed');
}
// Extract platform checkout result
// Response structure may vary: platform_checkout or fynd_checkout
const platformCheckout = verification.data?.platform_checkout ||
verification.data?.fynd_checkout;
// Verify success conditions
// All three conditions must be true for successful redirect
const isSuccess =
verification.success && // Payment verified
platformCheckout?.success && // Checkout succeeded
platformCheckout?.order_id; // Order ID exists
if (isSuccess) {
// Get platform state
const state = window.fpi.store.getState();
// Extract storefront domain
const storefrontDomain = getStorefrontDomain(state);
// Build success URL
const successUrl = buildSuccessUrl(
storefrontDomain,
platformCheckout.order_id
);
// Log redirect
console.log('Payment successful - redirecting to:', successUrl);
// Update platform state (optional)
updatePlatformState();
// Perform redirect
window.location.href = successUrl;
} else {
// Handle failure
hidePaymentLoader();
const errorMessage = verification.message ||
platformCheckout?.message ||
'Payment processing failed';
console.error('Payment processing failed', {
verification_success: verification.success,
checkout_success: platformCheckout?.success,
has_order_id: !!platformCheckout?.order_id,
error_message: errorMessage
});
alert(`Payment processing failed: ${errorMessage}`);
// No redirect on failure - user stays on page to retry or go back
}
} catch (error) {
// Handle errors
console.error('Payment processing error:', error);
hidePaymentLoader();
alert(`Payment processing failed: ${error.message}`);
// No redirect on error
}
};
Best Practices
1. Verify Success Before Redirect
Always verify all success conditions. Multiple conditions ensure redirect only happens when everything succeeds.
// Example: Comprehensive success check
const isSuccess =
verification.success && // Payment verified
platformCheckout?.success && // Checkout succeeded
platformCheckout?.order_id && // Order ID exists
!verification.errors; // No errors
if (isSuccess) {
redirect();
} else {
handleFailure();
}
2. Keep Loader Visible
Keep loader visible during redirect. Loader provides feedback during redirect. New page load removes it automatically.
// Example: Loader during redirect
if (isSuccess) {
// Loader stays visible
showPaymentLoader('Redirecting to order confirmation...');
// Redirect
window.location.href = successUrl;
// Loader will be removed when new page loads
}
Next Steps
After implementing redirection, you've completed the checkout extension flow:
- Test the complete flow: Verify the entire flow from Buy Now click to success page redirect
- Review the flow: The complete flow is documented in the Introduction page
The redirection completes the checkout extension implementation. Users are now successfully redirected to the order confirmation page after payment.