1.6 How a payment flows through Hyperswitch

Now that you’ve successfully created and confirmed a payment using Hyperswitch APIs, it’s important to understand what actually happens inside the system when a payment is initiated. This section walks through the complete lifecycle of a payment, mapping user actions to Hyperswitch components and explaining how responsibilities are distributed across the stack.

To keep things simple, we’ll walk through a basic payment flow as an example. In this scenario, a new customer initiates a payment via the Hyperswitch SDK, enters their card details, and successfully completes the checkout with save card flow being triggered after the payment is successful. This flow represents the most common starting point for understanding how payments move across the merchant systems and Hyperswitch components, before we layer in more advanced concepts like 3DS, FRM, retries etc., in later sections.

Although we’ve already discussed the parties involved in the earlier modules, here’s a quick refresher to jog your memory before we go through the flow.

  • The Buyer is the end customer who is trying to complete a payment.

  • The Merchant Client is the merchant’s front-end (web/mobile) where the buyer interacts with the checkout UI.

  • The Merchant Server is the merchant’s backend that creates payment intents, stores order context, and talks to Hyperswitch securely.

  • The Hyperswitch SDK is the client-side library embedded in the merchant client to render payment UI, collect payment details securely, and coordinate the next steps.

  • The Hyperswitch Router is Hyperswitch’s backend API layer that validates requests, creates/updates payment objects.

  • The Decision Engine is responsible for evaluating routing logic and deciding which payment connector should be used for a given attempt.

  • Connectors are adapter layers that translate Hyperswitch’s internal payment model into processor-specific API requests.

  • The Processor’s Server represents the external payment gateway or acquirer that ultimately authorizes or declines the payment.

  • The Card Vault is a secure, PCI-compliant service responsible for storing and tokenizing sensitive payment instruments such as card details.

  • Scheduler is a background task orchestration component that manages delayed, asynchronous workflows, such as polling for payment status updates etc.,

The flow starts when the Buyer initiates checkout, which hits the merchant side first and results in the Merchant Client getting enough context to begin the payment journey. Next, the Merchant Client asks the Merchant Server to create a checkout. This is typically where the merchant server decides the amount, currency, customer context, and creates a payment object to be sent to Hyperswitch along with headers (api_key, publishable_key, profile_id and the base_url) as discussed in the previous section. Once the server has the checkout context, the Merchant Server calls the Hyperswitch Router using /PaymentsCreate API call. The router creates with paymentID (this is also called payment intent id) and clientSecret which the client needs to proceed with a secure client-side flow. At this point, it’s important to understand a core concept in Hyperswitch’s payment model. The Payment Intent and Payment Attempt entities, which together form the foundation of how payments are modeled, executed, retried, and reconciled within the system. When you call /payments/create, Hyperswitch generates a payment_id. You can think of this payment_id as the Payment Intent ID. This represents the merchant’s expectation for the payment: the amount, currency, customer context, capture method, and other checkout-level details. Conceptually, it’s similar to a shopping cart / order reference on the merchant side logical payment request that the merchant wants to complete.

Inside that same payment, Hyperswitch also creates at least one Payment Attempt (with its own payment_attempt_id, usually when a confirm call is executed). A Payment Attempt represents the customer leg of the flow i.e., an execution attempt to fulfill the intent using a particular payment method and connector path. This is when the steps such as capturing payment instrument details (card), performing authentication if required, and sending the authorization/capture request to the processor are executed.

This distinction becomes really important as soon as retries or multiple tries enter the picture. A single Payment Intent (payment_id) can have multiple Payment Attempts, for example:

  • the first attempt fails due to a network/processor issue and Hyperswitch retries,

  • the customer retries with the same card,

  • the customer switches to a different card/payment method,

  • decision_engine chooses a different connector on a subsequent attempt.

In other words:

  • Payment Intent (payment_id) = the overall payment request (one logical payment)

  • Payment Attempt (payment_attempt_id) = each individual try to complete that request (many possible per intent)

From a state management lens, the Intent tracks the overall payment status across attempts, while each Attempt tracks the status of that specific authorization/capture attempt. This is also why the model helps both reconciliation (intent aligns neatly with merchant order/cart) and improving success rates (attempts enable retries, routing changes, and recovery strategies without losing the original intent). Now, back to the payment flow. The Merchant Server now passes the client secret which contains the paymet_id to the Merchant Client. With these values available on the front-end, the Merchant Client initializes the Hyperswitch SDK securely. Once initialized, the SDK calls the Router to fetch what it needs to render the payment experience shown as the grouped API calls /ListCustomerPaymentMethods, /MerchantPaymentMethods, /GetSession. The Router returns the available payment methods, after which the SDK is considered initiated and ready to take the buyer’s input. From there, the Buyer adds a new payment method and clicks “Pay Now”. Finally, the Hyperswitch SDK confirms the payment by calling /PaymentsConfirm to the Hyperswitch Router by constructing the payment object needed for the confirm call, which is the point where the router proceeds to execute the payment confirmation using the chosen payment method and the underlying connector setup.

Once the client-side SDK confirms the payment, the Hyperswitch Router begins the server-side execution of the payment attempt. The first step in this flow is the router invoking the routing evaluation logic (/Routing/Evaluate/Decide-gateway) against the Decision Engine. At this stage, the router provides the payment context such as amount, currency, merchant profile, and payment method while the Decision Engine evaluates routing rules, priorities, and eligibility. Based on this evaluation, the Decision Engine returns connector details, indicating which payment processor should be used for this attempt.

With the connector selected, the Hyperswitch Router proceeds to transform the payment request into a connector-specific format. This transformation step adapts Hyperswitch’s normalized payment model into the exact API contract expected by the chosen processor, including field mappings, authentication formats, and request structures. The transformed request is passed through the connector layer, ensuring Hyperswitch remains abstracted from processor-specific implementations.

Once transformation is complete, the router initiates the actual authorization by making a POST /Payment Attempt call via the selected connector to the Processor’s Server. This represents a single, concrete attempt to fulfill the previously created payment intent. The processor processes the request and responds with a payment status, such as success, failure, or a non-terminal state.

Finally, the processor’s response flows back through the connector and into the Hyperswitch Router. The router records the outcome of this attempt, updates the state of the payment attempt entity, and links it back to the original payment intent. This separation ensures that even if multiple retries or processors are involved later, the merchant’s original intent remains stable while each authorization attempt is tracked independently.

At this stage of the payment flow, the customer has already completed the checkout interaction via the SDK, and the Hyperswitch Router has processed the payment attempt with the processor. The Router now holds the authoritative view of the payment attempt outcome and begins post-processing based on the returned status. The Router first propagates the payment status back to the Hyperswitch SDK, which in turn communicates this status to the Merchant Client. Along with the status, a return URL is used to redirect the customer back to the merchant’s application, ensuring the user experience concludes cleanly with a success or failure outcome.

Once the status is determined, the Router evaluates whether the payment was successful. If the payment succeeds and the merchant has enabled card saving, the Router initiates a call to the Card Vault to store the customer’s card details. This step happens strictly after a successful payment to ensure that only valid and authorized payment instruments are stored. The Card Vault securely tokenizes the card information and persists it in a PCI-compliant manner, allowing the merchant to reference this card safely for future transactions without re-collecting sensitive data.

In parallel, the Router assesses whether the payment status is terminal or non-terminal. If the payment status is terminal meaning it will not change further the Router triggers an update to the Decision Engine, informing it of the final outcome. This allows Hyperswitch to update processor performance metrics, such as success rates, which are later used to make smarter routing decisions for future payment attempts.

If the payment status is not terminal, such as when the processor response is pending or delayed, the Router delegates responsibility to the Scheduler. In this case, the Router schedules a background task to periodically fetch the latest payment status from the processor. The Scheduler executes these tasks asynchronously, ensuring that long-running or delayed payment confirmations are eventually reconciled without blocking the customer’s checkout flow or overloading the Router with continuous polling.

Through this flow, Hyperswitch cleanly separates concerns: the Router coordinates state transitions and business logic, the Card Vault handles secure data persistence, and the Scheduler ensures eventual consistency for asynchronous payment outcomes.

This flow focuses on merchant notification, and status finalization, especially in scenarios where payment outcomes are delayed, updated asynchronously, or require retries. At this stage, the payment attempt has already been created and sent to the processor, but the final outcome may still evolve over time.

Once the payment status changes (either immediately or after a delay), the Hyperswitch Router becomes the central coordinator for propagating that updated state. When a definitive update is available, the Router sends the updated payment status back to the Merchant Client (typically via the SDK or server-side APIs). This ensures the merchant application is always aligned with the latest authoritative state of the payment.

If the payment is marked as successful, the Router propagates this success downstream and upstream. The success path is shown as a green dotted line in the diagram, indicating a clean terminal resolution. The merchant receives confirmation that the payment has completed successfully and can proceed with order fulfillment or post-payment business logic.

If the payment is marked as failed, the Router similarly propagates a terminal failure status (shown in red). This allows the merchant to present failure messaging to the customer, trigger alternative payment options, or log the failure internally for analytics and support workflows.

However, not all processor responses are immediately terminal. In cases where the payment status is not updated or not terminal, the Router delegates responsibility to the Scheduler. The Scheduler initiates a background task to fetch the latest payment status from the processor at a later time. This is done by calling into the Connector, which in turn communicates with the Processor’s Server using a “Get payment status” request. The processor responds with the latest known status, which flows back through the Connector to the Scheduler.

Once the Scheduler receives a status response, it forwards the updated state back to the Router. The Router then reassesses whether the payment has reached a terminal state. If it has, the Router updates internal records and propagates the final status to the merchant. If not, the Scheduler may continue polling based on configured retry logic.

In parallel, if outgoing webhooks to the merchant fail (for example, due to transient network issues or merchant endpoint downtime), the Router schedules a retry task for the outgoing webhook via the Scheduler. This ensures that merchants eventually receive critical payment lifecycle events even if initial delivery attempts fail.

Overall, this flow ensures eventual consistency across merchant systems, Hyperswitch, and processors. By separating synchronous checkout flows from asynchronous reconciliation and retry logic, Hyperswitch is able to provide a reliable, fault-tolerant payment experience that gracefully handles delayed processor responses, webhook failures, and network instability without blocking the customer or merchant in real time. To conclude, this section walked through the end-to-end payment flow in Hyperswitch, starting from checkout initiation and payment intent creation, all the way to authorization, reconciliation, and final status propagation. By breaking the flow into clear stages intent vs attempt, client-side SDK interactions, routing and decisioning, connector execution, vaulting, and asynchronous status handling you can see how Hyperswitch cleanly separates concerns while still coordinating them through a single, consistent control plane. This design allows merchants to build reliable payment experiences that handle retries, delays, and failures gracefully, without complicating their own systems. With this foundational understanding of how a payment moves through Hyperswitch’s components, you are now well-positioned to explore more advanced topics.

Last updated