# Exploration Guide

Try Hyperswitch and explore its modular architecture for a secure, streamlined payments

Hyperswitch gives you full control over your payments infrastructure without the complexity of building from scratch. Whether you're validating a prototype or scaling globally, you can get started in minutes.

### Try Hyperswitch Product Quickly

#### Use our hosted sandbox or Playground to explore the product quickly :

<details>

<summary><strong>Cloud Sandbox (Hyperswitch Hosted Test Environment)</strong></summary>

[Try Hyperswitch →](https://app.hyperswitch.io)\
Launch a ready-to-use Control Center test environment. No setup required, just log in and run your first transaction.

</details>

<details>

<summary><strong>Hosted playground environment (pre-configured)</strong></summary>

[Explore playground →](https://app.hyperswitch.io/hsdemo/)

Try all our product features in a pre-configured playground environment

</details>

### Try Hyperswitch Deployment Quickly

#### Deploy using Docker or Helm charts in local or a cloud environment:

<details>

<summary><strong>Local Deployment (Docker)</strong></summary>

[Set up Docker Locally →](https://github.com/juspay/hyperswitch-docs/tree/main/setup-hyperswitch-locally/run-hyperswitch.md)\
Perfect for developers who want local control and flexibility.

</details>

<details>

<summary><strong>Local Deployment (Helm charts)</strong></summary>

[Set up Docker Locally →](https://github.com/juspay/hyperswitch-docs/tree/main/setup-hyperswitch-locally/run-hyperswitch.md)\
Perfect for architects and infrastructure teams who want view all available components.

</details>

<details>

<summary><strong>Scalable, Self-Hosted Deployment | Helm Charts for AWS, GCP &#x26; Azure</strong></summary>

[Deploy on GCP or Azure →](https://docs.hyperswitch.io/self-hosting)

Install Hyperswitch on your cloud infrastructure using Helm charts for Kubernetes. This method gives you full control over your environment and is ideal for teams deploying on GCP, Azure, or any Kubernetes-compatible platform.

</details>

### Hyperswitch Capabilities Overview

Power only what you need with Hyperswitch’s modular architecture. You can pick and integrate the components that solve your specific payment challenges without unnecessary overhead.

<details>

<summary><strong>Power Only What You Need with Hyperswitch’s Modular Architecture</strong></summary>

[Intelligent Routing →](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/intelligent-routing)

Dynamically route transactions based on geography, cost, or success rate to reduce failures and fees.

[Revenue Recovery →](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/revenue-recovery)

Recover failed payments using machine learning–based retry logic that adapts to card network behavior.

[Vault (Tokenization) →](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/vault)

Securely store and reuse payment credentials across providers — ideal for subscriptions and saved cards.

[Cost Observability →](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/ai-powered-cost-observability)

Gain real-time visibility into your processing costs and optimize spend across processors.

[Reconciliation →](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/reconciliation)

Automatically match transaction data across banks, PSPs, and internal systems to reduce manual effort.

[3DS Decision Manager →](https://docs.hyperswitch.io/explore-hyperswitch/payment-orchestration/3ds-decision-manager)

Apply 3DS only when necessary, minimizing friction while keeping fraud under control.

[Payment Orchestration →](https://docs.hyperswitch.io/explore-hyperswitch/payment-orchestration)

Automate disbursements to vendors or sellers with rule-based routing logic.

</details>

### Explore Core Payment Flows and Capabilities

Power only what you need with Hyperswitch’s modular architecture. Integrate just the components that solve your payment challenges, without the extra overhead.

<details>

<summary><strong>Build Smarter Payment Flows</strong></summary>

[Payment Orchestration →](/other-features/payment-orchestration)

Automate and optimize how payments are routed, authorized, and split across providers with Hyperswitch’s flexible payment orchestration engine.

[Tokenization and Card Vault →](/integration-guide/workflows/vault)

Securely store and reuse customer payment credentials across processors to reduce friction and improve retention.

[Get Started with Hyperswitch's Vault](https://deepwiki.com/search/how-do-i-setup-the-vault_f3aed139-6118-40aa-a066-55b9b90d6775).

[Routing →](/other-features/payment-orchestration/smart-router)

Control how transactions flow across payment providers with configurable routing logic and fallback options

[Intelligent Routing →](/integration-guide/workflows/intelligent-routing)

Automatically route transactions based on geography, success rate, or cost to maximize authorization rates.

[Smart Retries →](/other-features/payments-modules/revenue-recovery)

Recover failed payments using ML-driven retry strategies optimized for timing, issuer behavior, and card type.

[Payouts →](/other-features/connectors/payouts)

Easily manage and automate disbursements to sellers, vendors, or partners with flexible payout logic.

[Subscriptions →](/other-features/payment-orchestration/subscriptions)

Handle recurring payments seamlessly with built-in support for subscription billing and invoicing.

[Split Payments →](/other-features/connectors/split-payments)

Divide transactions between multiple parties or accounts with precision and control.

</details>

### Improve Your Checkout and Payment Experience

Deliver seamless, flexible, and localized payment flows that drive higher conversion and customer trust.

<details>

<summary><strong>Create Seamless Checkout Experiences That Convert</strong></summary>

[Customizable Checkout SDK (Web) →](https://docs.hyperswitch.io/explore-hyperswitch/merchant-controls/integration-guide/web)\
Embed a native, responsive checkout experience into your website with full control over styling and flow.

[Click to Pay →](https://docs.hyperswitch.io/other-features/click-to-pay)\
Enable frictionless, one-click payments for returning users using wallets and saved cards.

[Payment Methods Management →](https://docs.hyperswitch.io/explore-hyperswitch/payment-flows-and-management/quickstart/payment-methods-setup)\
Dynamically configure and prioritize payment methods based on geography, currency, and user preference.

[Alternate Payment Methods (APMs) →](https://docs.hyperswitch.io/explore-hyperswitch/payment-flows-and-management/quickstart/payment-methods-setup)\
Offer support for UPI, wallets, and local payment options to meet your customers where they are.

[Integration Guide Overview →](https://docs.hyperswitch.io/explore-hyperswitch/merchant-controls/integration-guide)\
Explore the full set of tools and options to deliver a branded and consistent payment experience across platforms.

</details>

### Manage and Monitor Your Payment Operations

Operate at scale with tools to manage accounts, monitor transactions, handle disputes, and apply business rules.

<details>

<summary><strong>Operate and Monitor Your Payment Stack</strong></summary>

[Manage Accounts and Profiles →](https://docs.hyperswitch.io/explore-hyperswitch/account-management/multi-tenancy-with-hyperswitch)\
Create, manage, and operate across multiple merchant accounts and profiles with full multi-tenancy support.

[Analytics and Operations →](https://docs.hyperswitch.io/explore-hyperswitch/account-management/analytics-and-operations)\
Gain real-time visibility into transaction performance, routing behavior, and operational metrics.

[Disputes and Chargebacks →](https://docs.hyperswitch.io/explore-hyperswitch/account-management/disputes)\
Monitor, respond to, and manage disputes or chargebacks from a centralized operations interface.

[Surcharge Management →](https://docs.hyperswitch.io/explore-hyperswitch/account-management/surcharge)\
Apply dynamic surcharges or convenience fees based on card type, geography, or business logic.

[Full Operations Overview →](https://docs.hyperswitch.io/explore-hyperswitch/account-management)\
Explore the complete set of tools available for scaling your payment operations with confidence.

</details>

### Scalability, Relability, and Security

Take your Hyperswitch integration to production with confidence. Set up environments, secure credentials, monitor performance, and scale seamlessly as your business grows.

<details>

<summary><strong>Explore Security, Reliability, and Scalability</strong></summary>

Build with confidence on an architecture designed for compliance, low-latency scaling, and enterprise-grade uptime.

[Security and Compliance →](https://docs.hyperswitch.io/explore-hyperswitch/overview/security)\
Protect sensitive data and meet global compliance standards like PCI DSS with secure-by-default components.

[Latency →](https://docs.hyperswitch.io/learn-more/hyperswitch-architecture/a-payments-switch-with-virtually-zero-overhead)\
Scale effortlessly with a stateless architecture designed to handle high-throughput payment workloads with near-zero overhead.

Here's how [Hyperswitch handles horizontal scaling under high throughput](https://deepwiki.com/search/how-does-hyperswitch-handle-ho_8bba708f-e768-465c-8e24-953f7a60da72#1)

[Reliability →](https://docs.hyperswitch.io/learn-more/hyperswitch-architecture)\
Achieve consistent uptime and resiliency through modular design and built-in fault tolerance.

Here's how [Hyperswitch handles idempotency and message ordering](https://deepwiki.com/search/what-guarantees-does-the-syste_1bc51ad9-d897-4d9a-bce6-7d0a19cf00c4#1).

</details>

### Go Live with Hyperswitch

<details>

<summary>Take Hyperswitch into production</summary>

[How to Go Live with Hyperswitch →](https://docs.hyperswitch.io/self-hosting/production-deployment/going-live)\
Follow our go-live checklist to launch with confidence — covering setup, credentials, security, and monitoring.

</details>

### Need Help?

* [Join our Slack Community →](https://inviter.co/hyperswitch-slack)\
  Ask questions, share ideas, and connect with other developers building on Hyperswitch.
* [Contact Us →](https://hyperswitch.io/contact-us)\
  Prefer direct support? We’re happy to help.

***

### Developer Resources

* [API Reference →](https://api-reference.hyperswitch.io/introduction)
* [SDK Documentation →](https://docs.hyperswitch.io/learn-more/sdk-payment-flows)
* [Postman Collection →](https://docs.hyperswitch.io/self-hosting/hyperswitch-open-source/README#use-postman)
* [GitHub Repository →](https://github.com/juspay/hyperswitch)


# Overview

Hyperswitch: Open-Source Payments Platform by Juspay

[Hyperswitch](https://hyperswitch.io/) is an open-source payments platform from [Juspay](https://juspay.io/us), designed to simplify global payments for digital businesses. Juspay has been a global leader offering payment infrastructure solution for banks and merchants for 12+ years, processing over [300 Mn+ daily transactions](https://juspay.io/newsroom/juspay-secures-usd50-million-investment-from-westbridge-capital) and an annualized total payment value of $1 Tn+

### We offer two distinct solutions

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><mark style="color:blue;"><strong>Payments Suite</strong></mark></td><td>An end-to-end orchestration layer that unifies payments across providers, networks, and channels. It enables seamless checkout, dynamic routing, retries and redundancy for reliability.</td><td><strong>Optimize payments at scale without adding complexity to your infrastructure.</strong></td><td></td><td><a href="/pages/rlBSMgc2rmkDo9zLoCsG">/pages/rlBSMgc2rmkDo9zLoCsG</a></td></tr><tr><td><mark style="color:blue;"><strong>Payment Modules</strong></mark></td><td>A flexible, modular approach to integrate only the payment capabilities you need. Choose from intelligent routing, vault, reconciliation, cost observability, smart retries, and APM widgets.</td><td><strong>Enhance performance without overhauling your existing payment stack.</strong></td><td></td><td><a href="/pages/4HyzL1OGXCvOXBM7m9Ii">/pages/4HyzL1OGXCvOXBM7m9Ii</a></td></tr></tbody></table>

### Enterprise Grade Open Payments Infrastructure

{% embed url="<https://youtu.be/p6vqGHsoc0s?si=b6imHBVzZAcCQ2WB>" %}

At Juspay, we believe that payments infrastructure should be transparent, adaptable, and built for merchant control—not vendor lock-in. That’s why we made the bold decision to take our Payment Orchestrator open source.

Enterprise merchants operate in a world where payment agility is a competitive advantage. Traditional closed-loop platforms dictate their own rules, pricing, and pace of innovation. Based on our 12-years of experience building and scaling global payment systems, we decided to take a different approach, giving merchants the power to customize, optimize, and scale payments to fit their unique business needs.

Guided by the learnings from our enterprise go-lives, we have been working on unbundling a range of stand-alone solutions from our broader technology stack to make them more accessible to merchants looking to expand their in-house system engineering capability. These stand-alone solutions range from services for [intelligent / dynamic payment routing](https://github.com/juspay/decision-engine), [payment methods vaulting](https://github.com/juspay/hyperswitch-card-vault), [cost observability](https://hyperswitch.io/cost-observability), [PSP-agnostic authentication](/integration-guide/workflows/3ds-decision-manager), and an [APMs widget ](/integration-guide/payment-suite/payment-method-card/enable-alternate-payment-method-widgets)that can be embedded anywhere.

<figure><img src="/files/AOMJFFuk5ulEJtQO4TrK" alt=""><figcaption></figcaption></figure>

### Technical Foundation: Open System Architecture with Enterprise-Scale

Hyperswitch's technical architecture combines open source innovation with enterprise-grade reliability, built to power modern payment operations.

#### 1. Open-Source Transparency & Extensibility

* Complete Transparency & Confidence: Full visibility into payment orchestration with no black boxes, enabling informed decision-making and customization. Hyperswitch is maintained publicly on [GitHub](https://github.com/juspay/hyperswitch)
* [Open Roadmap & Innovation](/about-hyperswitch/roadmap-q3-2026/roadmap): Collaborative development approach that allows merchants to influence and contribute to the platform's evolution
* Speed to Market: Accelerate implementation and changes by building consensus faster through transparent architecture

#### 2. Enterprise-Grade Reliability & Security Model

* Built on battle-tested systems by Juspay's 1000+ engineers, the same team that powers 300M+ transactions daily for [global enterprises](https://juspay.io/customer-stories) like Amazon, Agoda, Zurich and many more.
* [Comprehensive security framework](/other-features/security-and-compliance) including PCI compliance, tokenization, and security certifications
* Proven reliability at scale, designed for high-performance payment processing

### [Core System Architecture Principles](https://hyperswitch.io/blog/building-hyperswitch-the-world-s-first-open-source-payments-platform)

<table data-view="cards"><thead><tr><th align="center"></th><th></th></tr></thead><tbody><tr><td align="center"><strong>Reliability</strong></td><td><ul><li>Graceful degradation - Critical path stays intact; non-core flows are optional</li><li>Recover failed transactions through intelligent retry logic</li><li>Strongly typed Rust ensures safety at compile time</li><li>Staggered releases</li></ul></td></tr><tr><td align="center"><strong>Scalability</strong></td><td><ul><li>Horizontal scalable architecture</li><li>Supports peak loads up to ~10K TPS</li><li>Connection pooling</li><li>First class support for K-V mode</li></ul></td></tr><tr><td align="center"><a href="/pages/P26kRLa2c4E3M1QHgf5U"><strong>Performance</strong></a></td><td><ul><li><p>Cache where-ever possible</p><ul><li>Configurations</li><li>Master data</li><li>Multi-level caching</li></ul></li></ul></td></tr><tr><td align="center"><strong>Modularity</strong></td><td><ul><li>Works with an <a href="/pages/SMlOZu1m2PnVsbfcDxLl">external or an in-house Vault</a> or Tokenization service</li><li>Offers <a href="/pages/4HyzL1OGXCvOXBM7m9Ii">standalone products</a></li><li>Integrate with connectors <a href="/pages/zkST1fAZ0DGeIVl8DUsu">beyond Payment Service Providers</a></li></ul></td></tr><tr><td align="center"><a href="/pages/vOxo8T782PExsHVm8PBv"><strong>Security &#x26; Compliance</strong></a></td><td><ul><li>Hyperswitch suite is PCI SSS validated</li><li>Mask at Source</li><li>Isolation and Encryption</li></ul></td></tr><tr><td align="center"><strong>Observability</strong></td><td><ul><li>Business &#x26; Tech metrics</li><li>Point debugging</li><li>Application / Infrastructure alerts with custom pipelines</li><li>Remote monitoring for self-hosted merchants</li></ul></td></tr><tr><td align="center"><strong>Quality &#x26; Maintenance</strong></td><td><ul><li>Strict PR checks</li><li>Automated E2E &#x26; Regression testing</li><li>Clear documentation with <a href="https://github.com/juspay/hyperswitch/releases">release notes</a></li></ul></td></tr></tbody></table>

**Get ready! We welcome you to the future of digital payments!**


# Roadmap – Q3 2026

July'26 to Sep'26

🗺️ Our roadmap typically spans a three-month period. Before the start of every quarter, we come together to define what we'll work on next based on our core values, progress from the previous roadmap, learnings from the past quarter, and feedback from the community.

👂 As always, we continue to listen to your feedback and adapt our plans as needed.

### Core Values

Our core values have remained largely unchanged since the early days:

• Make payments more **accessible** and **affordable** for every digital business.

• Stay **simple** and **lightweight**, while remaining **reliable** and **scalable** as a payment switch.

• Be **community-first** in the ideation, planning, and execution of features.

***

### Roadmap Themes

While there are many problems to solve in payments, our current focus is centered around five key themes.

#### 🧱 Composability

Enable businesses to independently adopt and compose the Hyperswitch modules they need to build a tailored, high-performance payments stack. These modules include payment processing, PCI vaults, intelligent routing, reconciliation, cost observability, revenue recovery, and card-network-certified services such as 3DS and network tokenization.

#### 🌐 Connectedness

Expand the Hyperswitch operating system through broader integrations across payment processors, vaults, payouts, fraud providers, subscription platforms, tokenization services, and more—while continuously improving and maintaining existing integrations.

#### 🎯 Reducing Payment Operations

Managing payments across multiple countries, currencies, and processors should not increase operational complexity. Hyperswitch aims to eliminate this overhead so businesses can focus on their core products and customers.

#### 🛡️ Reliability

Build fault tolerance, capacity resilience, and change tolerance into the payment platform to maximize uptime and confidence in production.

#### 🚀 Developer Experience

Provide a best-in-class self-service and self-hosting experience for developers adopting or contributing to Hyperswitch.

***

## Roadmap

### 🧱 Composability

#### Account Updater

Adding support for Juspay's Account Updater as a modular service that automatically keeps stored card credentials up to date, helping recurring payments succeed without customer intervention.

#### Offers Engine

Introducing a native Offers Engine within Hyperswitch that enables merchants to configure and manage discounts and cashback campaigns directly from the Hyperswitch Control Center.

#### Decoupling Connector Integrations

The connector integration layer is being decoupled into [**hyperswitch-prism**](https://github.com/juspay/hyperswitch-prism)**:** a stateless, embeddable payment integration library with multi-language SDK support.

Today, hyperswitch-prism powers **97 payment connectors** and **5 payout connectors**. During the coming quarter, we will continue expanding payment and payout coverage while adding support for additional connector categories, including:

* Vault connectors
* &#x20;Fraud & Risk Management (FRM) connectors
* Surcharge connectors

#### Intelligent Routing Enhancements

Enhancing the intelligent routing engine with **multi-objective routing** to optimize both authorization rates and payment processing costs. Also adding support for A/B Testing to compare different routing configurations.

#### Vault Service Enhancements

Expanding the Hyperswitch Vault / Payment Method Service with:

* Support for custom tokens
* Enhanced analytics and observability
* Network Tokenization support for External vaults
* Supporting additional request types for Proxy flows

#### Headless Vault SDK

Decoupling the Vault UI from the SDK, enabling teams to build fully customized payment method experiences while leveraging the underlying vault capabilities.

***

### 🌐 Connectedness

#### New Integrations

* TSYS Transit (Cards)
* Givepayments (Cards)

#### Enhancements to Existing Integrations

* Deutsche Bank - Payouts
* TrueLayer - Returning customer flow
* Checkout.com - TLID handling
* dLocal - GCash recurring payments
* Paysafe - Google Pay
* Payload - Payouts
* Payload - Split Payments
* Barclaycard - 3DS Payments
* PayPal - Returning customer flow

[Learn more about the existing connectors supported by Hyperswitch](https://docs.hyperswitch.io/explore-hyperswitch/connectors)

***

### 🎯 Reducing Payment Operations

#### Reconciliation Enhancements

**Improved Cashflow Visibility**

Revamping reconciliation analytics to provide a clearer view of how money moves through every stage of reconciliation. Teams will be able to trace cashflows end-to-end, identify matched, pending, delayed, and mismatched transactions, and investigate exceptions faster.

**Better Control Over Uploaded Data**

Introducing stronger validation and review workflows before reconciliation begins. Merchants will be able to preview uploaded files, inspect potential records and errors, discard incorrect uploads, and resolve issues before processing.

**Revamped User Experience**

Redesigning the reconciliation experience to make day-to-day operations faster and more intuitive, with improved workflows, better exception handling, clearer navigation, and more actionable operational insights.

[Learn more about existing reconciliation features](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/reconciliation)

***

### 🛡️ Reliability & Systems

#### Multi-Region Active-Passive Setup

Conducting production disaster recovery drills across the US and EU regional active-passive deployments to further validate operational readiness and resilience.

#### Automated Regression Testing

Major enhancements to our regression testing framework to replay production traffic against every code change before release, deterministically validating behavior, surfacing precise divergence reports, and giving teams greater confidence that changes won't introduce regressions before they reach production.

***

### 🚀 Developer Experience

#### Agentic Interface for Hyperswitch

Deploying and operating Hyperswitch Enterprise Edition will become significantly easier with a specialized agentic interface for exploring deployments, tracing requests, debugging issues, and analyzing system behavior.

A beta release with **Bring Your Own LLM (BYO-LLM)** support will be available during the quarter.

[Learn more about Revenue Recovery](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/revenue-recovery)

***

### Want to contribute to the roadmap?

Have an idea or feature request?

[Submit it here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests)

When submitting an idea, include a brief explanation of:

• **What** you'd like to see

• **Why** it would be valuable


# Previous Roadmap - Q2 2026

April '26 to June '26

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, previous roadmap, findings over the previous quarter, and what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

#### Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

### Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

There are a lot of problems to be solved in payments, but our majority of our current focus falls under 5 themes below.

🧱 **Composability:** Enabling users to independently augment Juspay Hyperswitch platform modules of choice to create a tailored, high-performance payment stack. Such modules could be payment processors (or) PCI vaults (or) intelligent routing (or) reconciliation, cost observability, revenue recovery, or card network certified services (like 3DS, network tokenization)

🌐 **Connectedness:** Increasing connectedness of the Juspay Hyperswitch operating system into more and more connectors for - Payins, Vaults, Payouts, Fraud, Subscriptions, Tokenization. And also keeping the connections up-to-date.

🎯 **Reducing Payment Operations:** Managing payments across multiple countries, currencies and processors should not add to the administrative burden on businesses. Hence, Hyperswitch intends to eliminate all such operational burdens so that businesses can focus on the core activities.

🛡️ **Reliability:** Building capabilities for Fault, Capacity and Change tolerance into the payment platform.

🚀 **Developer Experience:** Providing a great self-service and self-installation experience for developers who wish to use or contribute back to Hyperswitch.

## Roadmap <a href="#roadmap" id="roadmap"></a>

### Composability

**Decoupling the Connectors**: The connector integrations layer for payments will be decoupled into a stateless, embeddable payment integration library with multi-language SDK support. This will be done for payment connectors and further extended to payout connectors and vault connectors in the future.

**Compatibility with Cashier Platforms for Gaming and Gambling businesses**: The payment platform will be enhanced with more events to improve composability with cashier platforms used by gaming and gambling businesses. This is to support regulatory-level compliance and configurability - payment method blocking, user notification for responsible gambling, deposit amount controls.

**Enhancements to Platform and Connected merchants:** The Platform and Connected merchants setup will be enhanced with more feature modules - profile acquirer, async operations (process tracker), external vault, external authentication, card blocking, surcharge, Apple Pay merchant registration, analytics and relay.

**Enhancements to External Vault**: External vault support for VGS will be extended to the Hyperswitch native SDKs.

**Enhancements to Intelligent routing module:** Enhancement with a dashboard to visualize the module performance and uplift.

### Connectedness

**New Integrations**

* EFT Debit Order: Support for bank debit payment method popular in South Africa for recurring collections.
* iMerchant Solutions: Payment processor with full payment + webhook flow. Supports retrieving webhook reference IDs for async payment tracking.
* Santander: Pix Automatico (Brazil's recurring Pix payments) with push notifications, QR code generation, CIT, MIT, and webhook flows.
* Interpayments for surcharging

**Enhancements to Existing Connectors**

* ACI: Apple Pay and Google Pay wallet support
* Worldpay XML: Apple Pay pre-decrypted flow
* Stripe: Google Pay pre-decrypted flow
* Finix: Support for external 3DS
* Peach Payments: COF Data for CardWithLimitedDetails CIT and No-3DS Cards CIT
* Checkout: Network token payment support for CIT and MIT NTID support
* Stripe: on\_behalf\_of support for Stripe Connect split payments
* Loonio: Manual capture support
* Gigadat: Manual capture support

[Learn more about the existing connectors supported in Hyperswitch here.](https://docs.hyperswitch.io/explore-hyperswitch/connectors)

### Reducing payment operations

**Reconciliation Enhancements**:

* **Tolerance Rules** support to reduce manual effort and improve operational visibility. Merchants can define variance thresholds for automatic reconciliation, with any residual differences routed to a dedicated tolerance account for tracking and auditability.
* **Aging** provides visibility into unmatched transactions and enables configurable time-based thresholds to proactively identify stale items.
* **Manual corrections** will enable merchants to fix recon mismatches with an audit trail.
* **SFTP support** for fetching settlement files for Adyen, Amex

[Learn more about the existing Reconciliation features and workflows here](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/reconciliation).

### Reliability & Systems

**Multi-Region Active Passive Setup**: Production environment drills will be conducted on the active-passive setup for the US and EU regional stacks.

**Configuration Management**: Juspay Hyperswitch will adopt a context-based configuration management system to facilitate safe and flexible rollout of config changes. Configurations on the platform will be made more granular for merchants to control at a profile, merchant and organization level through adoption.

### Developer Experience

**Agentic interface for juspay hyperswitch**: Deploying and running Juspay hyperswitch Enterprise Edition is bound to become easier with a Specialized Agentic Interface to explore, trace, analyse. We will be launching a beta version supporting Bring-your-own-LLM support.

[Learn more about the existing Revenue Recovery features and workflows here.](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/revenue-recovery)

**Want to contribute to the roadmap?**

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous Roadmap - Q1 2026

Jan '26 to March '26

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, previous roadmap, findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

#### Recap of Q4 2025 <a href="#recap-of-q2-2024" id="recap-of-q2-2024"></a>

**Connectors**

* **New PSP integrations** – Gigadat and Loonio for Interac e Transfer; Tesouro for Cards, Apple Pay, and Google Pay; Paysafe for Cards, Apple Pay, Skrill, Interac e Transfer, and Paysafecards; Finix for Cards, Apple Pay, and Google Pay
* **Integration depth** – Expanded wallet and alternative rail coverage across new connectors, adding broader support for Apple Pay and Google Pay, plus regional payment rails like Interac e Transfer, and additional tender types like Skrill and Paysafecards through Paysafe

**Core orchestration**

* **Platform Merchants support:** Support for Platform merchant use-cases to share customers and payment methods across their managed-merchants
* **Split Payments:** Support for split payments with gift cards to enable combined payments within a single transaction
* **Error code enhancements** – Issuer error codes added to the Gateway Status Mapping table to improve response mapping and retry decisions; unified error codes expanded to generate clearer, consistent user facing error messages across channels
* **Real time payment method eligibility** – Merchant level risk based eligibility checkpoints added before payment confirmation to reduce fraud exposure and improve authorization performance

**Vault**

* **Guest checkout tokenization** – Token creation without customer creation in Hyperswitch, enabling secure and PCI compliant handling of guest one time and repeat transactions, with flexibility to map tokens to merchant owned identifiers
* **Volatile tokenization** – Support for time bound temporary tokens for PAN and network token flows, enabling secure session based authorizations and one time payment experiences without long term vault storage

**Revenue recovery** Account Updater to automatically refresh stored card credentials for expired, replaced, or reissued cards, improving continuity for stored payment methods and recovering failures tied to outdated card data

**Core Values**

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

#### Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

Last year, Hyperswitch was made more modular to provide businesses with focused solutions to specific payment-related problems. Hence, our roadmap includes updates for each module. A summary of these product modules is provided below :

1. **Orchestration:** The core module supporting workflows unifying various connector
2. **Vault:** Simplifying PCI compliance and data privacy regulations through a standalone Card Vault
3. **Authentication:** Data driven 3DS routing decision system and unified authentication SDK to encompass the diversity of authentication products.
4. **Revenue Recovery:** A payment recovery sub-system with a customizable retry engine that reduces passive churn to recover failed subscription payments.
5. **Reconciliation:** Improving Finops efficiency in multi-acquirer settlement reconciliation.
6. **Cost Observability:** Tracking and reducing payment processing costs via PSP reports.

### Roadmap <a href="#roadmap" id="roadmap"></a>

**Core Orchestration**

**Platform Managed Payments**

We plan to introduce platform capabilities that allow platforms to trigger and manage key payment operations on behalf of their managed merchants. This will include Payments, Refunds, Webhooks, and Disputes.

**Recurring Payments Expansion**

We plan to expand recurring payment capabilities across cards and bank-based methods, and improve lifecycle handling for recurring flows. This will include support for storing payment credentials and enabling recurring payments across ACH and other APMs, enabling PSP triggered recurring payments with lifecycle handling and reconciliation support, and supporting recurring payment flows using only card PAN and expiry without requiring Network Tokenization (NTI).

**Retry Enhancements to Improve Authorization Rates**

We plan to enhance retry tooling across APMs and merchant-initiated flows to help improve approval rates and reduce avoidable drop-offs. This will include automatic retries support for Google Pay and other APMs, support for manual retries in MIT flows, and support for merchants to configure retry rules for different error codes.

**Relay for Post Payment Actions**

We plan to enable Hyperswitch to act as a relay to orchestrate incremental and post payment actions on the original order across PSPs. This will support workflows such as incremental authorization, capture, refund, void, and churn recovery.

**Instalments**

We plan to support installment-based payments across supported payment methods, enabling merchants to offer flexible payment options without changing their orchestration setup.

**Connectors**

**New Integrations**

We plan to expand connector coverage with new PSP integrations including Banco Do Brasil, Cielo, Caixa, Bradesco, Bancoob, Worldpay Access Modular, and HyperPG.

**Enhancing Existing Integrations**

We also plan to enhance existing integrations to expand payment method coverage and improve reliability. This will include Payload (ACH), Itau Bank (Pix, Boleto), Stripe Connect (Apple Pay, Google Pay), Dwolla (ACH recurring), Worldpay WPG (3DS cards with fraud ID), Xendit (QRIS), and Deutsche Bank.

[Learn more about the existing Connectors supported in Hyperswitch here.](https://docs.hyperswitch.io/explore-hyperswitch/connectors)

#### Vault <a href="#vault" id="vault"></a>

**Multi Vault Support**

We plan to expand Vault capabilities to enable seamless use of both Juspay-hosted and external vaults across self-hosted and SaaS Hyperswitch deployments.

**Alt ID Network Tokenization for Guest Checkout**

We plan to enable alternate identifier-based flows for network tokenization in guest checkout scenarios, allowing tokenization without requiring full customer creation.

**Extended Proxy API Payload Support**

We plan to extend Proxy APIs to support non-JSON request formats such as application/x-www-form-urlencoded, XML, and other upstream formats, to improve compatibility with legacy gateway patterns.

**Custom Token Formats**

We plan to support configurable and merchant-defined token formats across Vault and payment flows, giving merchants more control over token design and interoperability.

**Vault Observability and Auditability**

We plan to add analytics, audit trails, and observability capabilities for the Vault service, improving traceability, governance, and operational debugging.

[Learn more about the existing Vault Services and workflows here.](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/vault)

#### Authentication and Checkout Experience <a href="#authentication-and-checkout-experience" id="authentication-and-checkout-experience"></a>

**SDK Accessibility Enhancements**

We are enhancing the checkout SDK to ensure accessibility compliance and inclusivity for all users. Updates will include improved keyboard navigation, screen reader support, and visual contrast adjustments aligned with WCAG accessibility standards.

**Framework Compatibility Upgrades**

We plan to add compatibility upgrades across Web and Native experiences. This will include support for React 19 for Web and support for React Native's new architecture for Native.

**Swift Package Manager Migration (iOS)**

We plan to migrate iOS integration to Swift Package Manager to consolidate all frameworks into a unified and modular package with clear dependency boundaries. This will replace CocoaPods for simpler merchant integration and cleaner versioning.

**Optional OTA Support for SDKs**

We plan to introduce optional OTA (Airborne) support for Hyperswitch SDKs. Merchants will be able to opt into Hyperswitch-managed updates, approval-gated releases, self-hosted OTA, or fully disable OTA based on governance, compliance, and risk requirements.

**Apple Pay Beyond Safari**

We plan to enable Apple Pay support across non-Safari browsers where supported, improving reach and checkout conversion without changing existing integrations.

**Subscription Based SDK Events**

We plan to enable subscription-based events across SDK flows, allowing merchants to subscribe to granular lifecycle signals for real time decisioning, observability, and tighter integration with merchant systems. Examples include BIN, field validation outcomes, and button clicks.

**Custom In SDK Messaging**

We plan to support custom in SDK messaging so merchants can configure and display contextual messages (info, warnings, errors, compliance text) within the Hyperswitch SDK UI, with an optional fallback to default SDK messaging for a consistent user experience.

[Learn more about the existing Authentication and Checkout Experience capabilities here.](https://docs.hyperswitch.io/explore-hyperswitch/merchant-controls)

#### Revenue Recovery <a href="#revenue-recovery" id="revenue-recovery"></a>

**Advanced Retry Logic for Hard Declines**

We plan to introduce smarter recovery for hard declines, where the system identifies transactions that were falsely marked as hard declines and retries them intelligently.

**Recovery Analytics in the Dashboard**

We plan to add analytics that provide merchants with real-time visibility into recovery performance through the dashboard.

**Hosted Recovery with Self-Hosted Orchestration**

We plan to support using self-hosted orchestration with Juspay-hosted revenue recovery, enabling merchants to adopt recovery improvements without changing their orchestration deployment model.

[Learn more about the existing Revenue Recovery features and workflows here.](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/revenue-recovery)

#### Reconciliation <a href="#reconciliation" id="reconciliation"></a>

**Tolerance & Aging**

We are enhancing reconciliation with **Tolerance Rules** and **Aging** to reduce manual effort and improve operational visibility. Merchants can define variance thresholds for automatic reconciliation, with any residual differences routed to a dedicated tolerance account for tracking and auditability.

Aging provides visibility into unmatched transactions and enables configurable time-based thresholds to proactively identify stale items. We plan to provide visibility into transactions awaiting a match and allow time-based threshold monitoring to help teams track stale reconciliation items.

[Learn more about the existing Reconciliation features and workflows here](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/reconciliation).

#### Control Centre <a href="#control-centre" id="control-centre"></a>

**Developer Observability & Self-Service Diagnostics**

We plan to expose real-time technical metrics and system health insights for platforms, enabling faster self-diagnosis and reducing dependency on support.

**Contextual Alerts & Configurable Automation**

We plan to add a configurable, multi-merchant alerting system to detect PSP downtimes, error spikes, and emerging failure patterns.

**Embeddable Components**

We plan to introduce widgets for payment configuration and operations that can be integrated directly into platform dashboards. This will enable platforms to manage payments, connector integrations, and refunds within their own dashboard experience.

**Theme Management UI**

We are building a self-serve Theme Management UI that allows merchants to configure and manage dashboard and email branding across **Organization, Merchant, and Profile** levels. Merchants can customize brand colors, sidebar styles, buttons, logos, favicons, and email branding, with a **live preview** to instantly visualize changes before applying them.

Themes follow a clear precedence model (**Profile → Merchant → Organization**), enabling flexible overrides without duplication. Organizations can define a base theme, merchants can override it for distinct brands, and profiles can further customize when needed—ensuring consistent yet scalable branding across complex setup

**Want to contribute to the roadmap?**

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.

Last updated 1 month ago

**Compliance**

* [Vulnerability Disclosure](https://hyperswitch.io/vulnerability-disclosure-policy)
* [PCI DSS 4.0](https://hyperswitch.io/pci.pdf)
* [ISO 27001:2022](https://hyperswitch.io/uaf.pdf)

**Community**

* [Slack](https://inviter.co/hyperswitch-slack)
* [GitHub Discussion](https://github.com/juspay/hyperswitch/discussions)


# Previous Roadmap - Q4 2025

Oct '25 to Dec '25

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, previous roadmap, findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

### Recap of Q3 2025 <a href="#recap-of-q2-2024" id="recap-of-q2-2024"></a>

* **Connectors**
  * **New PSP integrations** - Worldpay Vantiv, Payload, Dwolla, Bluecode, Checkbook, Trust Payments, Nordea, and Silverflow
  * **Integration enhancements** - Multisafe, Airwallex, Braintree, and Fiserv
  * **New category of integration** - Support for subscription management providers to augment the plan management and record-keeping capabilities of the subscription engine with payment orchestration
  * **Feature depth** - L2/L3 data standardization across PSPs, support merchant decryption and decrypted payload for Apple Pay and Google Pay, return MAC codes in API response, chargeback support for PSPs with no webhook support, and MIT category fields
* **Core orchestration** - Support for over-capture, extended authorization, and manual/user-triggered retries
* **Standalone Network Tokenization** Service with support for Visa, Mastercard, and Amex\
  Standalone EMVCo-certified Juspay 3DS Server and 3DS SDK
* **Revenue recovery** - New capabilities to handle partial capture, support in-house billing engines, invoice queuing or grouping of all pending invoices, hard decline smart retry
* **Intelligent routing** analytics added to offer real-time insights into transaction flow and gateway performance
* **Reconciliation** - New capabilities to support transaction-level audit logs to ensure every transaction can be traced from initiation to settlement, strengthening compliance and operational accountability
* **Cost observability** - New capabilities to accurately derive fee names from fragmented or ambiguous reports, fee rates and attribute costs, advanced fee auditing capabilities, estimate expected interchange and scheme fees per transaction and reconcile them against actual applied rates, conversational AI interface, and expanded acquirer coverage: adding support for five or more new acquirer report formats (AIBMS, Elavon, PayPal, Stripe, and Amex)
* **Control Centre** - Support for platform org and merchant to allow programmatic API-driven merchant account creation, management, and configuration

#### Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

### Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

Earlier this year, Hyperswitch was made more modular to provide businesses with focused solutions to specific payment-related problems. Hence, our roadmap, starting this quarter, will be published under each module. A summary of the 8 product modules is provided below :

1. **Core Orchestration:** The core module supporting workflows unifying various connector
2. **Vault:** Simplifying PCI compliance and data privacy regulations through a standalone Card Vault
3. **Cost Observability:** Tracking and reducing payment processing costs via PSP reports.
4. **Authentication:** Data driven 3DS routing decision system and unified authentication SDK to encompass the diversity of authentication products.
5. ​​**Alternate Payment Method Widgets:** Embracing the ever expanding diversity of payment methods and payment experiences through orchestration, and a simple add-on button to Checkout.
6. **Revenue Recovery:** A payment recovery sub-system with a customizable retry engine that reduces passive churn to recover failed subscription payments.
7. **Reconciliation:** Improving Finops efficiency in multi-acquirer settlement reconciliation.

## Roadmap <a href="#roadmap" id="roadmap"></a>

#### **Core Orchestration and Connectors**

* **Connectors**\
  We plan to expand connector coverage with new integrations including
  * **New integrations:** Gigadat (Interac e-transfer), Loonio (Interac e-transfer), Tesouro (Cards,Applepay,Googlepay), Paysafe (Cards, Applepay, Skrill, Interac e-transfer, Paysafecards), Finix (Cards, Applepay, Googlepay)
* **Core Orchestration**
  * We plan to introduce split-payment support for gift cards, enabling combined payments within a single transaction for greater flexibility across customer use cases.
* **Improve Auth rate**
  * **Error Code Enhancements**

    We plan to enhance our error-handling framework to improve visibility and precision in transaction outcomes.

    * **Issuer Error Codes in GSM Table**: Issuer-specific error codes will be added to the GSM (Gateway Status Mapping) table to improve accuracy in mapping responses. These will be leveraged to make better retry decisions during payment flows, helping merchants reduce unnecessary retries and improve approval rates.

      **Unified Error Codes and User-Facing Messages**: We will expand the existing unified error code system to generate clearer, user-focused error messages. This ensures consistency in how payment failures are communicated across channels, improving transparency for both merchants and end users.
* **Real-Time Payment Method Eligibility Checks**

  We plan to introduce real-time eligibility validation for payment methods during checkout. This will include:

  * **Risk-Based Eligibility Checkpoints**: Adding merchant-level risk evaluation before payment confirmation. This will allow merchants to assess potential transaction risks in real time, reducing fraud exposure and improving overall authorization performance.

*<mark style="color:blue;">Learn more about the existing Core Orchestration and Connectors features and workflows</mark>* [*<mark style="color:blue;">here</mark>*](/other-features/connectors)

#### **Vault**

* **Guest Checkout Tokenization in Hyperswitch Vault**

  We plan to extend our vault capabilities to support guest checkout tokenization. This will allow merchants to create tokens without generating a customer ID in Hyperswitch, enabling secure and PCI-compliant handling of one-time or repeat transactions. Merchants will also have the flexibility to map these tokens to their own unique identifiers as needed.
* **Volatile Tokenization for PAN and Network Tokens**

  We plan to add support for volatile tokenization, allowing merchants to generate temporary tokens valid for a limited time. This will be particularly useful for transient payment flows such as session-based authorizations or one-time payments, providing enhanced flexibility and security without long-term storage in the vault.
* **Proxy API for Vault-Only Integrations**

  We are expanding the Proxy API to support merchants who choose to integrate solely with Hyperswitch Vault services. This will allow merchants to pass a card token in their requests, which Hyperswitch will substitute with the actual card details before routing the call to the target connector.

*<mark style="color:blue;">Learn more about the existing Vault Services and workflows</mark>* [*<mark style="color:blue;">here</mark>*](https://docs.hyperswitch.io/about-hyperswitch/payments-modules/vault)

#### **Authentication and Checkout Experience**

* **Authorization Uplift**

  We are introducing a set of enhancements aimed at improving authorization success rates and overall checkout reliability. These features are designed to create a more adaptive, resilient, and insight-driven payment experience:

#### **Revenue Recovery**

* **Advanced retry logic for Hard declines**\
  The system intelligently identifies and retries transactions that were falsely marked as hard declines. This feature aims to recover transactions that were previously considered unrecoverable. Merchants will be able to manage these retries by setting a configurable budget that limits the number retry attempts.
* **Account Updater:**\
  The system will automatically refresh stored card credentials when a customer’s card information changes. This capability ensures continuity in payment processing by updating expired, replaced, or reissued cards in real time. As a result, payment failures caused by expired, closed, or lost/stolen cards can be effectively recovered.

*<mark style="color:blue;">Learn more about the existing Revenue Recovery features and workflows</mark>* [*<mark style="color:blue;">here</mark>*](/other-features/payments-modules/revenue-recovery)

#### **Reconciliation**

* **Rule Types Expansion**\
  Support for 1:many and many:1 rule types to enable flexible matching across split, aggregated, and multi-attempt transaction flows
* **Support for Lumpsum Reconciliation**\
  Enables matching aggregated payouts or bulk settlement files against multiple underlying transactions. This helps reconcile scenarios where processors or banks provide only a consolidated amount, allowing the system to auto-distribute, validate, and highlight variances at both the lump and individual transaction level

**Want to contribute to the roadmap?**

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous Roadmap - Q3 2025

Jul '25 to Sep '25

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, previous roadmap, findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

#### Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

### Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

Earlier this year, Hyperswitch was made more modular to provide businesses with focused solutions to specific payment-related problems. Hence, our roadmap, starting this quarter, will be published under each module. A summary of the 8 product modules is provided below :

1. **Core Orchestration:** The core module supporting workflows unifying various connector
2. **Vault:** Simplifying PCI compliance and data privacy regulations through a standalone Card Vault
3. **Cost Observability:** Tracking and reducing payment processing costs via PSP reports.
4. **Authentication:** Data driven 3DS routing decision system and unified authentication SDK to encompass the diversity of authentication products.
5. **Intelligent Routing:** Routing service to dynamically select the most optimal PSP/ network in real time exploring/exploiting/managing multiple objectives simultaneously.
6. ​​**Alternate Payment Method Widgets:** Embracing the ever expanding diversity of payment methods and payment experiences through orchestration, and a simple add-on button to Checkout.
7. **Revenue Recovery:** A payment recovery sub-system with a customizable retry engine that reduces passive churn to recover failed subscription payments.
8. **Reconciliation:** Improving Finops efficiency in multi-acquirer settlement reconciliation.

## Roadmap <a href="#roadmap" id="roadmap"></a>

### **Core Orchestration**

* Expand Hyperswitch with new payment connector integrations including Worldpay Vantiv, Payload, Dwolla, Bluecode, Checkbook.io, Trust Payments, Nordea, and Silverflow
* Extend support for additional payment methods across existing integrations such as Multisafe, Airwallex, Braintree, and Fiserv
* Introduce split payment support across - Gift cards, Long-term lending/leasing providers
* File exchange based integration for payment method verification, payment processing and settlement instructions
* Asynchronous chargeback handling for connectors without webhook support
* L2 and L3 card data enablement across key acquirers

### **Vault**

* Standalone Network Tokenization service for SaaS merchants

### **Authentication**

* Improve authentication rates and user experience with EMVCo certified Juspay 3DS Server and Juspay 3DS SDK
* Authentication Observability to provide analytics and insights to merchants with tightly coupled Acquirer 3DS for better authentication and authorization results.

### **Revenue Recovery**

* Open-source revenue recovery: Merchants will be able to self-deploy Hyperswitch's integrations and intelligence services onto their own stack
* Multi-card retries: The system will intelligently utilize payment methods already present with the customer to perform retries on a given invoice
* Intelligent invoice retrying: Automatically retries invoices declined due to hard decline error codes, within the retry budget specified by the merchant
* Custom subscription support: Enables integration with the merchant’s in-house subscription management platform to recover failed payments

### **Intelligent Routing**

* Audit Trail and observability dashboard: Allows monitoring of performance across various routing modules
* Extension of Least Cost Routing to wallet payments: Includes Apple Pay and Google Pay

### **Cost Observability**

* Smarter Fee Attribution Engine: Enhancing our system’s ability to accurately derive fee names from fragmented or ambiguous reports, fee rates and attribute costs across key dimensions such as card variants, acquirers, and funding sources
* Conversational AI Interface: Introducing an intuitive, AI-powered chat experience that allows users to explore their payment processing fees through a rich, context-aware interface, making cost observability more interactive, insightful, and user-friendly
* Expanded Acquirer Coverage: Adding support for five or more new acquirer report formats, enabling broader compatibility and faster onboarding for merchants working with a variety of providers

### Reconciliation

* N‑way ingestion & transformation: implement backend‑configured pipelines for any mix of OMS, PSP and bank asources to define normalization and transformation rules
* Reconciliation summary views: display real‑time n‑way match rates, exception counts and trend charts in dashboard widgets, with click‑through to transaction‑ vs. entry‑level drill‑downs and one‑click resolution actions.
* Transaction‑level audit logs: capture every transaction event in full detail with immutable records to ensure no information is lost
* Custom export & reporting: enable merchants to generate and download tailored reconciliation reports
* Adyen integration & auto‑fetch: provide a one‑click Adyen connector that securely pulls transactions on a schedule, auto‑maps fields and normalizes into your unified schema

**Want to contribute to the roadmap?**

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous Roadmap - Q2 2025

Hyperswitch roadmap (Apr to Jun'25)

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, previous roadmap, findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

### Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

### Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

Earlier this year, Hyperswitch was made more modular to provide businesses with focused solutions to specific payment-related problems. Hence, our roadmap, starting this quarter, will be published under each module. A summary of the 8 product modules is provided below :

1. **Vault:** Simplifying PCI compliance and data privacy regulations through a standalone Card Vault
2. **Cost Observability:** Tracking and reducing payment processing costs via PSP reports.
3. **Authentication:** Data driven 3DS routing decision system and unified authentication SDK to encompass the diversity of authentication products.
4. **Intelligent Routing:** Routing service to dynamically select the most optimal PSP/ network in real time exploring/exploiting/managing multiple objectives simultaneously.
5. ​​**Alternate Payment Method Widgets:** Embracing the ever expanding diversity of payment methods and payment experiences through orchestration, and a simple add-on button to Checkout.
6. **Orchestration:** The core module supporting workflows unifying various connector
7. **Revenue Recovery:** A payment recovery sub-system with a customizable retry engine that reduces passive churn to recover failed subscription payments.
8. **Reconciliation:** Improving Finops efficiency in multi-acquirer settlement reconciliation.

### Roadmap <a href="#roadmap" id="roadmap"></a>

#### Vault <a href="#modular-and-composable-payments" id="modular-and-composable-payments"></a>

* Make Hyperswitch interoperable with any third party card vault.
* Merchants self-hosting Hyperswitch stack will be able to outsource PCI compliance as a managed service to Hyperswitch managed card vault, or other third party card vaults.
* Single-use PCI token generation for guest checkout use cases.

#### Authentication <a href="#modular-and-composable-payments" id="modular-and-composable-payments"></a>

* 3DS Intelligence engine to provide 3DS step-up/ step-down decisions, to optimize for (i) Authentication success rate, and (ii) Overall transaction success rate
* Enhanced Authentication Analytics to deeply understand the cardholder’s authentication journey, 3DS failures, 3DS performance, etc. across issuers, markets, and 20+ other payment dimensions.

#### Revenue Recovery <a href="#modular-and-composable-payments" id="modular-and-composable-payments"></a>

* Support rule-based as well as intelligent retries

#### Intelligent Routing <a href="#modular-and-composable-payments" id="modular-and-composable-payments"></a>

* Making decision-engine a standalone offering to enable merchants to use it along side any payment authorization system (vendor agnostic).
* Multi-objective routing system to allow (i) Auth Rate Uplift (already available), and (ii) Cost Optimization through Debit routing (to be added)

#### Cost Observability <a href="#modular-and-composable-payments" id="modular-and-composable-payments"></a>

* Solve the data challenges across PSPs fee report formats. For example, achieve standardisation across PSP fee names and field names by building standard mapper that can scale for multiple PSPs
* Capability to display aggregated fee data in reports, including chargebacks, refunds, and backdated adjustments.

#### Core Orchestration <a href="#modular-and-composable-payments" id="modular-and-composable-payments"></a>

* Connector integrations - Facilitapay, Global Payments, Tranzilla, Paytm, Razorpay

#### **Want to contribute to the roadmap?** <a href="#want-to-contribute-to-the-roadmap" id="want-to-contribute-to-the-roadmap"></a>

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous Roadmap - Q1 2025

Jan'25 - Mar'25

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, previous roadmap, findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

### Recap of Q4 2024 <a href="#recap-of-q2-2024" id="recap-of-q2-2024"></a>

* [Dynamic Tax updater for express checkout wallets (Paypal, Applepay, Googlepay and Klarna) using Taxjar](https://docs.hyperswitch.io/explore-hyperswitch/e-commerce-platform-plugins/automatic-tax-calculation-for-express-checkout-wallets)
* [Smart retries extended to 7 more PSPs: Adyen, Worldpay, Braintree, Deutsche Bank, Novalnet, Fiuu and Nexi Xpay](https://docs.hyperswitch.io/explore-hyperswitch/payment-flows-and-management/smart-retries)
* Implementation of MPAN (merchant tokens) flow for Applepay recurring payments
* [Enablement of guest checkout flow with Click to Pay](https://docs.hyperswitch.io/explore-hyperswitch/merchant-controls/click-to-pay#easier-and-customizable-integration)
* [Pass through Split payments through Stripe Connect and Adyen Platforms](https://docs.hyperswitch.io/explore-hyperswitch/payment-flows-and-management/split-payments)
* [New connector and payment method integrations](https://hyperswitch.io/pm-list)
  * Nexixpay (Cards)
  * Fiuu (Duitnow QR, Apple Pay, Google Pay)
  * Cybersource (Paze Wallet, Samsung Pay)
  * Bankofamerica (Samsung Pay)
  * Novalnet (Paypal, Google Pay)
  * Paypal Vaulting (via Cards and Paypal Wallet)
  * Adyen (Paze Wallet)
  * Elavon (Cards)
  * Klarna Kustom Checkout
  * JPMorgan (Cards)
  * Deutsche Bank(Cards 3DS)
* Data reporting at an organization, merchant and profile level for easier reconciliation
* Enhancements in analytics module for Refunds, Disputes and Smart Retries
* [Support for migration of Network Tokens for business continuity](https://docs.hyperswitch.io/explore-hyperswitch/account-management/data-migration/import-data-to-hyperswitch)

### Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

### Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

There are a lot of problems to be solved in payments, but our majority of our current focus falls under 5 themes below.

🌎 **Community Feature Requests:** Most of our community feature requests falls under one of the above themes, but we still keep this as a separate theme, because we intend to actively explore new problem statements and themes from the community before scheduling actual feature work.

👨‍💻 **Developer Experience:** Providing a great self-service and self-installation experience for developers who wish to use or contribute back to Hyperswitch.

💰 **Reducing Payment Costs:** Payments should be like a free utility for digital businesses. Any business should be able reduce payment processing costs by embracing the diversity in payments.

📈 **Improving Authorization Rates:** Ensuring a best-in-class payment experience and access to latest innovations in the payments ecosystem for all businesses.

👍 **Reducing Payment Operations:** Managing payments across multiple countries, currencies and processors should not add to the administrative burden on businesses. Hence, Hyperswitch intends to eliminate all such operational burdens so that businesses can focus on the core activities.

| **Legend** | **Description**     |
| ---------- | ------------------- |
| 🟩         | Feature completed   |
| 🟧         | Feature in progress |
| 🟥         | Work not started    |
| 💪         | Stretch target      |
| 🚛         | Backlog feature     |

### Roadmap <a href="#roadmap" id="roadmap"></a>

#### Modular and Composable Payments <a href="#modular-and-composable-payments" id="modular-and-composable-payments"></a>

In Q1’25, Hyperswitch will be offering the following composable services as standalone modules on Hyperswitch SaaS version. This activity would be the major focus for the team and each of these modules address one or more of the above roadmap themes

* 🟧 **Payment Methods Service (includes Vault):** Merchants will be able use the standalone Payment methods service to do various levels of tokenization \[PCI tokenization, Network tokenization, PSP tokenization - one-time/multi-use]. PCI compliant merchants will be able to leverage server-to-server flow for tokenization. *(Larger-scope initiative extending into Q2)*
* 🟧 **Reconciliation Service:** Reconciliation module will have an upgraded user experience; and allow FinOps teams to use the module independently without having to use Hyperswitch as the transaction processing technology *(Larger-scope initiative extending into Q2)*
* 🟧 **Cost observability service:** For merchants on interchange+ pricing, HyperSense will ingest their PSP invoices and reports to present the cost - trends, drill-downs, auto RCAs for any anomalies and audit of the report *(Larger-scope initiative extending into Q2)*
* 🟧 **Churn Recovery Service:** For merchants with recurring payment use cases and working with an external subscription engine, Churn recovery service will get notified about all recurring transactions and retry those transactions that have failed *(Larger-scope initiative extending into Q2)*

#### Community Feature Requests <a href="#community-feature-requests" id="community-feature-requests"></a>

* New integrations
  * 🟩 Deutsche Bank for card payments
  * 🟩 Redsys
  * 🟩 Inespay
  * 🟩 Xendit
  * 🟧 Amazon Pay *(moved to Q2)*
* 🟥 Scan Card Feature for MWeb *(moved to Q2)*

#### Improving Authorization Rates <a href="#improving-authorization-rates" id="improving-authorization-rates"></a>

* 🟧 **Intelligent Routing:** Intelligent Routing module tracks the auth rates of various processor in realtime at a granular level to select the most optimal processor to boost conversions
  * 🟥 **Outages and acute failures:** Provides a failsafe system that proactively identifies incidents and holds off traffic to processors that are facing temporary downtimes or failures *(Larger-scope initiative extending into Q2)*
  * 🟥 **Volume Commitments:** Helps select the appropriate PSP for getting volume tier benefits from the processor by routing sufficient payments volume to necessary processors in accordance with their SLA or contracts *(Larger-scope initiative extending into Q2)*
* **🟧 Churn Recovery Service:** For all merchants with recurring payment use cases and working with an external subscription engine, Churn recovery service will get notified about all recurring txns and retry only those transactions that have failed *(Larger-scope initiative extending into Q2)*
  * 🟩 **Split retries -** Merchants will be able to split retries between their subscription engine and the Passive retry service
  * 🟩 **Single PSP -** The Churn Recovery service will interact with only a single PSP for a transaction
  * 🟩 **Basic Retry logic -** The Churn Recovery service will have a very basic error code & region based logic to retry transactions
* 🟧 Secure Card on File (SCOF) with Passkeys - For Mastercard cards, provide Biometric authentication to the customers *(extending to Q2)*
* 🟧 **One time tokenization:** During CIT payments, merchants will be able to do collect, validate and do one-time tokenization of cards & other PMs and use these one-time tokens later in the checkout flow once the customer confirms their purchase *(extending to Q2)*
* 🟩 Smart retry enhancements using Clear PAN as fallback for Network Tokens/ Gateway tokens to improve auth rates
* 🟩 More payment authorization workflows - Estimated auth and Over-capture

#### Reducing Payments Cost <a href="#reducing-payments-cost" id="reducing-payments-cost"></a>

* **🟧** PINless Debit routing - enable cost savings through regulated/ unregulated transactions in US *(extending to Q2)*

#### Reducing Payment Operations <a href="#reducing-payment-operations" id="reducing-payment-operations"></a>

* **🟧 Revamped Recon module** to support self exploration with transaction source agnostic recon and 2-way or 3-way level capabilities *(Larger-scope initiative extending into Q2)*
* **🟧 Cost observability service:** For merchants on interchange+ pricing, HyperSense will ingest their PSP invoices and reports to present the cost - trends, drill-downs, auto RCAs for any anomalies and audit of the report *(Larger-scope initiative extending into Q2)*
* 🟩 Data reporting on an organisation, merchant and profile level for easier reconciliation

#### Developer Experience <a href="#developer-experience" id="developer-experience"></a>

* 🟧 Enhancing Hyperswitch's self-deployment process to be even more seamless and self-serve, enabling merchants to deploy a fully compliant payments stack independently *(Larger-scope initiative extending into Q2)*
* 🟧 Revamped connector <> payment method matrix view *(extending to Q2)*

#### **Want to contribute to the roadmap?** <a href="#want-to-contribute-to-the-roadmap" id="want-to-contribute-to-the-roadmap"></a>

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous Roadmap - Q4 2024

Hyperswitch roadmap (Oct to Dec'24)

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, previous roadmap, findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

### Recap of Q3 2024 <a href="#recap-of-q2-2024" id="recap-of-q2-2024"></a>

* Hyperswitch is now PCI Software Security Standard (S3) certified
* Network Tokenization capability with Visa, Master and Amex card networks. This shall enable merchant to use network tokens to improve auth rates for one-time/ recurring payments and reduce the interchange fee
* Payment Method Management experience to view, add and delete payment methods (for Web platform)
* New connector and payment method integrations
  * Datatrans ([Planet.com](http://planet.com/)) for card payments
  * Wells Fargo (US) for card payments
  * Deutsche Bank (DE) for SEPA direct debits
  * Novalnet for card payments
  * Fiuu for cards, bank transfer and inter-operable QR based payments
  * Itau Bank for instant payments
  * Payouts via PayOne, and Wells Fargo
  * Razorpay UPI payments
* Pay by Bank Experience through [Plaid Open banking](/other-features/payment-orchestration/quickstart/payment-methods-setup/banks/open-banking). This is to allow merchants to enable instant bank transfer (push payments) in the UK and EU via with support for app2app redirection experience
* Account verification via Plaid for pull payments (ACH, SEPA) in the EU and US
* React Native SDK was Open Sourced
* Native 3DS Authentication Experience via Netcetera for mobile
* Merchant Initiated Transactions (MIT) were made PSP agnostic with Network Transaction ID (NTI)
* User management and dashboard analytics views at entity level granularity (org to profile)
* Payment plugin for Saleor - headless commerce platform to facilitate faster integrations
* Localisation support for Payouts across 17 languages
* Control Centre - Enable SSO sign in with Okta

### Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

### Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

There are a lot of problems to be solved in payments, but our majority of our current focus falls under 5 themes below.

🌎 **Community Feature Requests:** Most of our community feature requests falls under one of the above themes, but we still keep this as a separate theme, because we intend to actively explore new problem statements and themes from the community before scheduling actual feature work.

👨‍💻 **Developer Experience:** Providing a great self-service and self-installation experience for developers who wish to use or contribute back to Hyperswitch.

💰 **Reducing Payment Costs:** Payments should be like a free utility for digital businesses. Any business should be able reduce payment processing costs by embracing the diversity in payments.

📈 **Improving Authorization Rates:** Ensuring a best-in-class payment experience and access to latest innovations in the payments ecosystem for all businesses.

👍 **Reducing Payment Operations:** Managing payments across multiple countries, currencies and processors should not add to the administrative burden on businesses. Hence, Hyperswitch intends to eliminate all such operational burdens so that businesses can focus on the core activities.

| **Legend** | **Description**     |
| ---------- | ------------------- |
| 🟩         | Feature completed   |
| 🟧         | Feature in progress |
| 🟥         | Work not started    |
| 💪         | Stretch target      |
| 🚛         | Backlog feature     |

### Roadmap <a href="#roadmap" id="roadmap"></a>

#### Community Feature Requests <a href="#community-feature-requests" id="community-feature-requests"></a>

* 🟩 More payment authorization workflows - split payments and incremental authorization
* New integrations -
  * 🟩 SamsungPay
  * 🟩 Nexi Xpay card payments
  * 🟩 PAZE for card payments in the US
* 🟩 Dynamic Tax updater for express checkout wallets (Paypal, Applepay, Googlepay and Klarna) using Taxjar integration

#### Improving Authorization Rates <a href="#improving-authorization-rates" id="improving-authorization-rates"></a>

* 🟩 Extending smart retries to 7 more PSPs: Adyen, Worldpay, Braintree, Deutsche Bank, Novalnet, Fiuu and Nexi Xpay
* 🟩 Implement MPAN (merchant tokens) for Applepay recurring payments
* 🟩 Enabling guest checkout flow with [Click to Pay](https://developer.mastercard.com/mastercard-checkout-solutions/documentation/use-cases/click-to-pay/)

#### Reducing Payments Cost <a href="#reducing-payments-cost" id="reducing-payments-cost"></a>

* More direct bank acquirer integrations
  * 🟩 JP Morgan

#### Reducing Payment Operations <a href="#reducing-payment-operations" id="reducing-payment-operations"></a>

* 🟩 Data reporting at an organization, merchant and profile level for easier reconciliation
* 🟩 Enhancements in analytics module for Refunds, Disputes and Smart Retries
* 🟩 Migration of Network Tokens for business continuity

#### Developer Experience <a href="#developer-experience" id="developer-experience"></a>

* 🟩 Hyperswitch widgets to support Alternate payment methods, express checkout payment methods and Authentication solutions

#### **Want to contribute to the roadmap?** <a href="#want-to-contribute-to-the-roadmap" id="want-to-contribute-to-the-roadmap"></a>

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous Roadmap - Q3 2024

Hyperswitch roadmap (July to Sept'24)

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, previous roadmap, findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

### Recap of Q2 2024 <a href="#recap-of-q2-2024" id="recap-of-q2-2024"></a>

* Payouts support with Adyen Platform, Cybersource, Ebanx, Payone and Paypal and instant payout methods
* Vaulting payment methods with Hyperswitch for on-session payments
* Natively authenticating payments using Third party 3DS service providers - Netcetra, 3dsecure.io
* Integrations for alternate payment methods via Mifinity and ZSL
* Scan a card experience on Unified Checkout
* Open-sourced the Native SDK for Unified Checkout
* Control Centre support for Two Factor Authentication for user login
* One-click Express Checkout through Applepay, Klarna, GooglePay
* Secure payout iframe to collect payout details and trigger payouts

### Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

### Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

There are a lot of problems to be solved in payments, but our majority of our current focus falls under 5 themes below.

🌎 **Community Feature Requests:** Most of our community feature requests falls under one of the above themes, but we still keep this as a separate theme, because we intend to actively explore new problem statements and themes from the community before scheduling actual feature work.

👨‍💻 **Developer Experience:** Providing a great self-service and self-installation experience for developers who wish to use or contribute back to Hyperswitch.

💰 **Reducing Payment Costs:** Payments should be like a free utility for digital businesses. Any business should be able reduce payment processing costs by embracing the diversity in payments.

📈 **Improving Authorization Rates:** Ensuring a best-in-class payment experience and access to latest innovations in the payments ecosystem for all businesses.

👍 **Reducing Payment Operations:** Managing payments across multiple countries, currencies and processors should not add to the administrative burden on businesses. Hence, Hyperswitch intends to eliminate all such operational burdens so that businesses can focus on the core activities.

| **Legend** | **Description**     |
| ---------- | ------------------- |
| 🟩         | Feature completed   |
| 🟧         | Feature in progress |
| 🟥         | Work not started    |
| 💪         | Stretch target      |
| 🚛         | Backlog feature     |

### Roadmap <a href="#roadmap" id="roadmap"></a>

#### Community Feature Requests <a href="#community-feature-requests" id="community-feature-requests"></a>

* 🟩 Payment Method Management experience to view, add and delete payment methods (for Web platform)
* New connector and payment method Integrations (more will be added as we progress)
  * 🟩 🚛 Datatrans ([Planet.com](http://planet.com/)) for card payments
  * 🟩 Razorpay for UPI payments
  * 🟧 PAZE checkout *(extending to Q4)*
  * 🟧 TaxJar for dynamic tax calculations *(extending to Q4)*
  * 🟩 Novalnet for card payments
  * 🟩 Fiuu for cards, bank transfer and inter-operable QR based payments
  * 🟩 Itau Bank for instant payments
  * 🟩 Payouts via PayOne, and Wells Fargo

#### Improving Authorization Rates <a href="#improving-authorization-rates" id="improving-authorization-rates"></a>

* 🟩 Network Tokenization with account updater to (a) improve auth rates for one-time/ recurring payments and (b) reducing scheme fee

#### Reducing Payments Cost <a href="#reducing-payments-cost" id="reducing-payments-cost"></a>

* Direct integrations with banks acquirers to reduce cost (will be extended for EU banks)
  * 🟩 Wells Fargo (US)
  * 🟩 Deutsche Bank (DE)
* 🟩 Pay by Bank Experience through Plaid Open banking to enable instant bank transfer (push payments) in the UK and EU via with support for app2app redirection experience

#### Reducing Payment Operations <a href="#reducing-payment-operations" id="reducing-payment-operations"></a>

* 🟩 🚛 Account verification for pull payments like Direct Debits in the EU and US (ACH, SEPA) via Plaid
* 🟩 User management and dashboard analytics views at entity level granularity (org to profile)

#### Developer Experience <a href="#developer-experience" id="developer-experience"></a>

* 🟩 Payment plugins for ~~Commerce Tools~~ Saleor - Headless commerce platform to facilitate faster integrations
* 🟩 🚛 PCI Software Security Standard (S3) certification

#### **Want to contribute to the roadmap?** <a href="#want-to-contribute-to-the-roadmap" id="want-to-contribute-to-the-roadmap"></a>

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous Roadmap - Q2 2024

Hyperswitch roadmap (Apr to Jun'24)

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, [previous roadmap](/about-hyperswitch/roadmap-q3-2026/roadmap-q4-2023), findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

## Recap of Q1 2024 <a href="#recap-of-q4-2023" id="recap-of-q4-2023"></a>

Lets start with a short recap on what was released new in Q1 2024

* New connector integrations
  * Cybersource support for ApplePay, GooglePay
  * PlacetoPay support for card payments
  * [3Dsecure.io](http://3dsecure.io) integration for 3DS authentication
  * Pix and Boleto via Adyen
* Card vault was enhanced to support fingerprinting and MIT recurring payments
* Payment gateway agnostic MIT payments through Stripe, Adyen and Cybersource
* Upgraded helm charts to support cloud agnostic installation of Hyperswitch
* Enhanced audit trail for visibility into payment flows
* Decoupled 3DS authentication for smoother payment experience and better conversion rates authorization rates
* Customs roles on Control center for identity & access management
* Retries for failed webhooks
* Enabling surcharge for specific payment methods to promote low cost payment methods
* Control center can manage support tracking, submitting evidences for disputes (via Stripe) - we will be extending to more processors in the upcoming quarters.
* Global ID based search in control center to quickly access a payment record
* Block lists to prevent fraudulent card payments based on card issuers and fingerprints
* Interface to dynamically select components (Storage Backend, Secrets Manager) during runtime
* Enhancement of Payouts module - Save payout details, Payouts routing, Payout retries (same provider & different provider).
* Subscriptions - Payment processing support for all major subscription solution providers and plug-in support for Kill Bill subscription solution.

## Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

## Themes for Roadmap <a href="#themes-for-roadmap" id="themes-for-roadmap"></a>

There are a lot of problems to be solved in payments, but our majority of our current focus falls under 5 themes below.

🌎 **Community Feature Requests:** Most of our community feature requests falls under one of the above themes, but we still keep this as a separate theme, because we intend to actively explore new problem statements and themes from the community before scheduling actual feature work.

👨‍💻 **Developer Experience:** Providing a great self-service and self-installation experience for developers who wish to use or contribute back to Hyperswitch.

💰 **Reducing Payment Costs:** Payments should be like a free utility for digital businesses. Any business should be able reduce payment processing costs by embracing the diversity in payments.

📈 **Improving Authorization Rates:** Ensuring a best-in-class payment experience and access to latest innovations in the payments ecosystem for all businesses.

👍 **Reducing Payment Operations:** Managing payments across multiple countries, currencies and processors should not add to the administrative burden on businesses. Hence, Hyperswitch intends to eliminate all such operational burdens so that businesses can focus on the core activities.

<table data-header-hidden><thead><tr><th width="125"></th><th></th></tr></thead><tbody><tr><td><strong>Legend</strong></td><td><strong>Description</strong></td></tr><tr><td>🟩</td><td>Feature completed</td></tr><tr><td>🟧</td><td>Feature in progress</td></tr><tr><td>🟥</td><td>Work not started</td></tr><tr><td>💪</td><td>Stretch target</td></tr><tr><td>🚛</td><td>Backlog feature from Q1 2024</td></tr></tbody></table>

## Roadmap <a href="#roadmap" id="roadmap"></a>

### Community Feature Requests <a href="#community-feature-requests" id="community-feature-requests"></a>

* 🟩 Vaulting payment methods in non-payment flows
* 🟥 ~~Support business continuity for MIT payment through PSP tokens~~

  (Will be supported with custom migration APIs)
* 🟩 Card vaulting enhancements - support nickname updation
* 🟩 Hyperswitch Widgets for Quick Checkout experience - Paypal, Applepay and Googlepay
* New connector and payment method Integrations
  * 🟧 Datatrans ([Planet.com](http://planet.com)) for card payments
  * 🟩 Netcetera for 3DS service
  * 🟩 3DSecure.io for 3DS service
  * 🟩 ZSL for bank transfer payments
  * 🟩 Mifinity for wallet payments
  * 🟩 Payone for payouts

*(list of connectors will keep expanding as we receive more requests from the community!!! )*

### Developer Experience <a href="#developer-experience" id="developer-experience"></a>

* 🟧 🚛 Code restructuring for enhancing readability, reducing compile & build times
* 🟧 PCI Software Security Standard (S3) certification. At the moment, Hyperswitch application is battle tested for PCI L1 compliance. While PCI Software Security Standard (S3) is not mandatory for Hyperswitch related functionalities, we undertook the certification starting Feb 2024 to further augment our security standards. *Expected closure by June 2024*
* 🟩 Upgraded to PCI DSS 4.0 certification
* 🟩 Open sourcing the Native Unified Checkout SDK (Android and iOS)

### Improving Payment Authorization Rates <a href="#improving-payment-authorization-rates" id="improving-payment-authorization-rates"></a>

* 🟩 🚛 Enable scanning of cards to reduce manual entry of card details by the customer
* 🟩 Native 3DS on Android and iOS apps
* 🚛 🟧 Paypal Vault flows for improving repeat user payment experience
* 🟧 Customer initiated payment retries on Hyperswitch Unified Checkout
* 🟧 💪 Account verification for bank payment methods like ACH and SEPA

### Reducing Payment Operations <a href="#reducing-payment-operations" id="reducing-payment-operations"></a>

* 🟥 ~~Payment audit trail will carry more information for Hyperswitch Cloud users - Consolidated API logs, Webhook and State change events on the Control Centre~~
* 🟧 Hyperswitch Headless SDK methods to support payment account management experience for users - this will allow customers to add, update, edit and delete payment methods
* 🟧 Enhance the functionality of the analytics module in the control center by adding additional features such as expanded filter options, currency conversion capabilities, granular timeline views and a broader range of analytical views

### **Want to contribute to the roadmap?** <a href="#want-to-contribute-to-the-roadmap" id="want-to-contribute-to-the-roadmap"></a>

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous roadmap - Q1 2024

Hyperswitch roadmap (Jan to Mar' 24)

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, [previous roadmap](/about-hyperswitch/roadmap-q3-2026/roadmap-q4-2023), findings over the previous quarter, what we heard from the community as feature requests.

👂And as always, we listen to your feedback and adapt our plans if needed.

## Core Values <a href="#core-values" id="core-values"></a>

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, and at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

<table data-header-hidden><thead><tr><th width="125"></th><th></th></tr></thead><tbody><tr><td><strong>Legend</strong></td><td><strong>Description</strong></td></tr><tr><td>🟩</td><td>Feature completed</td></tr><tr><td>🟧</td><td>Feature in progress</td></tr><tr><td>🟥</td><td>Work not started</td></tr><tr><td>💪</td><td>Stretch target</td></tr><tr><td>🚛</td><td>Backlog feature from Q4 2023</td></tr></tbody></table>

## Roadmap <a href="#roadmap" id="roadmap"></a>

### Community Feature Requests <a href="#community-feature-requests" id="community-feature-requests"></a>

* 🟩 Card vault enhancements to support more use cases - enable vaulting before payment, card fingerprinting
* 🟩 Enhance MIT payments (Merchant Initiated Transactions) to accept `raw card data` and `network_reference_id.` This will allow for payment gateway agnostic MIT payments
* *(removed from the Q1 roadmap)* Enabling card transactions using `payment gateway token` to ensure business continuity for merchants with card vaulted with payment gateways
* 🟩 New connector and payment method Integrations

  * 🟩 Place2Pay
  * 🟩 Billwerk
  * 🟩 Pix and Boleto via Adyen

  *(the list of connectors will keep expanding as we receive more requests from the community!!! )*

### Developer Experience <a href="#developer-experience" id="developer-experience"></a>

* 🚛 Code restructuring for enhancing readability and ease of contributions
* 🟩 Helm charts enhancement to enable easy installation on Azure, Google Cloud and within existing Kubernetes clusters
* 🟩 Helm charts will support installation of `hyperswitch-card-vault`
* 🚛 PCI Software Security Standard (S3) certification. At the moment, Hyperswitch application is battle tested for PCI L1 compliance. While PCI Software Security Standard (S3) is not mandatory for Hyperswitch related functionalities, we are undertaking the certification to further augment our security standards
* 🟩Adding more developer help videos and improving developer documentations for Hyperswitch features, components and usage
* 💪🚛 Open sourcing the Native Unified Checkout SDK (Android and iOS)
* 🟩 Diagnostics tool to determine health of your on-cloud Hyperswitch stack setup

### Reduce Payment Costs <a href="#reduce-payment-costs" id="reduce-payment-costs"></a>

* 🟩 Enabling surcharge for specific payment methods to promote low cost payment methods
* 🚛 🟩 Hyperswitch API supports for Plaid for ACH account verification

### Improving Payment Authorization Rates <a href="#improving-payment-authorization-rates" id="improving-payment-authorization-rates"></a>

* 🟩Decoupled 3DS authentication and authorization using EMVCo certified 3DS connectors, for improving payment authorization rates and customer experience.
* 🚛 Paypal Vault flows for improving repeat user payment experience

### Reducing Payment Operations <a href="#reducing-payment-operations" id="reducing-payment-operations"></a>

* 🟩 Enhanced Audit trail visibility for Payments, Refunds, Disputes on Hyperswitch Control Centre
* 🟩 Support for Hosted Checkout Page on Web
* 🟩 Mitigating fraud by defining Block List rules to block transactions from specific customer ID, card bins, card numbers and more parameters
* 🟩 Enhanced search using Global Identifiers for improved discoverability. Hyperswitch Cloud users can use the Control Center to search for payments, customers, refunds, connector transaction IDs and get all related data
* 🟩 Dispute management and evidence submission workflow on Hyperswitch Control Centre
* 🟩 Hyperswitch Control Centre will allow to customize payment methods at country and currency
* 🟩 Create custom roles for Identity and Access Management

### **Want to contribute to the roadmap?** <a href="#want-to-contribute-to-the-roadmap" id="want-to-contribute-to-the-roadmap"></a>

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Previous roadmap - Q4 2023

Hyperswitch roadmap (Oct to Dec'23)

🗺️ Our Roadmap typically pans out over a 3-month period and we establish topics we work on upfront.

Before the beginning of every quarter we come together to develop the next roadmap based on our core values, findings over the previous quarter, what we heard from the community as issues and feature requests, in face-to-face discussions and social media.

👂And as always, we listen to your feedback and adapt our plans if needed.

## Core Values

Our core values have pretty much remained the same since the early days and here they are:

* Make payments more `accessible` and `affordable` to every digital business
* Staying `simple` and `super-lightweight`, at the same time `reliable` and `scalable` payment switch
* Being `community-first` in ideation, planning and execution of features

## Themes for Roadmap

There are a lot of problems to be solved in payments, but our majority of our current focus falls under 5 themes below.

* 👨‍💻 **Developer Experience:** Providing a great self-service and self-installation experience for developers who wish to use or contribute back to Hyperswitch.
* 💰 **Reducing Payment Costs:** Payments should be like a free utility for digital businesses. Any business should be able reduce payment processing costs by embracing the diversity in payments.
* 📈 **Improving Authorization Rates:** Ensuring a best-in-class payment experience and access to latest innovations in the payments ecosystem for all businesses.
* 👍 **Reducing Payment Operations:** Managing payments across multiple countries, currencies and processors should not add to the administrative burden on businesses. Hence, Hyperswitch intends to eliminate all such operational burdens so that businesses can focus on the core activities.
* 🌎 **Community Feature Requests:** Most of our community feature requests falls under one of the above themes, but we still keep this as a separate theme, because we intend to actively explore new problem statements and themes from the community before scheduling actual feature work.

<table><thead><tr><th width="148">Legend</th><th>Description</th></tr></thead><tbody><tr><td>🟩</td><td>Work completed</td></tr><tr><td>🟧</td><td>Work in progress</td></tr><tr><td>🟥</td><td>Work not started</td></tr><tr><td>💪</td><td>Stretch target</td></tr><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f69b">🚛</span></td><td>Backlogged for next quarter</td></tr></tbody></table>

### Developer Experience

* 🟩 Installation scripts for cloud deployment using EKS (on AWS). [Try the installation from here](https://docs.hyperswitch.io/self-hosting/hyperswitch-open-source/deploy-on-kubernetes-using-helm/deploy-on-aws-using-helm-charts)
* 🟩 Publish developer docs for self-hosting Hyperswitch. [Checkout the documentation here](https://opensource.hyperswitch.io/)
* 🟩 Hyperswitch Woocommerce plugin for Wordpress users. [Install the Woocommerce plugin](https://hyperswitch.io/docs/sdkIntegrations/wooCommercePlugin/wooCommercePluginOverview)
* 🟩 AWS menu-driven Hyperswitch installation support
* 🟩 Optimizing Hyperswitch application overhead from 30ms to 20ms

### Reducing Payment Costs

* 🟩 Reduce chargebacks by enabling Signifyd and Riskified (FRMs). [Try it out by signing up for hyperswitch](https://app.hyperswitch.io/register)
* 🟩 Support for Gocardless bank direct debits. [Try it out by signing up for Hyperswitch](https://app.hyperswitch.io/register)
* 🟩 Specialized low cost processor integration - Helcim
* 🟩 Open sourcing Smart Routing Framework for self hosting
* 🟧 Support Plaid for ACH account verification
* 🟧 Enabling surcharge for specific payment methods to promote low cost payment methods
* ~~🟥 Direct bank integration - Wells Fargo~~ \[Dropped]

### Improving Authorization Rates

* 🟩 Smart retry with 3DS for fraud declined payments. [Learn more about the feature](https://hyperswitch.io/docs/features/smartRetries)
* :articulated\_lorry: Paypal Vault flows for improving repeat user experience
* :articulated\_lorry:💪 Enhancing 3DS experience with Delegated Authentication and Visa's Digital Authentication Framework (for SCA markets)
* :articulated\_lorry:💪 Improve authorization rates for bank payments through Open banking integration for UK/EU

### Reducing Payment Operations

* 🟩 Support for exporting hyperswitch data to third party data warehouse
* :articulated\_lorry: Audit trail visibility for Payments, Refunds, Disputes on Hyperswitch Control Centre
* :articulated\_lorry:💪 System health metrics monitoring module on Hyperswitch Control Centre

### Community Feature Requests

* 🟩 Open sourcing Hyperswitch Unified Web Checkout for self-hosting. [Try it out here](https://docs.hyperswitch.io/self-hosting)
* 🟩 Open sourcing Card Vault application code for self-hosting
* 🟩 Open sourcing Control Centre (Hyperswitch dashboard) for self-hosting [Try it out here](https://docs.hyperswitch.io/self-hosting)
* 🟩 Direct bank integration - Bank of America
* 🟩💪 Open sourcing Fraud and Risk Management Integrations
* 🟩💪 Open sourcing Payouts module

## **Want to contribute to the roadmap?**

[Submit an idea or feature request here](https://github.com/juspay/hyperswitch/discussions/categories/ideas-feature-requests) with a simple explanation on `What?` and `Why?` included.


# Hyperswitch architecture

A 30,000 feet view of Hyperswitch's architecture

Hyperswitch comprises two distinct app services: **Router** and **Scheduler** which in turn consists of **Producer** and **Consumer**, where each service has its specific responsibilities to process payment-related tasks efficiently.

<figure><img src="https://github.com/juspay/hyperswitch/raw/main/docs/imgs/hyperswitch-architecture.png" alt=""><figcaption><p>Typical Deployment</p></figcaption></figure>

### Router

The Router is the main component of Hyperswitch, serving as the primary crate where all the core payment functionalities are implemented. It is a crucial component responsible for managing and coordinating different aspects of the payment processing system. Within the Router, the core payment flows serve as the central hub through which all payment activities are directed. When a payment request is received, it goes through the Router, which handles important processing and routing tasks.

### Scheduler

Suppose a scenario where a customer has saved their card details in your application, but for security reasons, you want to remove the saved card information after a certain period. To automate this process, Scheduler comes into picture. It schedules a task with a specific time for execution and stores it in the database. When the scheduled time arrives, the job associated with the task starts executing, here in this case, allowing the saved card details to be deleted automatically. One other situation in which we use this service in Hyperswitch is when we want to notify the merchant that their api key is about to expire.

#### Producer (Job scheduler)

The Producer is one of the components responsible for the Scheduler's functionality. Its primary responsibility is to handle the tracking of tasks which are yet to be executed. When the Router Service inserts a new task into the database, specifying a scheduled time, the producer retrieves the task from the database when the scheduled time is up and proceeds to group or batch these tasks together. These batches of tasks are then stored in a Redis queue, ready for execution, which will be picked up by consumer service.

#### Consumer (Job executor)

The Consumer is another key component of the Scheduler. Its main role is to retrieve batches of tasks from the Redis queue for processing, which were previously added by the Producer. Once the tasks are retrieved, the Consumer executes them. It ensures that the tasks within the batches are handled promptly and in accordance with the required processing logic.

### Database

#### Postgres

The application relies on a PostgreSQL database for storing various types of data, including customer information, merchant details, payment-related data, and other relevant information. The application maintains a master-database and replica-database setup to optimize read and write operations.

#### Redis

In addition to the database, Hyperswitch incorporates Redis for two main purposes. It is used to **cache** frequently accessed data in order to decrease the application latencies and reduce the load on the database. It is also used as a **queuing mechanism** by the Scheduler.

### Locker

The application utilizes a Rust locker built with a GDPR compliant PII (personal identifiable information) storage. It also uses secure encryption algorithms to be fully compliant with **PCI DSS** (Payment Card Industry Data Security Standard) requirements, this ensures that all payment-related data is handled and stored securely. You can find the source code of locker [here](https://github.com/juspay/hyperswitch-card-vault).

### Monitoring

<figure><img src="https://github.com/juspay/hyperswitch/raw/main/docs/imgs/hyperswitch-monitoring-architecture.png" alt=""><figcaption><p>HyperSwitch Monitoring Architecture</p></figcaption></figure>

The monitoring services in Hyperswitch ensure the effective collection and analysis of metrics to monitor the system's performance.

Hyperswitch pushes the metrics and traces in **OTLP** format to the [OpenTelemetry collector](https://opentelemetry.io/docs/collector/). [Prometheus](https://prometheus.io/docs/introduction/overview/) utilizes a pull-based model, where it periodically retrieves application metrics from the OpenTelemetry collector. [Promtail](https://grafana.com/docs/loki/latest/clients/promtail/) scrapes application logs from the router, which in turn are pushed to the [Loki](https://grafana.com/docs/loki/latest/) instance. Users can query and visualize the logs in Grafana through Loki. [Tempo](https://grafana.com/docs/tempo/latest/) is used for querying the application traces.

Except for the OpenTelemetry collector, all other monitoring services like Loki, Tempo, Prometheus can be easily replaced with a preferred equivalent, with minimal to no code changes.


# Router

The router service is implemented in Rust to ensure type safety and high performance. It follows a hexagonal architecture, promoting modularity by allowing independent management of different components. ​[l-lin.github.io](https://l-lin.github.io/programming-languages/rust/master-hexagonal-architecture-in-Rust)

### **Core API Layer**

* **Request Handling**: Incoming HTTP requests are directed to the Core API Layer.​
* **Authentication**: Depending on the API endpoint or group, appropriate authentication mechanisms are applied to verify the request.​
* **Data Validation**: The payload of incoming data is validated. This includes checking the data itself and ensuring it aligns with the merchant's configuration. For instance, a refund request should correspond to a successful payment.​
* **Data Storage and Response**: Valid data is stored. If the API action is standalone, a success response is returned. If it involves connector calls, the response's success or failure depends on the connector module's status.​
* **Error Handling**: In case of a connector failure, appropriate status mapping ensures a unified user interface.​

### **Connectors**

Connectors are external services that the router interacts with, such as payment processors, fraud and risk management services, and tokenization services.​

* **Selection Criteria**: The API request type, data, and merchant configuration determine which connectors the router will call.​
* **Connector Module**: This module contains the logic to construct necessary request data for the selected services and to interpret their responses.​[github.com+5thetechedvocate.org+5alexis-lozano.com+5](https://www.thetechedvocate.org/master-hexagonal-architecture-in-rust/)
* **Complex Operations**: Some services may require multiple API calls for a single action, which the connector can handle.​

### **Asynchronous Jobs Scheduler**

Certain API actions might be time-consuming, making it impractical to delay the API response until completion. In such cases, the router returns a success response with an intermediate state, like "processing." For example, if a payment processor doesn't immediately confirm success, the router will check the status later.​

* **Job Queueing**: The necessary action is queued for the scheduler to execute asynchronously.​
* **Scheduler Function**: The scheduler determines which jobs to run based on their scheduled times, executes them, updates the router's storage, and triggers any other required actions, such as webhook calls to the server.​

This design ensures that the router service remains efficient, modular, and capable of handling complex operations without compromising performance.​


# Storage

Storage layer is built with caching layer and persistent storage. The goal is to provide low latency persistent storage at lower cost.

## Cache Layer

Redis cluster is used as the cache.

Any data that is accessed frequently but doesn't change often, is already cached in the router's memory. Payment related data is cached in the cache layer. Cache allows very low latency payments through hyperswitch.

## Persistent Storage

Since Payment data should never be lost, the data is persisted in normal databases like Postgres. This allows hyperswitch to provide data related to payments, refunds, etc to the users on their dashboards.

## Drainer

The Payment related events are written to a queue (like kafka) and the drainer takes the events and populate/update the persistent storage in near realtime. This allows hyperswitch to handle traffic at scale and not bottleneck the database.

\\


# A Payments Switch with virtually zero overhead

When it comes to payments, every millisecond counts. The difference between a seamless customer experience and a frustrating one often boils down to the speed and efficiency of payment processing.

Merchants who operate in this digital arena understand the importance of **offering multiple payment options to their customers**. The challenge lies in integrating these payment processors seamlessly into their existing systems without wasting dev effort or introducing performance overhead.

{% hint style="success" %}
Enter Hyperswitch, a game-changing solution designed to be lightning fast and add **virtually zero overhead** to your payment processing infrastructure!
{% endhint %}

***

**Clarifying latency overhead**

> The latency overhead of Hyperswitch refers specifically to the time taken by the Hyperswitch application itself within the transaction flow.

While Hyperswitch optimizes its internal processes to add almost zero overhead, it's important to recognize that the overall transaction latency isn't solely determined by Hyperswitch alone. The entire transaction process involves multiple components, including the payment processor as shown below

| Component                                                                                   | Value                                                     |
| ------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| Network latency between Client App and your server (starting point)                         | A (BAU)                                                   |
| <mark style="color:blue;">**Hyperswitch Application latency (hosted in your stack)**</mark> | <mark style="color:blue;">**B (negligible)**</mark> :zap: |
| Network latency between your server and payment processor                                   | C (BAU)                                                   |
| Processor Latency                                                                           | D (BAU)                                                   |
| **Total Transaction Latency**                                                               | **A+B+C+D**                                               |

What Hyperswitch does is provide an option to connect to multiple processors at almost zero latency cost

### **How Hyperswitch achieves a near-invisible presence**

At its core, Hyperswitch is a payments switch that effortlessly connects merchants with multiple payment processors. What sets it apart is its extraordinary speed and efficiency. Here's how Hyperswitch manages to be lightning fast and virtually overhead-free:

<details>

<summary><strong>In-Memory Configuration Caching</strong></summary>

* Hyperswitch eliminates the delays associated with fetching configuration data for each transaction by caching all merchant and processor-related configurations in memory
* This ensures that transaction processing remains lightning quick, regardless of the specifics of each transaction

</details>

<details>

<summary><strong>Redis for Transaction Data</strong></summary>

* To further accelerate transaction processing, Hyperswitch stores all transaction-related data reads in Redis, an in-memory key-value store
* This choice of data storage allows for rapid access to transaction details, ensuring that every step of the process is nearly instantaneous.

</details>

<details>

<summary><strong>Asynchronous Data Persistence</strong></summary>

* Hyperswitch optimizes the transaction workflow by making all data writes to Redis and then asynchronously draining this data to the database
* This approach minimizes any potential delays in the critical transaction path, maintaining the rapid pace that customers expect

</details>

<details>

<summary><strong>Parallelization</strong></summary>

* Hyperswitch embraces parallelization wherever possible, ensuring that multiple operations can be executed simultaneously
* This approach further enhances its speed and responsiveness, making it a true powerhouse in payment processing

</details>

{% hint style="info" %}
The latency of the entire Hyperswitch application is just \~25 ms
{% endhint %}

<figure><img src="/files/RKA6QAnLvlOz5AwxoOrH" alt=""><figcaption></figcaption></figure>

<div data-full-width="false"><figure><img src="/files/YQ5evQhVJA4P6GM058cH" alt="" width="563"><figcaption></figcaption></figure></div>

### **Seamless Integration - Just another microservice in your system**

One of the remarkable features of Hyperswitch is its ability to seamlessly integrate into your existing technology stack. By functioning like a system software, Hyperswitch becomes an integral part of your system, eliminating network latency between your application and the switch. This means there's almost zero overhead introduced into your system.

**Reduced Network Latency**: Hyperswitch's integration into your stack eliminates network latency, leading to quicker transaction processing and improved system performance.

**Streamlined Workflow**: With Hyperswitch seamlessly embedded in your stack, transaction processing becomes an integral part of your system's workflow. This streamlines the management of payment processing and reduces the complexity of maintaining multiple external connections.

**Improved Reliability**: By operating as a tightly integrated component, Hyperswitch can be configured and managed alongside the rest of your stack, allowing for comprehensive monitoring and ensuring high levels of reliability and availability.

### **Bottomline**

By adding almost zero overhead, Hyperswitch ensures that the lion's share of the transaction's latency, as experienced by the end user, is determined by the payment processor's inherent processing time.

In essence, Hyperswitch acts as the invisible hand behind the scenes by connecting merchants with multiple payment processors in the blink of an eye without adding any noticeable overhead.


# Connector Payment Flows

This page outlines the various payment flows you may come across while building a connector.

### Pre-processing

This refers to the two-step payment flow where preprocessing steps are executed before the main authorization call. If your connector does not use tokenization or does not require customer or access token flows, implement the pre-processing pattern described below. It's important to note that different connectors implement preprocessing differently. For example, Airwallex creates payment intents during preprocessing as one of the steps while Nuvei performs 3DS enrollment checks as a step. The preprocessing call does make a separate (second) call for the authorize flow. The preprocessing and authorization are implemented as distinct, sequential operations in Hyperswitch's payment processing pipeline.

The preprocessing steps are executed first:

* **Preprocessing Execution**: The system creates a preprocessing connector integration and executes it
* **Data Transformation**: Converts the authorize request data to preprocessing request data
* **Connector Processing**: Executes the preprocessing step through the connector
* **Response Handling**: Processes the preprocessing response and updates the router data accordingly

Then, the system proceeds to build the actual authorization request:

* **First Call | Preprocessing**: The system creates a preprocessing connector integration and executes it
* **Response Processing**: The preprocessing response updates the router data
* **Second Call | Authorization**: After preprocessing completes, the system proceeds with the actual authorization flow

**When to Use This Flow** Use this pattern if:

* The connector issues temporary session credentials.
* You need to make a discovery or configuration call before authorization.
* No prior customer setup or vaulting is needed.

**Example Diagram**

<figure><img src="/files/alM6TPEuSPej140yupnF" alt=""><figcaption></figcaption></figure>

## Authorization Flow

This flow represents the core payment authorization logic executed once all prerequisite steps are complete. For example, after the pre-processing stage finishes, the authorization flow runs. At this point, the sequence below is evaluated, after which the authorization logic determines the next steps and uses the necessary tokens to construct the request:

* **Access Token Addition**: Adds access tokens if required by the connector
* **Session Token Addition**: Handles session tokens for wallet payments
* **Payment Method Tokenization**: Tokenizes payment methods if needed
* **Preprocessing Steps**: Executes preprocessing logic
* **Connector Customer Creation**: Creates customer records at the connector level

#### **Decision Logic**

The flow includes intelligent decision-making capabilities:

* **Authentication Type Decision**: Automatically steps up Google Pay transactions to 3DS when risk indicators are present
* **Proceed Decision**: Determines whether to proceed with authorization based on preprocessing responses (e.g., skips authorization if redirection is required)

**Example Diagram**

<figure><img src="/files/MuIViqSIsj3iOZKegvmH" alt=""><figcaption></figcaption></figure>


# SDK Payment flows

{% hint style="info" %}
If you're complete beginner to Digital Payments, take a look at this [Payments 101 ](https://hyperswitch.io/blogs/payments-101-for-a-developer)blog to get familiar with terminologies.
{% endhint %}

### **Payments flow**

There are multiple stages in a Payment flow depending on the payment methods that are involved. Considering an one-time payment method where there was no redirection involved, the following stages form the Payment flow:

**a) Creating a Payment:** When your customer wants to checkout, create a payment by hitting the payments/create endpoint. Fetch and store the payment\_id and client\_secret

**b) Loading the SDK:** After your customer checks out, load the Hyperswitch SDK by initiating it with the client\_secret and publishable\_key

**c) SDK being rendered:** After you initiate the SDK, the SDK makes several API calls involving the /sessions and /payment\_methods endpoints to load relevant payment methods and any saved cards associated with the customer

**d) Customer enters the payment method data:** After the SDK is fully rendered, your customer would choose a payment method and enter the relevant information and click pay

**e) Confirming the payment:** After the customer clicks pay, the SDK calls the payments/confirm endpoint with the customer's payment method details and post response, it displays the payment status

<figure><img src="/files/BWwJ15mkYFS6ZuwhayXM" alt=""><figcaption></figcaption></figure>

Here's a more detailed version of the payment flow:

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#ffffff",
    "primaryBorderColor": "#2563EB",
    "lineColor": "#2563EB",
    "secondaryColor": "#EFF6FF",
    "tertiaryColor": "#DBEAFE",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "14px",
    "textColor": "#000000",

    "actorBkg": "#346DDB",
    "actorBorder": "#999999",
    "actorTextColor": "#ffffff",

    "signalColor": "#000000",
    "signalTextColor": "#696969",

    "labelBoxBkgColor": "#346DDB",
    "labelBoxBorderColor": "#2563EB",
    "loopTextColor": "#000080"
  }
}}%%
sequenceDiagram
    participant MS as Merchant Server
    participant MC as Merchant Client
    participant SDK as Hyperswitch SDK
    participant HS as Hyperswitch Server
    participant PS as Processor Server

    MS->>HS: payments/create (amount, currency, api_key)
    HS-->>MS: payments/create response (payment_id, client_secret)
    MS->>MC: pass client_secret, publishable_key
    MC->>SDK: initiate SDK (client_secret, publishable_key)
    SDK->>HS: /payment_methods_list (client_secret)
    HS-->>SDK: /payment_methods_list response (eligible payment methods)
    Note over SDK: Display payment sheet with eligible methods
    Note over SDK: Customer selects desired payment method <br>(Say Card and Enters their Card Details)
    SDK->>HS: payments/confirm (client_secret, payment_method_data)
    HS->>PS: payments/confirm to processor (with merchant credentials)
    PS-->>HS: payments/confirm response (status)
    HS-->>SDK: payments/confirm response (status)
    SDK-->>MC: return to return_url with status
```

### **How does Payment flow vary across Payment methods?**

<table data-full-width="false"><thead><tr><th>Customer Action</th><th>Direct/Redirect flows</th><th>Payment- finalized immediately</th><th>Payment- finalized later</th></tr></thead><tbody><tr><td><strong>Customer action required before payments/ confirm</strong></td><td><strong>Within Hyperswitch SDK</strong></td><td><ul><li>Non 3DS Cards</li></ul></td><td><ul><li>Bank Debits like ACH Debit, BACS Debit, SEPA Debit</li></ul></td></tr><tr><td><strong>Customer action required before payments/ confirm</strong></td><td><strong>3rd party Redirect/SDK</strong></td><td><ul><li>Wallets like Apple Pay, Google pay, Paypal, AliPay</li><li>BNPL like Klarna, Afterpay, Affirm</li></ul></td><td><br></td></tr><tr><td><strong>Customer action required after payments/ confirm</strong></td><td><strong>3rd party Redirect</strong></td><td><ul><li>3DS cards</li><li>Bank Redirects like iDeal, Giropay, eps</li></ul></td><td><ul><li>Bank Transfers like ACH Transfer, SEPA Transfer, BACS Transfer, Multibanco</li><li>Crypto wallets like Cryptopay</li></ul></td></tr></tbody></table>

### **Functionalities provided by Hyperswitch**

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Accept online payments</strong></td><td>Get started with accepting one time payments globally on your online store</td><td></td><td><a href="/files/bCAWLoNxDHOg3QcQxcCX">/files/bCAWLoNxDHOg3QcQxcCX</a></td><td><a href="/pages/FgH8DjTXnf5Th2C7B2hA">/pages/FgH8DjTXnf5Th2C7B2hA</a></td></tr><tr><td><strong>Setup mandates &#x26; recurring payments</strong></td><td>Setup payments for a future date or charge your customers on a recurring basis</td><td></td><td><a href="/files/4TGjQBQxLyKgH9W8txTC">/files/4TGjQBQxLyKgH9W8txTC</a></td><td><a href="/pages/vjpY8TSr0sGJmjWYiifd">/pages/vjpY8TSr0sGJmjWYiifd</a></td></tr><tr><td><strong>Manage payouts</strong></td><td>Facilitate payouts for global network of partners and service providers</td><td></td><td><a href="/files/VBT7SYLnisWYmCYagzp9">/files/VBT7SYLnisWYmCYagzp9</a></td><td><a href="/pages/Aj7TIQDmiomFn5GwFemr">/pages/Aj7TIQDmiomFn5GwFemr</a></td></tr><tr><td><strong>Save a card during payment</strong></td><td>Learn how you can save your customers' cards in a secure PCI compliant manner</td><td></td><td><a href="/files/8LU0asFl64BOjSwrJ8Tl">/files/8LU0asFl64BOjSwrJ8Tl</a></td><td><a href="/pages/xUD3tdwLRlVNcXIxLLia">/pages/xUD3tdwLRlVNcXIxLLia</a></td></tr><tr><td><strong>Manage payments on your platform / marketplace</strong></td><td>Accept payments from your customers and process payouts to the sellers on your marketplace</td><td></td><td><a href="/files/ck7qSNRmkozreP60oZYl">/files/ck7qSNRmkozreP60oZYl</a></td><td><a href="/pages/7IbHrxgL3awnEZxY4x4S">/pages/7IbHrxgL3awnEZxY4x4S</a></td></tr><tr><td><strong>Accept payments on your e-commerce platform</strong></td><td>Give your Wordpress store a lightweight and embedded payment experience with the Hyperswitch WooCommerce plugin</td><td></td><td><a href="/files/m2JKIcMQZUOSicY63lqJ">/files/m2JKIcMQZUOSicY63lqJ</a></td><td><a href="/pages/ywDpx6aO2SB9SWfj7tCk">/pages/ywDpx6aO2SB9SWfj7tCk</a></td></tr><tr><td><strong>Create payment links</strong></td><td>Accept payments for your products through reusable links without writing any code</td><td></td><td><a href="/files/KrF8WgJPBrDY035pM64y">/files/KrF8WgJPBrDY035pM64y</a></td><td><a href="/pages/9AYUf5mZWCiTXihcSYbf">/pages/9AYUf5mZWCiTXihcSYbf</a></td></tr></tbody></table>

### **What are `PaymentIntent` and `PaymentAttempt` objects and how do they work in Hyperswitch?**

Hyperswitch uses the `PaymentIntent` object to track the status of a payment initiated by you. Since, Hyperswitch enables retrying a single payment multiple times across different processors until a successful transaction, we track each of these payment attempts through separate `PaymentAttempt` objects.

While `PaymentIntent` and `PaymentAttempt` have their own state machines, the various states in `PaymentAttempt` are also constrained by their respective mapping to the `PaymentIntent` statuses.

#### **PaymentIntent state machine:**

The following is an abridged version of the `PaymentIntent` state machine flow that covers majority of the above payment use-cases.

```mermaid
flowchart TD
A{PaymentsAPI} --> |amount,currency|RequiresPaymentMethod 
RequiresPaymentMethod -->|payment_method| RequiresConfirmation 
RequiresConfirmation --> |confirm| Processing 
Processing --> AuthType{auth type\nselection} 
AuthType --> |3ds| RequiresCustomerAction 
AuthType --> |no-3ds| CaptureMethod{capture method\nselection}
CaptureMethod --> |manual| RequiresCapture
CaptureMethod --> |automatic| Succeeded
RequiresCustomerAction --> CustomerAction{customer_action\nresult}
CustomerAction -->|success| CaptureMethod
CustomerAction -->|failure| Failed

RequiresCapture --> |capture|Succeeded
```

#### **PaymentAttempt state machine:**

The following is an abridged version of the `PaymentAttempt` state machine flow that covers majority of the above payment use-cases.

```mermaid
flowchart TD

AuthenticationFailed
AuthenticationPending
AuthenticationSuccessful
Authorized
AuthorizationFailed
Charged
Voided
CaptureInitiated
CaptureFailed
Pending
PaymentMethodAwaited
ConfirmationAwaited
DeviceDataCollectionPending

A{PaymentsAPI} --> |amount,currency|PaymentMethodAwaited
PaymentMethodAwaited -->|payment_method| ConfirmationAwaited
ConfirmationAwaited --> |confirm| Pending

%% Before calling the connector change status to Pending
Pending --> CallConnector{CallConnector}
CallConnector -->|Success| AuthType{auth_type}
CallConnector -->|Fail| AuthorizationFailed
AuthType --> |no-3ds| CaptureMethod{capture_method} 
AuthType --> |3ds| DeviceDataCollectionPending
DeviceDataCollectionPending --> |CollectDeviceData|AuthenticationPending --> Authenticate{Authenticate}
Authenticate --> |Success| AuthenticationSuccessful --> CaptureMethod{capture method}
Authenticate --> |Failure| AuthenticationFailed

%% Capture
CaptureMethod --> |automatic| Charged
CaptureMethod --> |manual| Authorized

Authorized --> |capture| CaptureInitiated --> Capture{Capture at connector}
Capture -->|Success| Charged
Capture -->|Failed| CaptureFailed

%% Payment can be voided after calling the connector but not charged
%% This will not void the payment at connector
DeviceDataCollectionPending -->|void| Voided
AuthenticationPending -->|void| Voided

%% Voiding a payment after it is Authorized will void at connector

```


# Payments Flows

Open, Modular, Self-Hostable Payment Infrastructure

Juspay Hyperswitch is built for teams that want engineering-grade control over payments.

To simplify architectural decisions, the ecosystem can be viewed as four independent building blocks. By defining ownership of each block — Hyperswitch-managed, self-hosted, or third-party — you can design an architecture aligned with your compliance posture, performance requirements, and internal engineering capabilities.

### The Four Core Components

#### The SDK (Frontend)

The entry point for your payment flow. It resides in your frontend and is responsible for securely capturing sensitive payment information.

#### Intelligent Routing & Orchestration (Backend)

The core of the operation. It manages the payment lifecycle, executes routing logic, and handles post-payment operations like refunds.

#### Acquirer & Processor Connectivity (Connectors)

The actual pipelines that translate the transaction (e.g., Stripe, Adyen, Worldpay).

#### Vault (Card Data Storage)

The secure locker for sensitive card data to enable "One-Click" recurring payments without the user re-entering details.

Each Component can be handled by Hyperswitch, managed or self-deployed by your own team, or even sourced from a third-party provider e.g. Vault ([reference](https://docs.hyperswitch.io/~/revisions/wA01t1OV6BPUckMZ2Pvg/explore-hyperswitch/workflows/vault/connect-external-vaults-to-hyperswitch-orchestration))

***

### Integration Architecture

With the components defined, the next step is to select your integration architecture. This choice hinges on a single question: Who controls the payment execution?

Choose the integration method that best aligns with your payment flow requirements:

#### Integration Model 1: Client-Side SDK Payments

(Tokenize Post-Payment | SDK-Initiated Execution)

**When to Choose This Model:**

* You want dynamic, frontend-driven payment experiences
* You prefer minimal backend orchestration logic
* You want SDK-triggered payment confirmation
* You are optimizing for rapid checkout implementation

**High-level Flow:**

1. Merchant will call the [/payments](https://api-reference.hyperswitch.io/v1/payments/payments--create) API and load the [Payment SDK](https://docs.hyperswitch.io/about-hyperswitch/sdk-payment-flows).
2. SDK securely collects payment details.
3. SDK triggers payment confirmation.
4. SDK communicates with Hyperswitch backend.
5. Hyperswitch:
   * Applies [routing logic](https://docs.hyperswitch.io/~/revisions/iPtyU5MKxmgIsGywgRhI/explore-hyperswitch/workflows/intelligent-routing)
   * Sends request to configured PSP
   * Manages authorization/capture
   * Returns final payment status

***

#### Integration Model 2: Server-to-Server (S2S) Payments

(Tokenize Pre-Payment | Backend-Controlled Execution)

**When to Choose This Model:**

* You want granular control over transaction timing
* You require backend-driven orchestration logic
* You want to tokenize credentials before execution
* You prefer decoupling vaulting from transaction processing

**High-level Flow:**

**Tokenize Card:**

* Tokenize payment credentials using - [Vault SDK](https://docs.hyperswitch.io/integration-guide/payment-experience/vault-then-pay/web) or backend call to [/payment-methods](https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--create-v1)
* Hyperswitch securely stores the credential and returns a reusable identifier - `payment_method_id`.

**Trigger Payment Execution:**

* Option A: Process via Hyperswitch Orchestration by calling /payments API.
  * Use this option if you want Hyperswitch to:
    * Apply [routing logic](https://docs.hyperswitch.io/~/revisions/iPtyU5MKxmgIsGywgRhI/explore-hyperswitch/workflows/intelligent-routing)
    * Select the optimal connector
    * Manage [retries](https://docs.hyperswitch.io/~/revisions/iPtyU5MKxmgIsGywgRhI/explore-hyperswitch/workflows/smart-retries) and failover
    * Handle authorization and capture lifecycle
  * This is the recommended model for merchants adopting Hyperswitch orchestration.
* Option B: Process via Proxy API by calling [/proxy](https://docs.hyperswitch.io/~/revisions/wbGQKlHTQ8NT2yPUGcD2/about-hyperswitch/payment-suite-1/payment-method-card/proxy) API.
  * Use this option if:
    * You do not want to change your existing PSP integration immediately
    * You want Hyperswitch to act as a passthrough layer
    * You are incrementally migrating to full orchestration
  * In this mode:
    * Your existing integration contract remains unchanged
    * Hyperswitch forwards requests to the configured processor
    * You can progressively enable routing and orchestration features


# Pay-Then-Vault

Comprehensive guide to card payment processing patterns including one-time payments, manual capture, 3DS authentication, and recurring payment flows.

Juspay Hyperswitch provides flexible payment processing with multiple flow patterns to accommodate different business needs. The system supports one-time payments, saved payment methods, and recurring billing through a comprehensive API design.

{% hint style="info" %}
**Integration Path**

**Client-Side SDK Payments (Tokenise Post Payment)**

Refer to Payments (Cards) section if your flow requires the SDK to initiate payments directly. In this model, the SDK handles the payment trigger and communicates downstream to the Hyperswitch server and your chosen Payment Service Providers (PSPs). This path is ideal for supporting dynamic, frontend-driven payment experiences.
{% endhint %}

```mermaid
flowchart TD
    A[Payment Request] --> B{Payment Type}

    %% One-time branch
    B -->|One-time| C[One-time Payment Flows]
    C --> C1[Instant Payment]
    C --> C2[Manual Capture]
    C --> C3[Decoupled Flow]

    %% Store card branch
    B -->|Store card| D[Payment Method Storage]
    D --> D1[Long-term storage]
    D --> D2[Short-term storage]
    D --> D3[List Saved Methods]

    %% Recurring branch
    B -->|Recurring| E[Recurring Payment Flows]
    E --> E1["Setup with charge (CIT)"]
    E --> E2["Setup without charge (CIT)"]
    E --> E3["Execute (MIT)"]
    
    classDef default fill:#3F8CFF,stroke:#3F8CFF,color:#ffffff,rx:6
```

### One-Time Payment Patterns

#### 1. Instant Payment (Automatic Capture)

**Use Case:** Simple, immediate payment processing

**Endpoint:** `POST /payments`

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#ffffff",
    "primaryBorderColor": "#2563EB",
    "lineColor": "#2563EB",
    "secondaryColor": "#EFF6FF",
    "tertiaryColor": "#DBEAFE",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "14px",
    "textColor": "#000000",

    "actorBkg": "#346DDB",
    "actorBorder": "#999999",
    "actorTextColor": "#ffffff",

    "signalColor": "#000000",
    "signalTextColor": "#696969",

    "labelBoxBkgColor": "#346DDB",
    "labelBoxBorderColor": "#2563EB"
  }
}}%%
sequenceDiagram
    participant Client
    participant Hyperswitch
    participant Processor

    Client->>Hyperswitch: POST /payments\n{confirm: true, capture_method: "automatic"}
    Hyperswitch->>Processor: Authorize + Capture
    Processor-->>Hyperswitch: Payment Complete
    Hyperswitch-->>Client: Status: succeeded
```

**Required Fields:**

* `confirm: true`
* `capture_method: "automatic"`
* `payment_method`

**Final Status:** `succeeded`

#### 2. Two-Step Manual Capture

**Use Case:** Deferred capture (e.g., ship before charging)

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#ffffff",
    "primaryBorderColor": "#2563EB",
    "lineColor": "#2563EB",
    "secondaryColor": "#EFF6FF",
    "tertiaryColor": "#DBEAFE",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "14px",
    "textColor": "#000000",

    "actorBkg": "#346DDB",
    "actorBorder": "#999999",
    "actorTextColor": "#ffffff",

    "signalColor": "#000000",
    "signalTextColor": "#696969",

    "labelBoxBkgColor": "#346DDB",
    "labelBoxBorderColor": "#2563EB"
  }
}}%%
sequenceDiagram
    participant Client
    participant Hyperswitch
    participant Processor

    Client->>Hyperswitch: POST /payments<br>{confirm: true, capture_method: "manual"}
    Hyperswitch->>Processor: Authorize Only
    Processor-->>Hyperswitch: Authorization Hold
    Hyperswitch-->>Client: Status: requires_capture

    Note over Client: Ship goods, then capture

    Client->>Hyperswitch: POST /payments/{id}/capture
    Hyperswitch->>Processor: Capture Funds
    Processor-->>Hyperswitch: Capture Complete
    Hyperswitch-->>Client: Status: succeeded
```

**Flow:**

1. **Authorize:** `POST /payments` with `capture_method: "manual"`
2. **Status:** `requires_capture`
3. **Capture:** `POST /payments/{payment_id}/capture`
4. **Final Status:** `succeeded`

Read more: [here](https://docs.hyperswitch.io/~/revisions/2M8ySHqN3pH3rctBK2zj/about-hyperswitch/payment-suite-1/payments-cards/manual-capture)

#### 3. Fully Decoupled Flow

**Use Case:** Complex checkout journeys with multiple modification steps. Useful in headless checkout or B2B portals where data is filled progressively.

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#ffffff",
    "primaryBorderColor": "#2563EB",
    "lineColor": "#2563EB",
    "secondaryColor": "#EFF6FF",
    "tertiaryColor": "#DBEAFE",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "14px",
    "textColor": "#000000",

    "actorBkg": "#346DDB",
    "actorBorder": "#999999",
    "actorTextColor": "#ffffff",

    "signalColor": "#000000",
    "signalTextColor": "#696969",

    "labelBoxBkgColor": "#346DDB",
    "labelBoxBorderColor": "#2563EB"
  }
}}%%
sequenceDiagram
    participant Client
    participant Hyperswitch

    Client->>Hyperswitch: POST /payments\n(Create Intent)
    Hyperswitch-->>Client: payment_id + client_secret

    Client->>Hyperswitch: POST /payments/{id}\n(Update: customer, amount, etc.)
    Hyperswitch-->>Client: Updated Intent

    Client->>Hyperswitch: POST /payments/{id}/confirm\n(Final Confirmation)
    Hyperswitch-->>Client: Status: succeeded / requires_capture

    opt Manual Capture
        Client->>Hyperswitch: POST /payments/{id}/capture
        Hyperswitch-->>Client: Status: succeeded
    end
```

**Endpoints:**

* **Create:** `POST /payments`
* **Update:** `POST /payments/{payment_id}`
* **Confirm:** `POST /payments/{payment_id}/confirm`
* **Capture:** `POST /payments/{payment_id}/capture` (if manual)

#### 4. 3D Secure Authentication Flow

**Use Case:** Enhanced security with customer authentication

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#ffffff",
    "primaryBorderColor": "#2563EB",
    "lineColor": "#2563EB",
    "secondaryColor": "#EFF6FF",
    "tertiaryColor": "#DBEAFE",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "14px",
    "textColor": "#000000",

    "actorBkg": "#346DDB",
    "actorBorder": "#999999",
    "actorTextColor": "#ffffff",

    "signalColor": "#000000",
    "signalTextColor": "#696969",

    "labelBoxBkgColor": "#346DDB",
    "labelBoxBorderColor": "#2563EB"
  }
}}%%
sequenceDiagram
    participant Client
    participant Hyperswitch
    participant Customer
    participant Bank

    Client->>Hyperswitch: POST /payments<br>{authentication_type: "three_ds"}
    Hyperswitch-->>Client: Status: requires_customer_action<br>+ redirect_url

    Client->>Customer: Redirect to 3DS page
    Customer->>Bank: Complete 3DS Challenge
    Bank-->>Hyperswitch: Authentication Result

     Hyperswitch-->>Hyperswitch: Resume Payment Processing

    Hyperswitch-->>Client: Status: succeeded
```

**Additional Fields:**

* `authentication_type: "three_ds"`

**Status Progression:** `processing` → `requires_customer_action` → `succeeded`

Read more: [here](https://docs.hyperswitch.io/~/revisions/9QlGypixZFcbkq8oGjaF/explore-hyperswitch/workflows/3ds-decision-manager)

### Recurring Payments and Payment Storage

#### 1. Saving Payment Methods

**During Payment Creation:**

* Add `setup_future_usage: "off_session"` or `"on_session"`
* Include `customer_id`
* **Result:** `payment_method_id` returned on success

**Understanding `setup_future_usage`:**

* **`on_session`**: Use when the customer is actively present during the transaction. This is typical for scenarios like saving card details for faster checkouts in subsequent sessions where the customer will still be present to initiate the payment (e.g., card vaulting for e-commerce sites).
* **`off_session`**: Use when you intend to charge the customer later without their active involvement at the time of charge. This is suitable for subscriptions, recurring billing, or merchant-initiated transactions (MITs) where the customer has pre-authorized future charges.

#### 2. Using Saved Payment Methods

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#ffffff",
    "primaryBorderColor": "#2563EB",
    "lineColor": "#2563EB",
    "secondaryColor": "#EFF6FF",
    "tertiaryColor": "#DBEAFE",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "14px",
    "textColor": "#000000",

    "actorBkg": "#346DDB",
    "actorBorder": "#999999",
    "actorTextColor": "#ffffff",

    "signalColor": "#000000",
    "signalTextColor": "#696969",

    "labelBoxBkgColor": "#346DDB",
    "labelBoxBorderColor": "#2563EB"
  }
}}%%
sequenceDiagram
    participant Client as Client
    participant HS as Hyperswitch

    Client->>HS: POST /payments/create<br/>{customer_id}
    HS-->>Client: client_secret

    Client->>HS: GET /customers/payment_methods<br/>{client_secret, publishable_key}
    HS-->>Client: List of payment_tokens

    Client->>HS: POST /payments/{id}/confirm<br/>{payment_token}
    HS-->>Client: Payment Result
```

**Steps:**

1. **Initiate:** Create payment with `customer_id`
2. **List:** Get saved cards via `GET /customers/payment_methods`
3. **Confirm:** Use selected `payment_token` in confirm call

#### PCI Compliance and `payment_method_id`

Storing `payment_method_id` (which is a token representing the actual payment instrument, which could be a payment token, network token, or payment processor token) significantly reduces your PCI DSS scope. Hyperswitch securely stores the sensitive card details and provides you with this token. While you still need to ensure your systems handle `payment_method_id` and related customer data securely, you avoid the complexities of storing raw card numbers. Always consult with a PCI QSA to understand your specific compliance obligations.

### Recurring Payment Flows

#### 3. Customer-Initiated Transaction (CIT) Setup

```mermaid
flowchart TD
    A[CIT Setup] --> B{Setup Type}
    B -->|With Charge| C[Amount > 0<br/>setup_future_usage:<br/>off_session]
    B -->|Zero Dollar Auth| D[Amount: 0<br/>payment_type:<br/>setup_mandate]
    C --> E[payment_method_id]
    D --> E

    classDef default fill:#3F8CFF,stroke:#3F8CFF,color:#ffffff,rx:6
    classDef accent fill:#3F8CFF,stroke:#3F8CFF,color:#ffffff,rx:6
    classDef decision fill:#FFF8E1,stroke:#CCCCCC,color:#1A1A1A
    class A accent
    class E accent
    class B decision
```

Read more: [here](https://docs.hyperswitch.io/~/revisions/j00Urtz9MpwPggJzRCsi/about-hyperswitch/payment-suite-1/payments-cards/recurring-payments)

#### 4. Merchant-Initiated Transaction (MIT) Execution

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#ffffff",
    "primaryBorderColor": "#2563EB",
    "lineColor": "#2563EB",
    "secondaryColor": "#EFF6FF",
    "tertiaryColor": "#DBEAFE",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "14px",
    "textColor": "#000000",

    "actorBkg": "#346DDB",
    "actorBorder": "#999999",
    "actorTextColor": "#ffffff",

    "signalColor": "#000000",
    "signalTextColor": "#696969",

    "labelBoxBkgColor": "#346DDB",
    "labelBoxBorderColor": "#2563EB"
  }
}}%%
sequenceDiagram
    participant Merchant as Merchant
    participant HS as Hyperswitch
    participant Processor as Processor

    Note over Merchant: Subscription billing trigger

    Merchant->>HS: POST /payments<br/>{off_session: true, recurring_details}
    HS->>Processor: Process with saved payment_method_id
    Processor-->>HS: Payment Result
    HS-->>Merchant: Status: succeeded
```

Read more: [here](https://docs.hyperswitch.io/~/revisions/j00Urtz9MpwPggJzRCsi/about-hyperswitch/payment-suite-1/payments-cards/recurring-payments)

### Status Flow Summary

```mermaid
stateDiagram-v2
    [*] --> RequiresConfirmation
    RequiresConfirmation --> Processing : confirm=true
    Processing --> RequiresCustomerAction : 3DS<br>needed       
    RequiresCustomerAction --> Processing : 3DS complete
    Processing --> RequiresCapture : manual capture
    Processing --> Succeeded : automatic capture
    Processing --> Failed : payment failed
    RequiresCapture --> Succeeded : capture API call
    RequiresCapture --> PartiallyCaptured : partial capture
    PartiallyCaptured --> [*]
    Succeeded --> [*]
    Failed --> [*]       
```

### Notes

* **Terminal States:** `succeeded`, `failed`, `cancelled`, `partially_captured` are terminal states requiring no further action
* **Capture Methods:** System supports `automatic` (funds captured immediately), `manual` (funds captured in a separate step), `manual_multiple` (funds captured in multiple partial amounts via separate steps), and `scheduled` (funds captured automatically at a future predefined time) capture methods.
* **Authentication:** 3DS authentication automatically resumes payment processing after customer completion
* **MIT Compliance:** Off-session recurring payments follow industry standards for merchant-initiated transactions


# Instant Payment (Auto Capture)

Authorize and capture a card payment in a single step — the simplest and most common one-time payment pattern.

### Overview

An instant payment charges the customer's card immediately upon confirmation. There is no separate capture step — authorization and capture happen together, and funds are settled without any additional action from your backend.

This is the right pattern for most standard checkout flows.

### How It Works

```mermaid
sequenceDiagram
    participant Client
    participant Hyperswitch
    participant Processor

    Client->>Hyperswitch: POST /payments\n{confirm: true, capture_method: "automatic"}
    Hyperswitch->>Processor: Authorize + Capture
    Processor-->>Hyperswitch: Payment Complete
    Hyperswitch-->>Client: Status: succeeded

```

1. Your backend calls `POST /payments` with `capture_method: "automatic"`
2. Hyperswitch returns a `client_secret`
3. You pass the `client_secret` to the frontend SDK and render Hyperswitch SDK.
4. The Hyperswitch SDK renders the payment form, collects card details, and calls `confirmPayment()` once the use clicks on the make payment button.
5. Hyperswitch sends request to payment process to authorizes and captures the payment in one step.
6. Processor sends the payment response to Juspay Hyperswitch, which is relayed back to merchant.

### SDK Integration

<details>

<summary>SDK Integration Steps</summary>

**Step 1 — Create the Payment (Backend)**

```bash
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

**Step 2 — Initialize SDK (Client-Side)**

The merchant client initializes the Hyperswitch SDK using the `client_secret` and `publishable_key`. The SDK fetches eligible payment methods from Hyperswitch and renders a secure payment UI.

```js
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({currency: "USD",amount: 100}),
  });
  const { clientSecret } = await response.json();
  
  // Initialise Hyperloader.js
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";
 
  let hyper; 
  script.onload = () => {
      hyper = window.Hyper("YOUR_PUBLISHABLE_KEY",{
      customBackendUrl: "YOUR_BACKEND_URL",
      //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
      })
      const appearance = {
          theme: "midnight",
      };
      const widgets = hyper.widgets({ appearance, clientSecret });
      const unifiedCheckoutOptions = {
          layout: "tabs",
          wallets: {
              walletReturnUrl: "https://example.com/complete",
              //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
          },
      };
      const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
      unifiedCheckout.mount("#unified-checkout");
  };
  document.body.appendChild(script);
}
```

**Step 3 — Collect Card Details**

The customer selects a card payment method and enters their card details directly within the Hyperswitch SDK-managed interface, ensuring sensitive data never passes through merchant systems.

**Step 4 —Authorize and Store Card**

The SDK submits a [`payments/confirm`](https://api-reference.hyperswitch.io/v1/payments/payments--confirm) request to Hyperswitch. Hyperswitch authorizes the payment with the processor.

**Step 5 — Return Status**

The final payment and vaulting status is returned to the SDK, which redirects the customer to the merchant's configured `return_url`.

</details>

### API Integration

<details>

<summary>API Integration Steps</summary>

**Step 1 — Create the Payment (Backend)**

```bash
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

**Step 2 — Confirm Payment**

The merchant client initializes the Hyperswitch SDK using the `client_secret` and `publishable_key`. The SDK fetches eligible payment methods from Hyperswitch and renders a secure payment UI.

```js
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({currency: "USD",amount: 100}),
  });
  const { clientSecret } = await response.json();
  
  // Initialise Hyperloader.js
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";
 
  let hyper; 
  script.onload = () => {
      hyper = window.Hyper("YOUR_PUBLISHABLE_KEY",{
      customBackendUrl: "YOUR_BACKEND_URL",
      //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
      })
      const appearance = {
          theme: "midnight",
      };
      const widgets = hyper.widgets({ appearance, clientSecret });
      const unifiedCheckoutOptions = {
          layout: "tabs",
          wallets: {
              walletReturnUrl: "https://example.com/complete",
              //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
          },
      };
      const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
      unifiedCheckout.mount("#unified-checkout");
  };
  document.body.appendChild(script);
}
```

**Step 3 — Collect Card Details**

The customer selects a card payment method and enters their card details directly within the SDK-managed interface, ensuring sensitive data never passes through merchant systems.

**Step 4 —Authorize and Store Card**

The SDK submits a [`payments/confirm`](https://api-reference.hyperswitch.io/v1/payments/payments--confirm) request to Hyperswitch. Hyperswitch authorizes the payment with the processor and securely stores the card in the Hyperswitch Vault, generating a reusable `payment_method_id`.

**Step 5 — Return Status**

The final payment status is returned to the SDK, which redirects the customer to the merchant's configured `return_url`.

</details>


# Manual Capture

Understand how to place a hold on your customers' funds and capture them later either fully or partially and either in one-go or multiple times

{% embed url="<https://youtu.be/XtOMZVhvLwQ>" %}

In most online payments use-cases, a merchant would want to capture the funds from their customers' accounts in one-step after the issuer authorizes the payment. This is called 'one-step' payments flow and at Juspay Hyperswitch we term this the 'Automatic Capture' flow.

But in some cases, merchants would like to place a hold on the customer's funds post authorization so that they can capture the funds at a later time once they deliver the goods and services. This is called the 'two-step' flow or 'Auth and Capture' flow in general payments parlance. Here at Hyperswitch, we call this the 'Manual Capture' flow.

### Benefits of Manual Capture

1. Improved Control: Funds are captured only after goods or services are delivered.
2. Flexibility: You can capture the full amount or a partial amount as per the delivery.
3. Customer Satisfaction: Builds trust by charging customers only after fulfilling the order.

### How to do Manual Capture?

#### Step 1 — Create [Payment](https://api-reference.hyperswitch.io/v1/payments/payments--create) with Deferred Capture

The 'capture\_method' field determines the type of capture for a particular payment and it defaults to 'automatic' if not passed. So, to do manual capture, set `"capture_method" = "manual"` when creating a payment from your server

**Sample curl:**

```bash
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <your_api_key>' \
--data '{
    "amount": 6540,
    "currency": "USD",
    "confirm": false,
    "capture_method": "manual",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "John"
        }
    }
}'
```

#### Step 2 — Confirm (Authorization Phase)

[Confirm](https://api-reference.hyperswitch.io/v1/payments/payments--confirm) the payment after collecting the payment\_method details from your customer and informing them that the funds in their account would be blocked and charged later once the goods and services are delivered. Unified checkout handles this for automatically. On successful authorization, the payment would transition to `'requires_capture'` status.

Note - You can mark `"confirm" = "true"` in the previous step and directly move to the capture flow.

**Sample curl:**

```bash
curl --location 'https://sandbox.hyperswitch.io/payments/<original_payment_id>/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <your_publishable_key>' \
--data '{
    "payment_method": "card",
    "client_secret": "<client_secret_of_the_original_payment>",
    "payment_method_data": {
        "card": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "card_cvc": "123"
        }
    }
}'
```

#### Step 3 — Capture Funds via [Capture API](https://api-reference.hyperswitch.io/v1/payments/payments--capture#payments-capture)

After delivering the goods and services, capture the payment by passing the `payment_id` from above step to `payments/capture` API endpoint. On successful capture, the payment would transition from `'requires_capture'` to `'succeeded'` status.

**Sample curl:**

```bash
curl --location 'https://sandbox.hyperswitch.io/payments/pay_At7O43TJJZyP7OmrcdQD/capture' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <your_api_key>' \
--data '{
    "amount_to_capture": 6540,
    "statement_descriptor_name": "Joseph",
    "statement_descriptor_suffix": "JS"
}'
```

### Capture types available :

#### **Full capture**

Capture the full amount that was authorized - Here the payments status transitions to 'SUCCEEDED' as soon the `payments/capture` API endpoint is executed for the `payment_id` .

#### **Partial Capture**

Capture only a partial amount from the total amount that was authorized. Once the transaction is executed, the status goes to either `partially_captured` or `partially_captured_and_capturable`

1. When capture method is manual & single capture is supported - `partially_captured`
2. When capture method is manual & multiple captures are supported - `partially_captured_and_capturable`<br>

Possible states:

| Connector Capability       | Resulting Status                    |
| -------------------------- | ----------------------------------- |
| Single capture only        | `partially_captured`                |
| Multiple capture supported | `partially_captured_and_capturable` |

#### Over Capture

Over Capture occurs when a merchant captures (settles) an amount greater than the originally authorized amount. You can find detailed docs [here](https://docs.hyperswitch.io/~/revisions/KHifKaZGv4c5XEloMvlu/about-hyperswitch/payment-suite-1/payments-cards/manual-capture/overcapture)


# Overcapture

Capture amounts greater than the originally authorized amount in manual capture payments

### Overview

In card payments, Over Capture occurs when a merchant captures (settles) an amount greater than the originally authorized amount.

This is particularly useful in scenarios such as:

* Additional charges (e.g., shipping, handling, gratuities).
* Price adjustments made after initial authorization.
* Reducing the risk of under-capturing when final order values differ.

### Enabling Over Capture

#### 1. Profile-level Configuration (via Dashboard)

* Navigate to:\
  Developer → Payment Settings → Always Enable Over Capture
* Toggle Enable/Disable as required.

#### 2. Per-request Configuration (via API)

Use the boolean field `enable_overcapture` in your payment request.

This can be passed in:

[POST /payments](https://api-reference.hyperswitch.io/v1/payments/payments--create)

[POST /payments/:id/update](https://api-reference.hyperswitch.io/v1/payments/payments--update)

{% hint style="warning" %}
**Note:**

* The request-level `enable_overcapture` will override the profile-level setting.
* Over Capture is only applicable for manual capture payments i.e. `capture_method = manual`.
  {% endhint %}

***

### Example: API Request

```json
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <your_publishable_key>' \
--data '{
  "amount": 100,
  "currency": "USD",
  "confirm": true,
  "capture_method": "manual",
  "enable_overcapture": true,
}'

```

### Example: API Response

```json
{
  "payment_id": "pay_GPnTPs4e56yZ8FKAcj0K",
  "status": "requires_capture",
  "amount": 100,
  "amount_capturable": 100,
  "connector": "adyen",
  "enable_overcapture": true,
  "is_overcapture_enabled": true,
  "capture_method": "manual",
  "payment_method": "card",
  "payment_method_type": "debit",
  "network_transaction_id": "112181545921495",
  "created": "2025-09-24T11:29:55.629Z",
  "expires_on": "2025-09-24T11:44:55.629Z"
}

```

#### Field Semantics

`enable_overcapture` Indicates merchant intent.

| Value   | Meaning                    |
| ------- | -------------------------- |
| `true`  | Over-capture requested     |
| `false` | Over-capture not requested |

***

`is_overcapture_enabled` Indicates connector capability acceptance.

| Value   | Meaning                                     |
| ------- | ------------------------------------------- |
| `true`  | Connector supports and enabled over-capture |
| `false` | Connector does not support over-capture     |

***

### Monitoring & Settlement

* After authorization, merchants can view the `amount_capturable` field (under More Payment Details) to see the maximum amount that can be captured.
* Once the payment is captured (or overcaptured), the final amount will be reflected in the `amount_received` field.

### Merchant Action

* Use Dashboard settings for global enablement
* Use API overrides for payment-specific enablement
* Monitor capturable and received amounts to track final settlements


# Subscriptions Management

Augment your subscriptions with payments orchestration capabilities

Businesses that run on subscription model powered by providers viz. Chargebee, Recurly, Stripe Billing etc. can now augment it with payments orchestration by decoupling the payments from the subscription provider and using them purely for subscription ledger and scheduling, while owning 100% of the card vaulting, payment attempts, and retry logic (owned in-house, or via an ensemble of specialized payment-focused orchestrator and other focused third parties, modularized to work with each other)

### Benefits

1. Greater control over payments with direct integrations and commercials with a range of Acquirers and Payment Processors
2. Improved reliability with a multi-PSP setup
3. Intelligent Routing capabilities to improve Authorization Rates and minimize Processing costs
4. Greater coverage of PMs, APMs and features offered by the PSPs
5. Centralised tokenisation of payment methods for PSP agnostic payments

### How does it work?

1. Integrate your subscription provider as a billing processor on Juspay Hyperswitch
2. Create and maintain plans on the subscription provider's dashboard
3. During the checkout process use Hyperswitch for Payments
4. Hyperswitch completes the payment, securely tokenises and stores the card
5. Subscription is created at Hyperswitch and at the subscription provider's end
6. First invoice is marked as paid and the subscription is activated
7. Subsequent billing cycles are handled independently by Hyperswitch through MIT payments
8. Failed MIT payments can be smartly retried by Hyperswitch ([read more](/other-features/payments-modules/revenue-recovery)) or by the solution provider of your choice.

### Flow Diagram

#### Initial Subscription create flow (with CIT Payment)

<figure><img src="/files/YEo8eKYquR2kTGbuqrF4" alt=""><figcaption></figcaption></figure>

#### MIT payment flow in subsequent billing cycle

<figure><img src="/files/i3cvhBsfe7pOZYhrXAXN" alt=""><figcaption></figcaption></figure>

### Integration Guide

#### 1. For non-PCI compliant merchants who wants to use Hyperswitch Payments SDK

**Initial Subscription create flow (with CIT Payment)**

{% stepper %}
{% step %}
Configure your Subscription Provider with Hyperswitch and set it as billing connector for the desired profile

*Note: Dashboard support for this configuration will be available soon*

{% code overflow="wrap" fullWidth="false" %}

```
curl --location 'http://<base_url>/account/<merchant_id>/connectors' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <api_key>' \
--data '{
    "connector_type": "billing_processor",
    "connector_name": "chargebee",
    "connector_account_details": {
        "auth_type": "HeaderKey",
        "api_key": "<api_key>",
        "site": ""
    },
    "business_country": "US",
    "business_label": "default",
    "connector_webhook_details": {
        "merchant_secret": "hyperswitch", 
        "additional_secret": "hyperswitch" 
    },
    "metadata": {
        "site": "test"
    }
}'

SET AS BILLING CONNECTOR
curl --location 'http://<base_url>/account/<merchant_id>/business_profile/<profile_id' \
--header 'Content-Type: application/json' \
--header 'api-key: <api_key>' \
--data '{
  "billing_processor_id": "<mca_id>"
}'
```

{% endcode %}
{% endstep %}

{% step %}
Configure Hyperswitch Webhook endpoint for invoice events on the subscription provider's dashboard
{% endstep %}

{% step %}
Fetch the plan details (to be setup prior on subscription provider)

```
curl --location 'http://<base_url>/subscriptions/plans' \
--header 'Content-Type: application/json' \
--header 'api-key: <api_key>'

Response:
[
    {
        "plan_id": "cbdemo_enterprise-suite",
        "name": "Enterprise Suite",
        "description": "High-end customer support suite with enterprise-grade solutions.",
        "price_id": [
            {
                "id": "cbdemo_enterprise-suite-INR-Daily",
                "name": "Enterprise Suite INR Daily",
                "pricing_model": "flat_fee",
                "price": 10000,
                "period": 1,
                "currency_code": "INR",
                "period_unit": "day",
                "free_quantity": 0,
            }]
       }
]

```

{% endstep %}

{% step %}
Display the retrieved Plan and Price Details to the user to make their selection
{% endstep %}

{% step %}
Once the user selects a particular Plan, create a customer on Hyperswitch ([API Reference](https://api-reference.hyperswitch.io/v1/customers/customers--create)) and create a subscription with the following API

```
curl --location '<baseurl>/subscriptions/create' \
--header 'Content-Type: application/json' \
--header 'X-Profile-Id: <profile_id>' \
--header 'api-key: <api-key>' \
--data '{
    "customer_id": "cus_uBtUJLSVSICr8ctmoL8i",
    "amount": 14100,
    "currency": "USD",
    "payment_details": {
        "authentication_type": "no_three_ds",
        "setup_future_usage": "off_session",
        "capture_method": "automatic",
        "return_url": "https://google.com"
    }
}'
```

{% endstep %}

{% step %}
Initiate the Hyperswitch unified checkout SDK using the `client_secret` returned in the `/subscriptions/create` API response

{% hint style="info" %}
When setting up subscription there are two distinct implementation flows.

The correct flow depends on whether you intend to charge the customer immediately or simply validate their details for later use.

**1. The Setup with Charge Flow**

**Use Case:** Use this when you need to collect a payment immediately (e.g., the first month of a subscription or a setup fee) while simultaneously saving the card details for future automatic charges.

**Configuration Parameters :**

* `setup_future_usage: "off_session"`
* `amount > 0`

**2. The Zero Dollar Authorization Flow**

**Use Case:** Use this for free trials, pay-later models, or delayed billing. This flow validates the payment method details without charging the customer's card.

**Configuration Parameters :**

* Pass below parameters while calling payments API for [Zero Dollar Auth](https://docs.hyperswitch.io/explore-hyperswitch/payment-orchestration/quickstart/tokenization-and-saved-cards/zero-amount-authorization-1)
* `setup_future_usage: "off_session"`
* `amount: 0`
* `payment_type: "setup_mandate"`
  {% endhint %}
  {% endstep %}

{% step %}
Once the customer selects a payment method and enters the details and confirms the subscription, hit the `/subscriptions/:id/confirm` using a similar [implementation as this](/integration-guide/payment-suite/payment-method-card/web/react-with-rest-api-integration)
{% endstep %}

{% step %}
Sync with the subscription status for disbursement of services and future billing cycles
{% endstep %}
{% endstepper %}

#### 2. For PCI Compliant merchants handling the entire checkout experience

{% stepper %}
{% step %}
Follow the same steps as above to create a billing connector, fetch plan details and display the retrieved Plan and Price Details to the user to make their selection
{% endstep %}

{% step %}
Once the user selects a particular Plan, create a customer on Hyperswitch ([API Reference](https://api-reference.hyperswitch.io/v1/customers/customers--create)), initiate checkout and collect payment method details
{% endstep %}

{% step %}
After the user enter card/PM details and confirms the payment, hit the Hyperswitch Subscriptions API

{% hint style="info" %}
When setting up subscription there are two distinct implementation flows.

The correct flow depends on whether you intend to charge the customer immediately or simply validate their details for later use.

**1. The Setup with Charge Flow**

**Use Case:** Use this when you need to collect a payment immediately (e.g., the first month of a subscription or a setup fee) while simultaneously saving the card details for future automatic charges.

**Configuration Parameters :**

* `setup_future_usage: "off_session"`
* `amount > 0`

**2. The Zero Dollar Authorization Flow**

**Use Case:** Use this for free trials, pay-later models, or delayed billing. This flow validates the payment method details without charging the customer's card.

**Configuration Parameters :**

* Pass below parameters while calling payments API for [Zero Dollar Auth](https://docs.hyperswitch.io/explore-hyperswitch/payment-orchestration/quickstart/tokenization-and-saved-cards/zero-amount-authorization-1)
* `setup_future_usage: "off_session"`
* `amount: 0`
* `payment_type: "setup_mandate"`
  {% endhint %}

```
curl --location 'http://<baseurl>/subscriptions/' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Profile-Id: pro_2WzEeiNyj8fSCObXqo36' \
--header 'api-key: dev_Ske75Nx2J7qtHsP8cc7pFx5k4dccYBedM6UAExaLOdHCkji3uVWSqfmZ0Qz0Tnyj' \
--data '{
    "item_price_id": "cbdemo_enterprise-suite-INR-Daily",
    "customer_id": "cus_NdHhw4wwWyYXSldO9oYE",
    "billing_address": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "payment_details": {
        "payment_method": "card",
        "payment_method_type": "credit",
        "payment_method_data": {
            "card": {
                "card_number": "4242424242424242",
                "card_exp_month": "10",
                "card_exp_year": "25",
                "card_holder_name": "joseph Doe",
                "card_cvc": "123"
            }
        },
        "setup_future_usage": "off_session",
        "customer_acceptance": {
            "acceptance_type": "online",
            "accepted_at": "1963-05-03T04:07:52.723Z",
            "online": {
                "ip_address": "127.0.0.1",
                "user_agent": "amet irure esse"
            }
        }
    }
}'

```

Response:

```
{
  "id": "subscription_wBV1G9dhh6EBhTOTXRBA",
  "merchant_reference_id": null,
  "status": "active",
  "plan_id": null,
  "price_id": null,
  "coupon": null,
  "profile_id": "profile_id",
  "payment": null,
  "customer_id": "customer_id",
  "invoice": {
    "id": "invoice_0XANlbhMp2V7wUvWRhhJ",
    "subscription_id": "subscription_wBV1G9dhh6EBhTOTXRBA",
    "merchant_id": "merchant_id",
    "profile_id": "profile_id",
    "merchant_connector_id": "mac_id",
    "payment_intent_id": null,
    "payment_method_id": null,
    "customer_id": "cus_id",
    "amount": 14100,
    "currency": "INR",
    "status": "InvoiceCreated"
  }
}
```

{% endstep %}

{% step %}
Sync with the status of the Subscription API to disburse services to subscribed users

{% code overflow="wrap" %}

```
curl --location 'http://<baseurl>/subscriptions/<subscripion_id>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Profile-Id: <profile_id>' \
--header 'api-key: <api_key>'

RESPONSE:
{
    "id": "<subcription_id>",
    "merchant_reference_id": "mer_ref_id",
    "status": "active",
    "plan_id": null,
    "profile_id": "<profile_id>",
    "merchant_id": "<merchant_id>",
    "coupon_code": null,
    "customer_id": "<customer_id>"
}
```

{% endcode %}
{% endstep %}

{% step %}
Monitor incoming webhooks for renewal during subsequent cycles
{% endstep %}
{% endstepper %}

### Decoupled CIT and MIT Flow

Hyperswitch supports decoupled transaction flows, allowing Merchant-Initiated Transactions (MITs) to be processed independently of the original Customer-Initiated Transaction (CIT), even when the CIT was completed outside the Hyperswitch platform.

MITs are initiated by invoking the [`/payments`](https://api-reference.hyperswitch.io/v1/payments/payments--create) API with `off_session: true` and providing the available reference data in the `recurring_details` object. Depending on the artifacts available in your system, one of the following approaches can be used:

[**Processor Payment Token**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#option-3) **:** Submit a processor-issued token that represents the previously authorized payment instrument.

[**Network Transaction ID with Card Data**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#option-4) : Provide the original network transaction identifier along with the associated primary card data required for authorization.

[**Network Transaction ID with Network Token**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#option-5) **:** Submit the network transaction identifier in combination with the corresponding network tokenized card credentials.

[**Limited Card Data**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#option-6) **:** Use a reduced card data set captured at the time of subscription creation to authorize subsequent MITs.

### FAQs

#### 1. What are subscriptions providers that are currently supported?

Currently we support Chargebee integration. In the upcoming roadmap we are planning to extend support for Recurly, Stripe Billing and Zuora

#### 2. Can the entire experience from plan display, price estimation to payments be handled by Hyperswitch SDK?

We are planning to release a Hyperswitch Subscriptions SDK that will take care of the end-to-end experience.


# Saving Payment Method

Setting up and managing recurring payments

Juspay Hyperswitch supports the following ways of saving a payment method used in a successful payment:

1. Saving for future customer on-session payments (COF-CIT)
2. Saving for future customer off-session payments (MIT)

### Saving a payment method for future on-session payments (COF CIT)

To improve conversion rates and eliminate friction for the customer during checkout, you can save the customer's card so that they wouldn't have to enter the card details every time. This also minimises the risk of the customer entering incorrect card details.

Saving for future on-session payments implies that the customer will be available online during the checkout and can authenticate the payment by entering CVV or complete 3DS verification. These are known as Card-on-File Customer Initiated Transactions (COF-CIT).

This is typically limited for card payment methods and not for wallets (viz. Apple Pay) and other APMs.

### To save a customer's payment method used in a successful transaction for future CIT payments:

<details>

<summary>Follow Steps for SDK integration</summary>

Pass the following field in the `/payments` create request to indicate your intention to save the payment method

```bash
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "setup_future_usage":"on_session", 
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

{% hint style="info" %}
**Note:** Ensure to enable this functionality using the [*displaySavedPaymentMethodsCheckbox*](https://docs.hyperswitch.io/hyperswitch-cloud/integration-guide/web/customization#id-6.-handle-saved-payment-methods) property during SDK integration
{% endhint %}

If you are using the Hyperswitch SDK, the `customer_acceptance` is sent in the `/payments/:id:/confirm` request on the basis of customer clicking the save card radio button

<figure><img src="/files/xmu3qJ2kFQrfT1NaIHmN" alt="" width="375"><figcaption><p>The customer's consent to save their card is expressed through this checkbox</p></figcaption></figure>

</details>

<details>

<summary>Follow Steps For API Integration</summary>

**Step 1 --**

Pass the following field in the `/payments` create request to indicate your intention to save the payment method

```bash
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "setup_future_usage":"on_session", 
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

**Step 2 --**

During the payment confirm call pass the customer's consent to store the card in the request

```bash
"customer_acceptance": {
        "acceptance_type": "online",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "user_agent": "amet irure esse"
        }
    }
```

</details>

***

### Saving a payment method for future MIT payments

Let's say, you want to save a customer's payment method to charge them at a later point without the need for additional cardholder authentication. This is done by raising an MIT (Merchant Initiated Transaction) exemption to the card network by the payment processor with reference to an initial transaction where the customer has authorised recurring charges. These are typically used when you want to charge a customer periodically/sporadically with a flexibility on the amount to be charged and number of charges.

Based on the payment processors support, this functionality is also available for other payment methods like Apple Pay and Google Pay Wallets.

#### To save a customer's payment method used in a successful transaction for future MIT payments:

<details>

<summary>Follow Steps for SDK integration</summary>

Pass the following field in the `/payments` create request to indicate your intention to save the payment method

```bash
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "setup_future_usage":"off_session", 
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

If you are using the Hyperswitch SDK, the `customer_acceptance` is sent in the `/payments/:id:/confirm` request on the basis of customer clicking the save card radio button

{% hint style="info" %}
**Note:** Ensure to enable this functionality using the [*displaySavedPaymentMethodsCheckbox*](https://docs.hyperswitch.io/hyperswitch-cloud/integration-guide/web/customization#id-6.-handle-saved-payment-methods) property during SDK integration
{% endhint %}

Retrieve the `payment_method_id` that was created against the above payment by retrieving the payment. You will get the payment\_method\_id in the response. Store this ID for making subsequent MIT payments.

```bash
curl --location 'https://sandbox.hyperswitch.io/payments/<pass the payment_id>' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
```

</details>

<details>

<summary>Follow Steps for API integration</summary>

Pass the following field in the `/payments` create request to indicate your intention to save the payment method

```bash
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "setup_future_usage":"off_session", 
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

During the payment confirm call pass the customer's consent to store the card in the request

```bash
"customer_acceptance": {
        "acceptance_type": "online",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "user_agent": "amet irure esse"
        }
    }
```

Retrieve the `payment_method_id` that was created against the above payment by retrieving the payment. You will get the payment\_method\_id in the response. Store this ID for making subsequent MIT payments.

```bash
curl --location 'https://sandbox.hyperswitch.io/payments/<pass the payment_id>' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
```

</details>

***

### Using a saved payment method to do a MIT payment

Once a customer's payment method is saved for MIT payments you can start charging the customer by sending the following details in the `/payments` request

<pre class="language-bash"><code class="lang-bash"><strong>"off_session": true,
</strong>"recurring_details": {
        "type": "payment_method_id",
        "data": "pm_lmTnIO5EdCiiMgRPrV9x" //pass the payment method id here
}
</code></pre>

You would be using the same `payment_method_id` that was returned in the `/payments/:id:/retrieve` response for the initial transaction where the customer authorized saving for future use.

To get all the payment methods saved for a customer use the[ List Customer Payment Methods](https://api-reference.hyperswitch.io/v1/payment-methods/list-payment-methods-for-a-customer) API.

```bash
curl --request GET \
  --url https://sandbox.hyperswitch.io/customers/{customer_id}/payment_methods \
  --header 'api-key: <api-key>'
```

***

### Processing MIT Payments Without a Saved Payment Method

If a merchant is PCI-compliant and has the customer payment method details stored, an MIT payment can be performed by passing the card details and the network transaction id directly in the confirm call.

<pre class="language-bash"><code class="lang-bash"><strong>"off_session": true,
</strong>"recurring_details": {
        "type": "network_transaction_id_and_card_details",
        "data": {
            "card_number": "4242424242424242",
            "card_exp_month": "10",
            "card_exp_year": "25",
            "card_holder_name": "joseph Doe",
            "network_transaction_id": "MCC5ZRGMI0925" //scheme transaction id
        }
}
</code></pre>

***


# Saved Card

Secure card vaulting with Hyperswitch SDK for PCI-DSS compliant payment processing

In this approach, the Juspay Hyperswitch SDK is used on the frontend to capture card details. Card data is securely sent to the Hyperswitch backend and stored in Hyperswitch Vault. Payment orchestration, routing, and connector logic are handled entirely by the Hyperswitch backend.

The merchant uses the Hyperswitch Dashboard to configure connectors, routing rules, and orchestration logic. All payment requests are initiated using vault tokens, and raw card data never reaches merchant systems. Since card details are handled entirely by Hyperswitch, merchants are not required to be PCI DSS compliant for card data handling.

### **New User (Payments SDK)**

<figure><img src="/files/By9b40cOAJMYCC934PX7" alt=""><figcaption></figcaption></figure>

#### **1. Create Payment (Server-Side)**

The merchant server creates a payment by calling the Hyperswitch [`payments/create`](https://api-reference.hyperswitch.io/v1/payments/payments--create) API with transaction details such as amount and currency. Hyperswitch responds with a `payment_id` , `customer_id` and `client_secret`, which are required for client-side processing.

```bash
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

{% hint style="info" %}
Note - In case the merchant does not pass the customer ID, then the transaction is treated as a Guest customer checkout
{% endhint %}

#### **2. Initialize SDK (Client-Side)**

The merchant client initializes the Hyperswitch SDK using the `client_secret` and `publishable_key`. The SDK fetches eligible payment methods from Hyperswitch and renders a secure payment UI.

```js
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({currency: "USD",amount: 100}),
  });
  const { clientSecret } = await response.json();
  
  // Initialise Hyperloader.js
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";
 
  let hyper; 
  script.onload = () => {
      hyper = window.Hyper("YOUR_PUBLISHABLE_KEY",{
      customBackendUrl: "YOUR_BACKEND_URL",
      //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
      })
      const appearance = {
          theme: "midnight",
      };
      const widgets = hyper.widgets({ appearance, clientSecret });
      const unifiedCheckoutOptions = {
          layout: "tabs",
          wallets: {
              walletReturnUrl: "https://example.com/complete",
              //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
          },
      };
      const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
      unifiedCheckout.mount("#unified-checkout");
  };
  document.body.appendChild(script);
}
```

#### **3. Collect Card Details**

The customer selects a card payment method and enters their card details directly within the SDK-managed interface, ensuring sensitive data never passes through merchant systems.

#### **4. Authorize and Store Card**

The SDK submits a [`payments/confirm`](https://api-reference.hyperswitch.io/v1/payments/payments--confirm) request to Hyperswitch. Hyperswitch authorizes the payment with the processor and securely stores the card in the Hyperswitch Vault, generating a reusable `payment_method_id`.

#### **5. Return Status**

The final payment and vaulting status is returned to the SDK, which redirects the customer to the merchant's configured `return_url`.

### **Returning or Repeat User (Payments SDK)**

<figure><img src="/files/2HcpIYH6RoZKDNyMeF2d" alt=""><figcaption></figcaption></figure>

#### **1. Create Payment (Server-Side)**

The merchant server initiates the payment by calling the [`payments/create`](https://api-reference.hyperswitch.io/v1/payments/payments--create) API with transaction details such as amount and currency. Hyperswitch responds with a `payment_id` , `customer_id` and `client_secret`, which are required for client-side processing.

```json
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

{% hint style="info" %}
Note -The merchant needs to pass the same customer ID for the SDK to fetch the saved customer payment methods and display them\
\
In case the merchant is not using the SDK then they need to use the List Customer Saved Payment Methods API to fetch the stored payment methods against a customer
{% endhint %}

#### **2. Initialize SDK and Fetch Saved Cards**

The merchant client initializes the Hyperswitch SDK. The SDK requests eligible payment methods from Hyperswitch, including any saved cards associated with the customer.

```js
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({currency: "USD",amount: 100}),
  });
  const { clientSecret } = await response.json();
  
  // Initialise Hyperloader.js
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";
 
  let hyper; 
  script.onload = () => {
      hyper = window.Hyper("YOUR_PUBLISHABLE_KEY",{
      customBackendUrl: "YOUR_BACKEND_URL",
      //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
      })
      const appearance = {
          theme: "midnight",
      };
      const widgets = hyper.widgets({ appearance, clientSecret });
      const unifiedCheckoutOptions = {
          layout: "tabs",
          wallets: {
              walletReturnUrl: "https://example.com/complete",
              //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
          },
      };
      const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
      unifiedCheckout.mount("#unified-checkout");
  };
  document.body.appendChild(script);
}
```

#### **3. Customer Selects a Saved Card**

The SDK displays the saved cards in the payment UI, customer enters the CVV.

#### **4. Retrieve Card Data and Authorize**

The SDK sends a [`payments/confirm`](https://api-reference.hyperswitch.io/v1/payments/payments--confirm) request with the selected `payment_method_id`. Hyperswitch securely retrieves the card data from the Hyperswitch Vault and submits the authorization request to the processor via the Hyperswitch Connector.

#### **5. Return Status**

The processor returns the authorization result to Hyperswitch, which forwards the final status to the SDK. The customer is redirected to the merchant's `return_url` with the payment outcome.

#### Integration Guide :

[Unified Checkout](https://docs.hyperswitch.io/~/revisions/DXTxY8PvOykOfdbFcGmW/explore-hyperswitch/payment-experience/payment/web)

[Payments API](https://api-reference.hyperswitch.io/v1/payments/payments--create)


# Recurring payments

Set up and manage recurring payments with Card-on-File and MIT support

Recurring payments via Juspay Hyperswitch can be setup by passing some additional flags, as highlighted below. The recurring payments are not tied to a specific amount or cycle and the merchant can charge the end-user as per their own business requirements.

### Programmatic Card-on-File Setup with Immediate Charge (CIT + Save)

When setting up subscription there are two distinct implementation flows. The correct flow depends on whether you intend to charge the customer immediately or simply validate their details for later use.

#### 1. The Setup with Charge Flow

**Use Case:** Use this when you need to collect a payment immediately (e.g., the first month of a subscription or a setup fee) while simultaneously saving the card details for future automatic charges. For this call Payments API with the below configuration parameters.

**Required API Configuration**

Include below parameter and values while calling the [payments](https://api-reference.hyperswitch.io/v1/payments/payments--create) API.

| Parameter            | Value                  |
| -------------------- | ---------------------- |
| `amount`             | >0 (Greater than zero) |
| `setup_future_usage` | `off_session`          |

**Run-Ready API Example (CIT with Charge)**

```json
curl --location 'https://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "amount": 6540,
    "currency": "USD",
    "profile_id": <enter the relevant profile id>,
    "setup_future_usage":"off_session", 
    "customer_id": "customer123",
    "description": "Its my first payment request",
    "return_url": "https://example.com", // 
}'
```

#### 2. Zero Dollar Authorization (Mandate-Only Setup)

**Use Case:** Use this for free trials, pay-later models, or delayed billing. This flow validates the payment method details without charging the customer's card.

**Required API Configuration**

Pass below parameters while calling payments API for [Zero Dollar Auth](https://docs.hyperswitch.io/explore-hyperswitch/payment-orchestration/quickstart/tokenization-and-saved-cards/zero-amount-authorization-1)

| Parameter            | Value          |
| -------------------- | -------------- |
| `setup_future_usage` | `off_session`  |
| `amount`             | `0`            |
| `payment_type`       | `payment_type` |

**Run-Ready API Example (Zero Auth Mandate)**

```json
curl --location 'http://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
"amount": 0,
"currency": "USD",
"confirm": false,
"customer_id": "zero_auth_test_customer",
"email": "m.arjunkarthik@gmail.com",
"name": "John Doe",
"phone": "999999999",
"phone_country_code": "+1",
"description": "Its my first payment request",
"profile_id": <enter the relevant profile id>,
"setup_future_usage": "off_session"
}'
```

Once the CIT is successful, Hyperswitch returns a `payment_method_id` . This `payment_method_id` can be used by the merchant for all subsequent MIT recurring payments. Hyperswitch also returns the `network_transaction_id` (NTID) in its response to allow PICI compliant merchants to direct pass card + NTID for processing MIT recurring payments

The `payment_method_id` serves as a unique identifier mapped to a specific combination of a Customer ID and a unique Payment Instrument (e.g., a specific credit card, digital wallet, or bank account). A single customer can have multiple payment methods, each assigned a distinct ID. However, the same payment instrument used by the same customer will always resolve to the same `payment_method_id`. This uniqueness applies across all payment types, including cards, wallets, and bank details.

For example, you can refer the below table -

| **Customer ID** | **Payment Instrument**            | **Payment Method ID** |
| --------------- | --------------------------------- | --------------------- |
| 123             | Visa ending in 4242               | `PM1`                 |
| 123             | Mastercard ending in 1111         | `PM2`                 |
| 456             | Visa ending in 4242               | `PM3`                 |
| 123             | PayPal Account (`user@email.com`) | `PM4`                 |

Internally the payment\_method\_id is mapped to a bunch of credentials - PSP token, Raw card + NTID, Network token + NTID depending on functionalities enabled for the merchant.

### Customer Consent Capture (Mandate Compliance)

If you are not using Hyperswitch SDK, then `customer_acceptance` (customer's consent)is required along with the other parameters [confirm](https://api-reference.hyperswitch.io/v1/payments/payments--confirm) request to store the card.

```bash
"customer_acceptance": {
        "acceptance_type": "online",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "user_agent": "amet irure esse"
        }
    }
```

If you are using the Hyperswitch SDK, the `customer_acceptance` is sent in the [confirm](https://api-reference.hyperswitch.io/v1/payments/payments--confirm) request on the basis of customer clicking the save card radio button

**Note:** Ensure to enable this functionality using the [*displaySavedPaymentMethodsCheckbox*](https://docs.hyperswitch.io/hyperswitch-cloud/integration-guide/web/customization#id-6.-handle-saved-payment-methods) property during SDK integration

***

### Merchant-Initiated Transactions (MIT) – Decoupled Execution

Hyperswitch supports decoupled transaction flows, allowing Merchant-Initiated Transactions (MITs) to be processed independently of the original Customer-Initiated Transaction (CIT), even when the CIT was completed outside the Hyperswitch platform.

MITs are initiated by invoking the [`/payments`](https://api-reference.hyperswitch.io/v1/payments/payments--create) API with `off_session: true` and providing the available reference data in the `recurring_details` object. Depending on the artifacts available in your system, one of the following approaches can be used:

#### [**Payment Method ID**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#body-recurring-details)

Submit the Hyperswitch generated payment\_method\_id to process the MIT transaction. Depending on the merchant configurations the MIT will be processed with the same PSP or with a different PSP.

#### [**Processor Payment Token**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#option-3)

Submit a processor-issued token that represents the previously authorized payment instrument.

#### [**Network Transaction ID with Card Data**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#response-network-transaction-id-one-of-0)

Provide the original network transaction identifier along with the associated primary card data required for authorization.

{% hint style="info" %}
⚠️ **PSP Configuration Required**

This feature is not enabled by default and must be explicitly enabled by PSP.

You may receive errors such as `Received unknown parameter: payment_method_options[card][mit_exemption]`, follow the steps below to request activation.

Email the PSP Support requesting:

* Access to the `mit_exemption` parameter for MIT (Merchant Initiated Transaction) payments
* Ability to pass `network_transaction_id` in the parameter: `payment_method_options[card][mit_exemption][network_transaction_id]`
* Explain your use case: enabling cross-processor MIT payments using network transaction IDs from card schemes
  {% endhint %}

#### [**Network Transaction ID with Network Token**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#option-5) **:**

Submit the network transaction identifier in combination with the corresponding network tokenized card credentials.

#### [**Limited Card Data**](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#option-6) **:**

Use a reduced card data set captured at the time of subscription creation to authorize subsequent MITs.

***

### Connector-Agnostic MIT Routing

The CIT used to set up recurring payments via MIT uses the PG token. This introduces a connector stickiness since the recurring payments can only go through the connector which issued the token.

To mitigate this we would be storing the Network Transaction ID which will be a chaining identifier for the CIT in which the payment method was saved for off-session payments.

In the following MIT payments basis the enablement of the feature and the availability of Network Transaction ID Hyperswitch will route your payments to the eligible set of connectors. (This will also be used for retries).

```mermaid
flowchart TD
  start([pg_agnostic_mandate])
  enabled[enabled]
  disabled[disabled]
  check{Check if Network Reference ID is stored against that mandate}
  route[Decide connector after Routing]
  retrieve[Retrieve Card from locker]
  mit1[MIT using raw card details and n/w reference ID]
  mit2[MIT using mandate_id via the original connector]
  mit3[MIT using mandate_id via the original connector]

  start --> enabled
  start --> disabled
  enabled --> check
  disabled --> mit3
  check -->|Present| route
  check -->|Not Present| mit2
  route --> retrieve
  retrieve --> mit1

  classDef default fill:#3F8CFF,stroke:#3F8CFF,color:#ffffff,rx:6
```

#### Enabling Connector agnostic MITs

To start routing MIT payments across all supported connectors in addition to the connector through which the recurring payment was set up, use the below API to enable it for a business profile

```bash
curl --location 'http://sandbox.hyperswitch.io/account/:merchant_id/business_profile/:profile_id/toggle_connector_agnostic_mit' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: api_key' \
--data '{
    "enabled": true
}'
```

All the payment methods saved with `setup_future_usage : off_session` after enabling this feature would now be eligible to be routed across the list of supported connectors during the subsequent MIT payments

***

### Routing example - CITs are routed through PSP-1 and all MITs through PSP-2

The [Hyperswitch dashboard](https://app.hyperswitch.io/dashboard/routing/rule) provides UI to configure routing rules for PG Agnostic Recurring Payments. You can choose the profile for which you wish to configure the rule in the Smart Routing Configuration.

Then, you can configure the rule as shown below using the metadata field in the Rule-Based Configuration.

<figure><img src="/files/SkAigJ7MvYl90kvrMzn2" alt=""><figcaption></figcaption></figure>

This rule would be used in conjunction with the other active routing rules that you have configured.

Once the rule is configured, you would need to send the following metadata as per the payment request:

#### **Metadata to be sent in CITs**

```
"metadata": {
    "is_cit": "true"
}
```

#### **Metadata to be sent in MITs**

```
"metadata": {
    "is_mit": "true"
}
```

According to the above configured rule all the CITs for the specific business profile should be routed through Stripe and MITs through Adyen.


# Authorizations

Overview of specialized authorization flows including zero-auth, estimate, incremental, extended, and partial authorizations

### **Advanced Authorization Types**

This section outlines the specialized authorization flows supported by Juspay Hyperswitch. These methods allow you to verify payment instruments or manage fluctuating transaction totals without requiring the customer to re-enter their details.

**1. $0 Authorization (Account Verification)**

Commonly used for card-on-file or subscription setups, this flow verifies that a payment method is valid and active without actually blocking any funds. It is an essential step for "Save Card" features to ensure the payment\_method\_id is linked to a legitimate account before future use.

**2. Estimate Authorization**

This allows a business to block a calculated amount on a customer's card based on an expected total, such as a hotel stay or a car rental deposit. It ensures the customer has sufficient credit available before the service is rendered, providing a safety net for the merchant.

**3. Incremental Authorization**

If the final cost exceeds the initial estimate (e.g., a guest extends their stay or adds room service), this flow allows you to increase the authorized amount on the existing transaction. It avoids the need for a completely new transaction, keeping the checkout experience seamless and consolidated.

**4. Extended Authorization**

Standard authorizations typically expire within 3 to 7 days; however, Extended Authorization keeps the hold active for a longer duration. This is ideal for businesses with long lead times, such as custom-manufactured goods or pre-orders, where shipping might occur weeks after the initial order.

**5. Partial Authorization**

In scenarios where a customer's card balance is lower than the total purchase amount, a Partial Authorization allows you to capture the remaining available balance. The customer can then cover the difference using a secondary payment method, effectively preventing a total transaction decline.


# Incremental Authorization

Request additional funds after initial authorization for variable-cost transactions

Generally for any payment transaction, the payable amount from the payment request is authorized and then captured. But in some situations like hotel bookings, car rentals, or services where the final cost is uncertain, we might need to increase the authorized amount.

Incremental authorization in Juspay Hyperswitch allows merchants to request additional funds after the initial authorization, giving them the flexibility to handle changing costs without disrupting the customer's payment experience.

### Why is it important?

Incremental authorization extends the ability to request more funds beyond the original authorized amount, which is perfect for aforementioned situations like hotel bookings, car rentals, or services where the final cost is uncertain. Hyperswitch enables merchants to easily add charges during the checkout process without affecting the user journey for re-authorization.

### How Incremental Authorization Helps Businesses?

Incremental authorization can help businesses to fulfill the following use-cases:

* **Adjust Payments in Real-Time**: Handle unexpected increases in charges, such as additional services or extended stays without redirecting customers for re-authorization.
* **Improve Customer Experience**: Avoid disruptions in the payment process, as customers do not need to reauthorize or re-enter their payment information.
* **Streamline Settlements**: Hyperswitch combines the initial charge and all incremental authorizations into a single settlement, simplifying reconciliation.

### Pre-requisites

1. Ensure that your business operates in a region without Strong Customer Authentication (SCA) requirements, as incremental authorizations are only possible in such environments.
2. This feature is limited to card payments and specific networks, with rules that vary depending on the payment connector used.

### How to use Incremental Authorization through Hyperswitch?

**Step 1:** To use Incremental authorization you can set the value of the [request\_incremental\_authorization](https://api-reference.hyperswitch.io/v1/payments/payments--create) field to true in the payments/create API call.

```
curl --request POST \
  --url https://sandbox.hyperswitch.io/payments \
  --header 'Content-Type: application/json' \
  --header 'api-key: <api-key>' \
  --data '{
  "amount": 6540,
  "authentication_type": "three_ds",
  "currency": "USD",
  "request_incremental_authorization": "true"
}'
```

**Step 2:** In the response, you can find whether the connector allows the Incremental authorization for that particular payment intent or not, refer to [incremental\_authorization\_allowed](https://api-reference.hyperswitch.io/v1/payments/payments--create) field in API response.

**Step 3:** Use the below curl to make the Incremental authorization requests.

```
curl --request POST \
  --url https://sandbox.hyperswitch.io/payments/{payment_id}/incremental_authorization \
  --header 'Content-Type: application/json' \
  --header 'api-key: <api-key>' \
  --data '{
  "amount": 6540,
  "reason": "<string>"
}'
```


# $0 Authorization

Best way to validate customer payment data and charge the customer later

{% hint style="info" %}
In this section, we will understand zero-auth flow, it's usage, and webhook consumption
{% endhint %}

The zero amount authorization flow in Juspay Hyperswitch allows the merchant to validate customer payment data and charge the customer later. On customer registration, the merchant can initiate a zero-auth flow transaction with Hyperswitch to authenticate the customer payment method (card, bank account etc.) and receive authorization from the customer to use the payment method to charge them at a later point. A payment\_method\_id would be created and issued to the merchant. And in the future they can charge against this payment\_method\_id.

The following API cURLs demonstrate the usage of the zero-auth flow. The example below uses the credit card payment method. But this can be extended to bank debits and other payment methods as well.

### How to use the zero amount authorization flow?

1. Creating a 0 amount payment along with `setup_future_usage= off_session` to set up a mandate to store and charge the customer's payment method later **( Called as 'CIT' : Customer initiated transaction)**

```shell
curl --location 'http://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
"amount": 0,
"currency": "USD",
"confirm": false,
"customer_id": "zero_auth_test_customer",
"email": "m.arjunkarthik@gmail.com",
"name": "John Doe",
"phone": "999999999",
"phone_country_code": "+1",
"description": "Its my first payment request",
"profile_id": <enter the relevant profile id>,
"setup_future_usage": "off_session"
}'
```

2. Confirm the payment after collecting payment information from the user **\[You can skip this step if you are using the Hyperswitch Unified Checkout]**

```bash
curl --location 'http://sandbox.hyperswitch.io/payments/{{payment_id}}/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
--data-raw '{
    "confirm": true,
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "4111111111111111",
            "card_exp_month": "01",
            "card_exp_year": "2035",
            "card_holder_name": "joseph Doe",
            "card_cvc": "100"
        }
    },
    "customer_id": "GC222",
    "setup_future_usage": "off_session",
    "payment_type": "setup_mandate",
    "customer_acceptance": {
        "acceptance_type": "online",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
        }
    },
    "browser_info": {
        "ip_address": "172.0.0.1"
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "9000000001",
            "country_code": "+91"
        }
    }
}'
```

3. Retrieve the `payment_method_id` that was created against the above payment by retrieving the payment. You will get the payment\_method\_id in the response

```bash
curl --location 'https://sandbox.hyperswitch.io/payments/<pass the payment_id>' \
--header 'Accept: application/json' \
--header 'api-key: <enter your Hyperswitch API key here>' \
```

4. Charge the customer later by passing the payment\_method\_id **(Called as 'MIT': Merchant initiated Transaction)**

Pass the above `payment_method_id` under the `recurring_details` object along with `off_session=true` in the payments request and confirm the payment. Make sure you are using the same `customer_id` and `profile_id` from the CIT.

```bash
curl --location 'http://sandbox.hyperswitch.io/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: use your Hyperswitch API key' \
--data-raw '{
    "amount": 1231,
    "currency": "USD",
    "confirm": true,
    "customer_id": "zero_auth_test_customer",
    "profile_id": <enter the relevant profile id>,
    "off_session": true,
    "recurring_details": {
        "type": "payment_method_id",
        "data": "pm_lmTnIO5EdCiiMgRPrV9x"
    }
}'
```


# Extended Authorization

Extend authorization hold periods beyond standard windows for flexible transaction capture

### **Overview**

Extended Authorization allows merchants to extend the authorization hold period beyond the standard window — giving more flexibility before a transaction is captured or settled.

This is particularly useful for industries where the final transaction amount or service completion time isn't known upfront — such as:

* Hospitality (room service or stay extensions)
* Car rentals (extra mileage, damages)
* Fuel & utilities (variable usage-based billing)

Example: A hotel may authorize a card for $500 during check-in but extend the authorization period if the guest extends their stay.

### How to Enable Extended Authorization

You can enable Extended Authorization at two levels — Profile Level or Per Payment Request.

#### 1. Profile-level configuration (via Dashboard)

To enable globally across all transactions:

1. Navigate to Developer → Payment Settings → Always Enable Extended Authorization
2. Toggle Enable/Disable as required

#### 2. Per-request configuration (via API)

To enable it for specific transactions, include the boolean field request\_extended\_authorization in your payment request.

This flag can be used in the following API calls:

* /payments/create with `confirm = false`
* /payments/update
* /payments/create call with `confirm = true`

> **⚠️ Note:**
>
> * The value of request\_extended\_authorization in the request will override the profile-level setting.
> * Extended Authorization is applicable only for manual capture payments (`capture_method = manual`)

### Example Request

```json
{
  "amount": 100,
  "currency": "USD",
  "confirm": true,
  "capture_method": "manual",
  "request_extended_authorization": true,
  "payment_method": "card",
  "payment_method_type": "credit",
  "payment_method_data": {
    "card": {
      "card_number": "4111111111111111",
      "card_exp_month": "03",
      "card_exp_year": "30",
      "card_cvc": "7373"
    }
  }
}
```

### Example Response

```json
{
  "payment_id": "pay_GPnTPs4e56yZ8FKAcj0K",
  "status": "requires_capture",
  "amount": 100,
  "amount_capturable": 100,
  "connector": "stripe",
  "enable_overcapture": true,
  "is_overcapture_enabled": true,
  "capture_method": "manual",
  "payment_method": "card",
  "payment_method_type": "debit",
  "network_transaction_id": "112181545921495",
  "created": "2025-09-24T11:29:55.629Z",
  "extended_authorization_last_applied_at": "2025-09-24T11:29:55.729Z",
  "extended_authorization_applied": true,
  "request_extended_authorization": true,
  "capture_by": "2025-09-24T11:44:55.629Z"
}
```

#### 3. Post-Authorization: Extended Authorization via API

Some connectors require extended authorization to be triggered manually. This API allows you to request an extended authorization when automatic handling is not supported.

Currently, manual extended authorization is supported for:

* Adyen
* PayPal

Calling this endpoint will initiate an extended authorization request. The actual behavior, including how much the capture or honor period is extended, depends on the specific connector and the issuing bank.

{% hint style="info" %}
Be aware: With some connectors like Adyen, a failed extended authorization attempt may also cause the initial authorization to fail.
{% endhint %}

> **⚠️ Note:**
>
> * To use this API, extended authorization must be enabled for the authorization you are attempting to extend.
> * Adyen handles extended authorization asynchronously. In such cases, you'll need to perform a psync to retrieve the updated response.

### Example Request

```
curl --location --request POST '{{basue_url}}/payments/{{payment_id}}/extend_authorization' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: ******************'
```

### Example Response

```json
{
  "payment_id": "pay_GPnTPs4e56yZ8FKAcj0K",
  "status": "requires_capture",
  "amount": 100,
  "amount_capturable": 100,
  "connector": "stripe",
  "enable_overcapture": true,
  "is_overcapture_enabled": true,
  "capture_method": "manual",
  "payment_method": "card",
  "payment_method_type": "debit",
  "network_transaction_id": "112181545921495",
  "created": "2025-09-24T11:29:55.629Z",
  "extended_authorization_last_applied_at": "2025-09-24T12:29:55.729Z",
  "extended_authorization_applied": true,
  "request_extended_authorization": true,
  "capture_by": "2025-09-24T11:44:55.629Z"
}
```

### Response Field Reference

| Field                                    | Description                                                                      |
| ---------------------------------------- | -------------------------------------------------------------------------------- |
| `request_extended_authorization`         | Indicates if extended authorization was requested for this payment               |
| `extended_authorization_applied`         | Shows whether extended authorization has been applied                            |
| `capture_by`                             | The deadline for capturing the payment (if available from the connector)         |
| `extended_authorization_last_applied_at` | The date when the connector last successfully applied an extended authorization. |

If the connector doesn't provide the capture deadline, the `capture_by` field will appear as null.

### Monitoring

After authorization, you can view the capture deadline under `capture_by` in the More Payment Details section of the dashboard. This helps you ensure capture occurs before the authorization hold expires. If `capture_by` is not available use the `extended_authorization_last_applied_at` parameter to compute the capture window.


# Vault-Then-Pay

Vault a payment method first, then use the token to execute payments via Server-to-Server API — giving you granular control over the payment lifecycle

{% hint style="info" %}
**Choose this path when** you want to use the SDK exclusively for vaulting/storing card details. The actual payment is then executed via S2S API calls from your backend using the resulting `payment_method_id` token.

If you want payment and vaulting to happen together in a single SDK flow, see [Pay-Then-Vault](/integration-guide/payment-suite/payments).
{% endhint %}

### The Two-Step Pattern

1. **Vault** — Capture card details using the [Vault SDK](https://docs.hyperswitch.io/integration-guide/workflows/vault/integration/sdk-integration) or the [Server-to-Server API](https://docs.hyperswitch.io/integration-guide/workflows/vault/integration/server-to-server-vault-tokenization). This generates a `payment_method_id`.
2. **Pay** — Pass the `payment_method_id` into the `/payments` API (or the Proxy endpoint) from your backend to execute the transaction.

### Payment Method Lifecycle

The `payment_method_id` is a unique, reusable token that maps a `customer_id` to a specific payment instrument (card, wallet, bank account). The same instrument from the same customer always resolves to the same ID.

| Customer ID | Payment Instrument        | Payment Method ID |
| ----------- | ------------------------- | ----------------- |
| 123         | Visa ending in 4242       | `PM1`             |
| 123         | Mastercard ending in 1111 | `PM2`             |
| 456         | Visa ending in 4242       | `PM3`             |
| 123         | PayPal (`user@email.com`) | `PM4`             |

### Integration Options in This Section

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Token Led Payment</strong></td><td>Execute a payment using a <code>payment_method_id</code> via S2S API</td><td><a href="/pages/ecneth5mwKKB9scVONye">/pages/ecneth5mwKKB9scVONye</a></td></tr><tr><td><strong>Proxy Payment</strong></td><td>Send PSP payment requests through the Vault Proxy — raw card data never leaves the Vault</td><td><a href="/pages/TMSjT7A6dQjxfw2VxDJI">/pages/TMSjT7A6dQjxfw2VxDJI</a></td></tr><tr><td><strong>Payment Methods Management</strong></td><td>Embed the Vault SDK widget to let customers view, add and delete saved cards</td><td><a href="/pages/yyUy7tIb5oaFrDk2XycP">/pages/yyUy7tIb5oaFrDk2XycP</a></td></tr></tbody></table>

### Vault Integration Reference

For the full SDK and API setup guides used in this flow, see:

* [Vault SDK Integration](https://docs.hyperswitch.io/integration-guide/workflows/vault/integration/sdk-integration) — React and Vanilla JS step-by-step
* [Server-to-Server Vault Tokenization](https://docs.hyperswitch.io/integration-guide/workflows/vault/integration/server-to-server-vault-tokenization) — direct API tokenization for PCI-certified backends
* Vault Configuration — API key generation and dashboard setup


# Token Led Payment

Process payments using Payment Method SDK with guest checkout, customer checkout, and repeat purchase flows via S2S APIs

The Payment Method SDK and `/payment-methods` API work in tandem with the `/payments` API to achieve any business objective as listed below.

### Guest Checkout Flow (S2S)

1. Collect card details and tokenise with HS [Create PM API](https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--create-v1) to get a [PM ID](https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--create-v1#response-id) (payment\_method\_id)
2. Use the PM ID to authorize the [payment request](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#body-payment-token-one-of-0) during order confirmation
3. For extended sessions, where token expires before order completion, create a new PM ID with the same card details using the Create PM API

{% hint style="info" %}
Note - The PM ID in case of guest checkout is volatile in nature and has a default expiry of 1-hour which can be extended by Merchant at a session level.

For guest checkout flow the PM ID is NOT unique to Customer + Payment method combination.
{% endhint %}

### Customer Checkout Flow - First Time Payment (S2S)

1. Create a customer with HS using the [Create Customer API](https://api-reference.hyperswitch.io/v2/customers/customers--create-v1)
2. Use the customer\_id to tokenize the collected card details using Create PM API
3. Use the PM ID to authorize the [payment request](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#body-payment-token-one-of-0) during order confirmation
4. For extended sessions, where token expires before order completion update the PM with CVV using the [Update PM API](https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--update-v1) and use this PM ID to complete the payment

{% hint style="info" %}
Note - The CVV storage is volatile in nature and can be stored for 1-hour by default which can be extended by Merchant at a session level.

For logged-in user checkout flow the PM ID is unique to Customer + Payment method combination.
{% endhint %}

### Customer Checkout Flow - Repeat Purchase (S2S)

1. Fetch the stored cards for the customer using [List Saved PMs API](https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--list-customer-saved-payment-methods-v1) which returns the masked card details with corresponding PM ID
2. Update the PM ID of the user selected card along with CVV value collected from the user using the [Update PM API](https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--update-v1)
3. Use the PM ID to authorize the [payment request](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#body-payment-token-one-of-0) during order confirmation
4. For extended sessions, where token expires before order completion update the PM again with the collected CVV and use this PM ID to complete the payment

### Payment Method SDK Checkout - Guest, New Customer and Repeat Customer Flows

1. Create a PM session using the [Session Create API](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--create-v1) to get a [sdk authorization](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--create-v1#response-sdk-authorization-one-of-0)
2. For guest user, pass "storage\_type" as "volatile" and skip sending the Customer ID
3. Initialize and mount the [Vault SDK](https://docs.hyperswitch.io/integration-guide/payment-experience/vault-then-pay) using the `sdkAuthorization`
4. The SDK now takes care of the following flows based on user action:
5. Post which the SDK submits the card details via the [PM Confirm API](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--confirm-a-payment-method-session-v1) and returns back a [PM Token](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--confirm-a-payment-method-session-v1#response-id) (short-lived) in the response
6. Pass the PM Token to the Merchant Server. You may either use it directly for payment or exchange it for a PM ID using [PM token exchange API](https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--payment-method-token-to-payment-method-id-v1)
7. Use either the **PM Token (short-lived)** or **PM ID (long-lived)** to authorize [payment request](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#body-payment-token-one-of-0)

{% hint style="info" %}
Note - The HS SDK returns a short-lived PM Token. This can be used directly for immediate payments or exchanged via S2S to obtain a reusable PM ID for future transactions.
{% endhint %}

### HS SDK Checkout for Repeat Customer - No CVV Flow

1. Create a PM session using the [Session Create API](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--create-v1) to get a [sdk authorization](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--create-v1#response-sdk-authorization-one-of-0)
2. Initialize and mount the [Vault SDK](https://docs.hyperswitch.io/integration-guide/payment-experience/vault-then-pay) using the sdk authorization
3. The SDK lists the previously saved cards for customers to select
4. If the card has been vaulted previously with an MIT setup for it, CVV is not collected for it and the SDK returns back a [PM Token](https://api-reference.hyperswitch.io/v1/payments/payments--confirm#response-payment-token-one-of-0) (short-lived) in the response. Note - The PM ID in case of guest checkout is volatile in nature and has a default expiry of 1-hour which can be extended by Merchant at a session level.

{% hint style="info" %}
When using the HS SDK, the response always contains a temp token and you'll need to exchange it to get the PM ID via a S2S call. Highlighted in detail in (4.)
{% endhint %}


# Proxy Payment

Vault your card and use proxy endpoint for payment processing

The Proxy Payments Service allows merchants to tokenize cards via Juspay Hyperswitch Vault and make API calls to PSPs using those tokens. The Vault intercepts these requests, replaces tokens with raw card data (de-tokenization), and forwards them securely to the PSP.

Key Highlights:

* No PSP re-integration needed – Keep your existing PSP connections.
* PCI DSS scope reduction – Raw card data stays within Vault.
* Data security – Detokenization happens only during the request lifecycle.
* Centralized token management – One vault, many PSPs.

### Vault and Proxy - Vaulting and Payments Flow

```mermaid
%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#ffffff",
    "primaryBorderColor": "#2563EB",
    "lineColor": "#2563EB",
    "secondaryColor": "#EFF6FF",
    "tertiaryColor": "#DBEAFE",
    "fontFamily": "Inter, system-ui, sans-serif",
    "fontSize": "14px",
    "textColor": "#000000",

    "actorBkg": "#346DDB",
    "actorBorder": "#999999",
    "actorTextColor": "#ffffff",

    "signalColor": "#000000",
    "signalTextColor": "#696969",

    "labelBoxBkgColor": "#346DDB",
    "labelBoxBorderColor": "#2563EB"
  }
}}%%
sequenceDiagram
  participant C as Consumer
  participant MFE as Merchant FE
  participant PSDK as Hyperswitch PM SDK
  participant MBE as Merchant BE
  participant HBE as Hyperswitch BE
  participant V as Vault
  participant PSP as PSP

  MFE ->> MBE: Create-payment-method-session with customer_id
  MBE ->> HBE: "Create-payment-method-session" API using Merchant HS API Key & Profile ID
  HBE -->> MBE: sdk_authorization
  MBE -->> MFE: sdk_authorization

  Note over MFE: Create a script tag to load HyperLoader.js
  Note over MFE: Initialize window.Hyper using the Publishable Key
  Note over MFE: Create PMM elements group using sdkAuthorization
  Note over MFE: Create specific widget instance & mount SDK

  C ->> PSDK: Add Payment method
  PSDK ->> HBE: "Payment Method Session - Confirm a payment method session" API with card details
  HBE ->> V: Store card details
  Note over MBE: CVV is stored temporarily for a specific TTL or until first txn
  V -->> HBE: Response
  HBE -->> PSDK: Response (Session id & associated_token_id)

  MBE ->> HBE: "Payment Method Session - List Payment Methods" API with Session id
  HBE -->> MBE: Response (PM_ID)
  Note over MBE: Response contains all payment methods associated with customer
  Note over MBE: Choose the PM_ID for the Session id of the session

  Note over MBE: Making a proxy payment
  MBE ->> HBE: Send PSP payment request to Vault proxy endpoint with PM_ID
  HBE ->> PSP: Send PSP payment request<br>to PSP (PM_ID replaced with actual card data)
  PSP -->> HBE: Payment response
  HBE -->> MBE: Payment response
```

#### 1. Create Payment Method Session (Server-Side)

The merchant server initiates the flow by calling the Hyperswitch [`Create-payment-method-session`](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--create-v1) API with the `customer_id`. Hyperswitch responds with a `sdk_authorization`, which are required to authenticate the client-side session.

```bash
curl --request POST \
  --url https://sandbox.hyperswitch.io/v1/payment-method-sessions \
  --header 'Authorization: <api-key>' \
  --header 'Content-Type: application/json' \
  --header 'X-Profile-Id: <x-profile-id>' \
  --data '
{
  "customer_id": "12345_cus_abcdefghijklmnopqrstuvwxyz"
}
'
```

#### 2. Initialize SDK (Client-Side)

The merchant client loads the `HyperLoader.js` script and initializes `window.Hyper` using the Publishable Key. Using the `sdk_authorization`, the SDK creates a Payment Method Management (PMM) group and mounts the specific widget instance to the UI.

```js
// Fetches a payment method session and mounts the payment methods management element
async function initialize() {
  // Step 1: Create payment method session
  const response = await fetch("/create-payment-method-session", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      customer_id: "CUSTOMER_ID",
    }),
  });
  const { sdkAuthorization } = await response.json();

  // Step 2: Initialize HyperLoader.js
  var script = document.createElement("script");
  script.type = "text/javascript";
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";

  let hyper;
  script.onload = () => {
    // Step 3: Initialize Hyper with your publishable key and profile ID
    hyper = window.Hyper({
      publishableKey: "YOUR_PUBLISHABLE_KEY",
      profileId: "YOUR_PROFILE_ID",
    });

    // Step 4: Configure appearance
    const appearance = {
      theme: "default",
    };

    // Step 5: Create payment methods management elements
    const paymentMethodsManagementElements =
      hyper.paymentMethodsManagementElements({
        appearance,
        sdkAuthorization: sdkAuthorization,
      });

    // Step 6: Create and mount the paymentMethodsManagement element
    const paymentMethodsManagement = paymentMethodsManagementElements.create(
      "paymentMethodsManagement"
    );
    paymentMethodsManagement.mount("#payment-methods-management-elements");
  };
  document.body.appendChild(script);
}

// Call initialize when page loads or when user clicks a button
initialize();
```

#### 3. Collect and Vault Card (Client-Side)

The customer enters their card details directly into the SDK-managed widget. Upon confirmation, the SDK calls the `/Confirm a payment method session` API. Hyperswitch securely receives the data, stores it in the Vault (retaining the CVV temporarily for the transaction TTL), and returns a success response with the `session_id` to the client.

#### 4. Retrieve Payment Method ID (Server-Side)

The merchant server calls the "List Payment Methods" API using the `session_id`. Hyperswitch returns a list of payment methods associated with the customer, from which the merchant server selects the appropriate `PM_ID` (Payment Method ID) to use for the transaction.

#### Execute Proxy Payment (Server-Side)

The merchant server initiates the payment by sending a request to the [Hyperswitch vault proxy](https://docs.hyperswitch.io/~/revisions/01bZ2maqjwpnmrttix7i/explore-hyperswitch/payments-modules/vault/hyperswitch-vault-pass-through-proxy-payments) endpoint using the `payment_method_id`. The proxy securely replaces the token with the actual card data from the Vault and forwards the request to the Payment Service Provider (PSP), returning the final payment response to the merchant.

#### New User Payments Flow

1. Create Payment Method Session (Server-Side) The merchant server initiates the flow by calling the Hyperswitch
2. [Initialize SDK (Client-Side)](/integration-guide/payment-suite/payment-method) The merchant client loads the `HyperLoader.js` script and initializes `window.Hyper` using the Publishable Key. Using the `sdk_authorization`, the SDK creates a Payment Method Management (PMM) group and mounts the specific widget instance to the UI.
3. Collect and Vault Card (Client-Side) The customer enters their card details directly into the SDK-managed widget. Upon confirmation, the SDK calls the `/Confirm a payment method session` API. Hyperswitch securely receives the data, stores it in the Vault (retaining the CVV temporarily for the transaction TTL), and returns a success response with the `session_id` to the client.
4. Retrieve Payment Method ID (Server-Side) The merchant server calls the "List Payment Methods" API using the `session_id`. Hyperswitch returns a list of payment methods associated with the customer, from which the merchant server selects the appropriate `PM_ID` (Payment Method ID) to use for the transaction.
5. Execute Proxy Payment (Server-Side) The merchant server initiates the payment by sending a request to the

#### Proxy Payment Request

Include the following details:

1. Include the Hyperswitch Proxy payments related fields in the headers:
   1. URL: Proxy endpoint (<https://sandbox.hyperswitch.io/proxy>)
   2. API Key: Your API key for the merchant\_id under which the vault service was created on Hyperswitch dashboard
   3. Profile\_id: Your profile\_id for the merchant\_id under which the vault service was created on Hyperswitch dashboard
2. Include the following details in the body:
   1. `request_body`: Include the request body of the PSP payment request
   2. `destination_url`, `method`, `headers`: Pass your PSP url as destination url, PSP endpoint method and headers under the respective fields
   3. Vault tokens:
      1. `token_type`: Choose payment\_method\_id or tokenization\_id
      2. `token`: Plug the payment\_method\_id or tokenization\_id that you would have received when tokenizing card data or PII data at Hyperswitch vault
   4. Placeholders for token data: In the `request_body`, Plug in the dynamic placeholders `{{$card_number}}`, `{{$card_exp_month}}`, `{{$card_exp_year}}` against the PSP request fields where you want the actual values of the tokens from the Vault to be substituted

#### Sample Proxy Payment Request (Checkout.com)

<pre class="language-bash"><code class="lang-bash">curl --location 'https://sandbox.hyperswitch.io/proxy' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Profile-Id: pro_p3ifmp0HzuC0Bp1KhMnK' \
--header 'Authorization: api-key=dev_bBPAkg0KX9Wn4Zewavrd0W76LsgDpGSey8iMARauXDWqzX4zwk4D03d0851Tx0EV' \
--header 'api-key: dev_30hnPzj6Kk6UAETk9hjWdaIxdVVuTk3mjmz2kxh6CIhq1K1DJ4nTZdpGt986L53G' \
--data '{
    "request_body": {
        "source": {
            "type": "card",
            "number": "{{$card_number}}",
            "expiry_month": "{{$card_exp_month}}",
            "expiry_year": "{{$card_exp_year}}",
            "billing_address": {
                "address_line1": "123 High St.",
                "address_line2": "Flat 456",
                "city": "London",
                "state": "GB",
                "zip": "SW1A 1AA",
                "country": "GB"
            }
        },
        "processing_channel_id": "pc_jx5lvimg..",
        "amount": 6540,
        "currency": "USD",
        "payment_type": "Regular",
        "reference": "ORD-5023-4E89",
        "description": "Set of 3 masks",
        "capture": true,
        "capture_on": "2019-09-10T10:11:12Z",
    },
    "destination_url": "https://api.sandbox.checkout.com/payments",
    "headers": {
        "Content-Type": "application/json",
        "Authorization": "Bearer sk_sbox_3uu..."
    },
<strong>    "token": "12345_pm_0196f252baa1736190bf0fc81b9651ea",
</strong>    "token_type": "payment_method_id",
    "method": "POST"

}'
</code></pre>

#### Sample Response

```bash
{
    "response": {
        "id": "pay_7f6x6vki25futmy54uot5c3ama",
        "action_id": "act_egzzg6mojknungbe3367fvsiaq",
        "amount": 6540,
        "currency": "USD",
        "approved": true,
        "status": "Authorized",
        "auth_code": "690380",
        "response_code": "10000",
        "response_summary": "Approved",
        "risk": {
            "flagged": false,
            "score": 0.0
        },
        "source": {
            "id": "src_jliqxofnudseteb5dl4hl7frh4",
            "type": "card",
            "expiry_month": 12,
            "expiry_year": 2026,
            "scheme": "Visa",
            "last4": "0093",
            "fingerprint": "EEF6D525CC7C861D6AB1CEB56F9285839AE850E79BA43D7D8C06790B7A0ABD7C",
            "bin": "476136",
            "card_type": "CREDIT",
            "card_category": "CONSUMER",
            "issuer": "YES BANK, LTD.",
            "issuer_country": "IN",
            "product_id": "F",
            "product_type": "Visa Classic",
            "avs_check": "G",
            "payment_account_reference": "V001711066651680047",
            "regulated_indicator": false
        },
        "processed_on": "2025-05-21T10:10:42.7625936Z",
        "reference": "ORD-5023-4E89",
        "scheme_id": "509352732623965",
        "processing": {
            "acquirer_transaction_id": "096359746174895421192",
            "retrieval_reference_number": "404030119279",
            "merchant_category_code": "5815",
            "scheme_merchant_id": "75155",
            "scheme": "VISA",
            "aft": false,
            "pan_type_processed": "fpan",
            "cko_network_token_available": false,
            "provision_network_token": false
        },
        "expires_on": "2025-06-20T10:10:42.7625936Z",
        "_links": {
            "self": {
                "href": "https://api.sandbox.checkout.com/payments/pay_7f6x6vki25futmy54uot5c3ama"
            },
            "actions": {
                "href": "https://api.sandbox.checkout.com/payments/pay_7f6x6vki25futmy54uot5c3ama/actions"
            },
            "capture": {
                "href": "https://api.sandbox.checkout.com/payments/pay_7f6x6vki25futmy54uot5c3ama/captures"
            },
            "void": {
                "href": "https://api.sandbox.checkout.com/payments/pay_7f6x6vki25futmy54uot5c3ama/voids"
            }
        }
    },
    "status_code": 201,
    "response_headers": {
        "date": "Wed, 21 May 2025 10:10:42 GMT",
        "cko-version": "1.1049.0+54597dfad",
        "strict-transport-security": "max-age=16000000; includeSubDomains; preload;",
        "location": "https://api.sandbox.checkout.com/payments/pay_7f6x6vki25futmy54uot5c3ama",
        "content-length": "1883",
        "content-type": "application/json; charset=utf-8",
        "connection": "keep-alive",
        "cko-request-id": "61354917-3541-44fc-8ec7-98dd385aa0b4"
    }
}
```


# Payment Methods Management

Integrate Hyperswitch's Vault service to store customer payment methods securely and eliminate PCI DSS compliance burden

The Juspay Hyperswitch Payment Methods Management SDK provides a secure solution for merchants to handle and store payment information without the burden of PCI DSS compliance requirements. By leveraging Hyperswitch's Vault service, merchants can securely store customer payment methods (credit cards, digital wallets, etc.) while minimizing their exposure to sensitive payment data.

{% hint style="info" %}
**Full SDK reference:** This page provides a quick-start guide. For the complete React + JS integration walkthrough (including `confirmTokenization`, error handling, and appearance customization), see [Vault SDK Integration](https://github.com/juspay/hyperswitch-docs/tree/main/workflows/vault/sdk-integration.md).
{% endhint %}

### Key Features

| Feature                        | Description                                                        |
| ------------------------------ | ------------------------------------------------------------------ |
| **Payment Method Creation**    | Allow customers to save new payment methods during checkout        |
| **Storing Payment Methods**    | Securely store card details — customers never re-enter information |
| **Retrieving Payment Methods** | Load a customer's saved methods by `customer_id`                   |
| **Deleting / Deactivating**    | Let customers remove outdated payment methods                      |

### Prerequisites

Before integrating, generate your **Vault API Key** and note your **Profile ID**. See [Vault Configuration](https://github.com/juspay/hyperswitch-docs/tree/main/workflows/vault/configuration.md).

### Integration Guide

#### 1. Server-Side Setup

First, you'll need to set up your server to create payment method sessions, which establish secure connections between your frontend and the Hyperswitch Vault.

**Obtaining Your API Keys**

* Get your API key from the [Hyperswitch dashboard](https://app.hyperswitch.io/developers?tabIndex=1) under Developers -> API Keys section. You'll need both your API key and profile ID for server and client integration.

**Creating a Payment Methods Session Endpoint**

Add an endpoint on your server that creates [payment methods sessions](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--create-v1). This endpoint will return the necessary session information to your client application.

```javascript
// Create-Payment-Methods-Session
const app = express()

app.post("/create-payment-method-session", async (req, res) => {
  try {
    // Create payment method session on Hyperswitch
    const response = await fetch(
      `${HYPERSWITCH_SERVER_URL}/v1/payment-method-sessions`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-profile-id": YOUR_PROFILE_ID,
          Authorization: `api-key=${YOUR_API_KEY}`,
        },
        body: JSON.stringify(req.body),
      }
    );
    const data = await response.json();

    if (!response.ok) {
      console.error("Hyperswitch API Error:", data);
      return res.status(response.status).json({
        error: data.error || "Failed to create payment method session",
      });
    }
    // Return sdk authorization to the frontend
    res.json({
      sdkAuthorization: data.sdk_authorization,
    });
  } catch (error) {
    console.error("Server Error:", error);
    res.status(500).json({
      error: "Internal server error",
      message: error.message,
    });
  }
});
```

> **Note**: Replace `YOUR_PROFILE_ID` and `YOUR_API_KEY` with your actual credentials. See [Vault Configuration](https://github.com/juspay/hyperswitch-docs/tree/main/workflows/vault/configuration.md).

API reference: [Payment Method Session — Create](https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--create-v1)

#### 2. Client-Side Integration

Once your server endpoint is set up, you'll need to integrate the Vault/Payment Methods Management SDK into your client application.

**2.1 Define the Payment Methods Management Form**

Add one empty placeholder `div` to your page for the Payment Methods Management widget that you'll mount.

```html
<form id="payment-methods-management-form">
  <div id="payment-methods-management-elements">
    <!--HyperLoader injects the Payment Methods Management SDK-->
  </div>
</form>
```

**2.2 Fetch the Payment Method Session and Mount the Payment Methods Management Element**

Make a request to the endpoint on your server to create a new payment method session. The `sdk_authorization` returned by your endpoint are used to initialize and display the customer's saved payment methods. Following this, create a `paymentMethodsManagementElements` element and mount it to the placeholder `div` in your form. This embeds an iframe with a dynamic interface that displays saved payment methods, allowing your customer to view, manage, and delete their payment methods.

> Note: Make sure to never share your API key with your client application as this could potentially compromise your payment flow.

```js
// Fetches a payment method session and mounts the payment methods management element
async function initialize() {
  // Step 1: Create payment method session
  const response = await fetch("/create-payment-method-session", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      customer_id: "CUSTOMER_ID",
    }),
  });
  const { sdkAuthorization } = await response.json();

  // Step 2: Initialize HyperLoader.js
  var script = document.createElement("script");
  script.type = "text/javascript";
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";

  let hyper;
  script.onload = () => {
    // Step 3: Initialize Hyper with your publishable key and profile ID
    hyper = window.Hyper({
      publishableKey: "YOUR_PUBLISHABLE_KEY",
      profileId: "YOUR_PROFILE_ID",
    });

    // Step 4: Configure appearance
    const appearance = {
      theme: "default",
    };

    // Step 5: Create payment methods management elements
    const paymentMethodsManagementElements =
      hyper.paymentMethodsManagementElements({
        appearance,
        sdkAuthorization: sdkAuthorization,
      });

    // Step 6: Create and mount the paymentMethodsManagement element
    const paymentMethodsManagement = paymentMethodsManagementElements.create(
      "paymentMethodsManagement"
    );
    paymentMethodsManagement.mount("#payment-methods-management-elements");
  };
  document.body.appendChild(script);
}

// Call initialize when page loads or when user clicks a button
initialize();
```

**2.3 Complete tokenization and handle errors**

Call `confirmTokenization()`, passing the mounted Payment Methods Management widgets and a `return_url` to indicate where Hyper should redirect the user after any required authentication. Depending on the payment method, Hyper may redirect the customer to an authentication page. After authentication is completed, the customer is redirected back to the `return_url`.

If there are any immediate errors (for example, invalid request parameters), Hyper returns an error object. Show this error message to your customer so they can try again.

```js
async function handleSubmit(e) {
  setMessage("");
  e.preventDefault();

  // Ensure Hyper is initialized
  if (!hyper || !paymentMethodsManagementElements) {
    return;
  }

  setIsLoading(true);

  try {
    const response = await hyper.confirmTokenization({
      paymentMethodsManagementElements,
      confirmParams: {
        // URL to redirect the user after authentication (if required)
        return_url: "https://example.com/complete",
      },
      redirect: "always", // if you wish to redirect always, otherwise it is defaulted to "if_required"
    });

    // Tokenization succeeded
    if (response?.id) {
      // You can use the returned payment method/session token here
      handleTokenRetrieval(response);
    } else {
      // Handle immediate errors returned by Hyper
      const error = response?.error;

      if (error) {
        if (error.type === "card_error" || error.type === "validation_error") {
          setMessage(error.message);
        } else {
          if (error.message) {
            setMessage(error.message);
          } else {
            setMessage("An unexpected error occurred.");
          }
        }
      } else {
        setMessage("An unexpected error occurred.");
      }
    }
  } catch (err) {
    setMessage(err.message || "An unexpected error occurred.");
  } finally {
    setIsLoading(false);
  }
}
```

Now that you have integrated the Hyperswitch Payment Methods Management on your app, you can customize it to blend with the rest of your website.


# Web

Integrate Juspay Hyperswitch unified checkout with your web app for a seamless payment experience

### Global Checkout Experience

Juspay Hyperswitch Unified Checkout is an inclusive, consistent and blended payment experience optimized for the best conversion rates.

| <img src="/files/tyNieL72lTbK7pq3GeMp" alt="" data-size="original"> | <p><strong>Inclusive</strong><br>A variety of global payment methods including cards, buy now pay later and digital wallets are supported by the Unified Checkout, with adaptation to local preferences and ability to local language customization.</p>                            |
| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <img src="/files/tyNieL72lTbK7pq3GeMp" alt="" data-size="original"> | <p><strong>Consistent</strong><br>With a diverse set of payment methods supported, the Unified Checkout provides a singular consistent payment experience across platforms (web, android and ios) powered by smart payment forms, minimal redirections and intelligent retries.</p> |
| <img src="/files/FHjGGWboL3hjbQ6FgBPM" alt="" data-size="original"> | <p><strong>Blended</strong><br>The Unified Checkout includes 40+ styling APIs, which could be tweaked to make the payment experience blend with your product. Your users will get a fully native and embedded payment experience within your app or website</p>                     |

### Modify and Experiment

<figure><img src="/files/vOD2ejKAAQCHlw4nq0kb" alt="" width="563"><figcaption></figcaption></figure>

While the Unified Checkout is pre-optimized for maximum conversions, Hyperswitch does not restrict you to stick to a one-size-fits-all approach. Using Hyperswitch SDK APIs, you get complete control over modifying the payment experience by,

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Prioritizing payment methods</strong><br>You can make an impact on the payment mix or conversion rates by prioritizing/ promoting specific payment methods for your customers.</td><td></td><td></td><td><a href="/pages/zMfShvn3zjsGJugBGUST">/pages/zMfShvn3zjsGJugBGUST</a></td><td><a href="/files/nYF8awSzYOaV8W2pSN4H">/files/nYF8awSzYOaV8W2pSN4H</a></td></tr><tr><td><p><strong>Switching themes and layouts of checkout page</strong></p><p>The Unified Checkout comes with a wide range of pre-designed themes and layouts which you can choose from.</p></td><td></td><td></td><td><a href="/pages/zMfShvn3zjsGJugBGUST">/pages/zMfShvn3zjsGJugBGUST</a></td><td><a href="/files/eR1MrGtAScFTn1M8K6uD">/files/eR1MrGtAScFTn1M8K6uD</a></td></tr></tbody></table>

### Optimize

You can further optimize Unified Checkout web SDK by preloading all the resources that are needed by the iframe. By the time iframe is to be mounted (checkout button), everything that is required can be fetched from their server and stored in the disk cache.

* `<Elements/>` wrapper has to be used in the top-level of the merchants app, say web app has two pages eg: homepage and checkout page, the wrapper must be added in the homepage itself.
* `<Elements/>` has the required props to load our Hyperloader (script) which will
  1. Preload all the resources that are required by the SDK ie. files, svgs, icons, css, fonts etc.
  2. Prefetch the two main API calls and is ready with response

{% hint style="success" %}
**This will significantly decrease the SDK load time from \~10-15s (in slow 3G network) to just \~1-5ms.**
{% endhint %}


# React with REST API Integration

Integrate Hyperswitch SDK with React and REST API for web checkout

**Before following these steps, please configure your payment methods** [here](https://app.hyperswitch.io/dashboard/connectors). Use this guide to integrate `hyperswitch` SDK to your React app. You can also use this demo app as a reference with your Juspay Hyperswitch credentials to test the setup.

<details>

<summary><a href="https://github.com/PritishBudhiraja/hyperswitch-react-demo-app/archive/refs/heads/main.zip"><strong>Demo App</strong></a></summary>

You can use this demo app as a reference with your Hyperswitch credentials to test the setup.

</details>

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on the client

#### 2.1 Install the [`hyper-js`](https://www.npmjs.com/package/@juspay-tech/hyper-js) and [`react-hyper-js`](https://www.npmjs.com/package/@juspay-tech/react-hyper-js) libraries

Install the packages and import it into your code

```bash
npm install @juspay-tech/hyper-js
npm install @juspay-tech/react-hyper-js
```

#### 2.2 Add `hyper` to your React app

Use `hyper-js` to ensure that you stay PCI compliant by sending payment details directly to Hyperswitch server.

```js
import React, { useState, useEffect } from "react";
import { loadHyper } from "@juspay-tech/hyper-js";
import { hyperElements } from "@juspay-tech/react-hyper-js";
```

#### 2.3 Load `hyper-js`

Call `loadHyper` with your publishable API keys to configure the library. To get a publishable Key please find it [here](https://app.hyperswitch.io/developers).

**Basic Configuration**

```js
const hyperPromise = loadHyper("YOUR_PUBLISHABLE_KEY",{
    customBackendUrl: "YOUR_BACKEND_URL",
    //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
});
```

**Advanced & Custom Configuration&#x20;*****(Beta / Upcoming)***

`loadHyper` also supports an extended configuration object for multi-tenant platform setups or custom endpoint overrides (e.g., dedicated backend, custom logging, or asset endpoints):

```js
const hyperPromise = loadHyper({
  publishableKey: "YOUR_PUBLISHABLE_KEY",
  profileId: "YOUR_PROFILE_ID",
  platformPublishableKey: "pk_platform_xxxx", // Required for platform/connected account setups
  customConfig: {
    customEndpoint: "https://dev.hyperswitch.io/api",                      // Primary Hyperswitch API base URL
    overrideCustomBackendEndpoint: "https://sandbox.hyperswitch.io",       // Custom backend API endpoint
    overrideCustomConfirmEndpoint: "https://sandbox.hyperswitch.io",       // Custom payment confirm calls endpoint
    overrideCustomSDKConfigEndpoint: "https://config.example.com/api",     // Custom SDK config fetch endpoint
    overrideCustomLoggingEndpoint:   "https://logs.example.com/logs",      // Custom beacon logging endpoint
    overrideCustomAssetsEndpoint:    "https://assets.example.com",         // Custom static assets endpoint
  },
});
```

#### 2.4 Fetch the Payment and Initialise `hyperElements`

Immediately make a request to the endpoint on your server to create a new Payment as soon as your checkout page loads. The clientSecret returned by your endpoint is used to complete the payment.

```js
useEffect(() => {
  // Create PaymentIntent as soon as the page loads
  fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ items: [{ id: "xl-tshirt" }], country: "US" }),
  })
    .then((res) => res.json())
    .then((data) => setClientSecret(data.clientSecret));
}, []);
```

#### 2.5 Initialise `HyperElements`

Pass the promise from `loadHyper` to the `HyperElements` component. This allows the child components to access the Hyper service via the `HyperElements` parent component. Additionally, pass the client secret as an [options](https://hyperswitch.io/docs/sdkIntegrations/unifiedCheckoutWeb/customization) to the `HyperElements` component.

```js
<div className="App">
  {clientSecret && (
    <HyperElements options={options} hyper={hyperPromise}>
      <CheckoutForm />
    </HyperElements>
  )}
</div>
```

#### 2.6 Setup the state (optional)

Initialize a state to keep track of payment, display errors and control the user interface.

```js
const [message, setMessage] = useState(null);
const [isLoading, setIsLoading] = useState(false);
```

#### 2.7 Store a reference to `Hyper`

Access the `hyper-js` library in your CheckoutForm component by using the `useHyper()` and `useWidgets()` hooks. If you need to access Widgets via a class component, use the `WidgetsConsumer` instead. You can find the API for these methods here.

```js
const hyper = useHyper();
const widgets = useWidgets();
```

### 3. Complete the checkout on the client

{% tabs %}
{% tab title="ExpressCheckout" %}
**Key Features of Hyperswitch's Express Checkout**

* Fast Performance: One-click payment at checkout enables a smooth and frictionless payment experience to customers.
* Multiple Payment Options: Supports ApplePay, PayPal, Klarna, and GooglePay, giving customers a variety of payment choices on top of the speed in checkout.
* Easy Integration: Our SDK can be easily integrated with web applications.

**Benefits of Hyperswitch's Express Checkout Feature**

* Better User Experience: One-click payment makes shopping easier, leading to more sales and fewer abandoned carts.
* Time Savings: Speeds up the checkout process, saving time for both customers and merchants.
* Great for Mobile: Optimized for mobile shopping with ApplePay, PayPal and GooglePay integration for quick purchases on smartphones.
* Collect billing and shipping details directly from ApplePay, Klarna, GooglePay, PayPal

**3.1 Add the ExpressCheckout**

<figure><img src="/files/IeqQ5DTtab94K5xekcPW" alt=""><figcaption></figcaption></figure>

> The Express Checkout Element gives you a single integration for accepting payments through one-click payment buttons. Supported payment methods include ApplePay, GooglePay and PayPal.

Add the `ExpressCheckout` to your Checkout. This embeds an iframe that displays configured payment method types supported by the browser available for the Payment, allowing your customer to select a payment method. The payment methods automatically collects the associated payment details for the selected payment method type.

Define paymentElementOptions:

```js
var expressCheckoutOptions = {
  wallets: {
    walletReturnUrl: "https://example.com/complete",
    //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
  },
};
```

```js
<ExpressCheckoutElement id="express-checkout" options={expressCheckoutOptions} />
```

{% endtab %}

{% tab title="UnifiedCheckout" %}
**3.1.A Add the UnifiedCheckout**

<figure><img src="/files/N5y0vbdmkMAv3nTD0ZT1" alt=""><figcaption></figcaption></figure>

Add the `UnifiedCheckout` to your Checkout. This embeds an iframe with a dynamic form that displays configured payment method types available for the Payment, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.

(Optional) Define paymentElementOptions:

```js
var unifiedCheckoutOptions = {
  wallets: {
    walletReturnUrl: "https://example.com/complete",
    //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
  },
};
```

```js
<UnifiedCheckout id="unified-checkout" options={unifiedCheckoutOptions} />
```

**3.1.B Complete the payment and handle errors**

Call `confirmPayment()`, passing along the `UnifiedCheckout` and a return\_url to indicate where `hyper` should redirect the user after they complete the payment. For payments that require additional authentication, `hyper` redirects the customer to an authentication page depending on the payment method. After the customer completes the authentication process, they're redirected to the return\_url.

If there are any immediate errors (for example, your customer's card is declined), `hyper-js` returns an error. Show that error message to your customer so they can try again.\
\
**Standard Implementation**

Use `hyper.confirmPayment()` by retrieving instances from the `useHyper()` and `useWidgets()` hooks:

```js
const handleSubmit = async (e) => {
  setMessage("");
  //e.preventDefault();

  if (!hyper || !widgets) {
    return;
  }
  setIsLoading(true);

  const { error, status } = await hyper.confirmPayment({
    elements,
    confirmParams: {
      // Make sure to change this to your payment completion page
      return_url: "https://example.com/complete",
    },
    redirect: "always", // if you wish to redirect always, otherwise it is defaulted to "if_required"
  });

  if (error) {
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message);
    } else {
      if (error.message) {
        setMessage(error.message);
      } else {
        setMessage("An unexpected error occurred.");
      }
    }
  }
  if (status) {
    handlePaymentStatus(status); //handle payment status
  }
  setIsLoading(false);
};
```

\
**Direct Ref Trigger&#x20;*****(Beta / Upcoming)***

Alternatively, you can trigger confirmation directly via a React `ref` attached to the `<PaymentElement/>` component, eliminating the need to pass `elements` manually into `confirmPayment()`:

```js
import React, { useRef, useState } from "react";
import { PaymentElement } from "@juspay-tech/react-hyper-js";

function CheckoutForm() {
  const paymentElementRef = useRef(null);
  const [isProcessing, setIsProcessing] = useState(false);
  const [message, setMessage] = useState(null);

  const handleSubmit = async (e) => {
    e.preventDefault();

    if (!paymentElementRef.current || isProcessing) return;

    setIsProcessing(true);
    setMessage(null);

    try {
      // Trigger payment confirmation directly using the PaymentElement ref
      const { error, status } = await paymentElementRef.current.confirmPayment({
        confirmParams: {
          return_url: window.location.origin,
        },
      });

      if (error) {
        setMessage(error.message || "An unknown error occurred.");
      }

      if (status) {
        handlePaymentStatus(status, setMessage, setIsSuccess);
      }
    } catch (err) {
      setMessage(`Error confirming payment: ${err.message}`);
    } finally {
      setIsProcessing(false);
    }
  };

  return (
    <form id="payment-form" onSubmit={handleSubmit}>
      <PaymentElement ref={paymentElementRef} options={options} />
      <button disabled={isProcessing} id="submit">
        {isProcessing ? "Processing..." : "Pay now"}
      </button>
      {message && <div id="payment-message">{message}</div>}
    </form>
  );
}
```

<details>

<summary>Alternate Implementation: SDK handles the Confirm Button</summary>

For SDK to render the confirm button and handle the confirm payment, in paymentElementOptions, you can send:

```javascript
var unifiedCheckoutOptions = {
  ...,
  sdkHandleConfirmPayment: {
     handleConfirm: true,
     buttonText: "SDK Pay Now",
     confirmParams: {
       return_url: "https://example.com/complete",
     },
   },
};
```

1. **`handleConfirm (required)`** - A boolean value indicating whether the SDK should handle the confirmation of the payment.
2. **`confirmParams (required)`** - It's an object which takes return\_url. return\_url parameter specifies the URL where the user should be redirected after payment confirmation.
3. **`buttonText (optional)`** - The text to display on the payment button.\
   Default value: **Pay Now**

For customization, please follow the [`Customization docs`](https://docs.hyperswitch.io/hyperswitch-cloud/integration-guide/web/customization#id-5.-confirm-button).

</details>
{% endtab %}
{% endtabs %}

#### 3.2 Display payment status message

When Hyperswitch redirects the customer to the `return_url`, the `payment_client_secret` query parameter is appended by hyper-js. Use this to retrieve the Payment to determine what to show to your customer.

```js
//Look for a parameter called `payment_intent_client_secret` in the url which gives a payment ID, which is then used to retrieve the status of the payment

const paymentID = new URLSearchParams(window.location.search).get(
  "payment_intent_client_secret"
);

if (!paymentID) {
  return;
}

hyper.retrievePaymentIntent(paymentID).then(({ paymentIntent }) => {
  switch (paymentIntent.status) {
    case "succeeded":
      setMessage("Payment succeeded!");
      break;
    case "processing":
      setMessage("Your payment is processing.");
      break;
    case "requires_payment_method":
      setMessage("Your payment was not successful, please try again.");
      break;
    default:
      setMessage("Something went wrong.");
      break;
  }
});
```

{% hint style="danger" %}
Please retrieve the payment status from the Hyperswitch backend to get the terminal status of the payment. Do not rely solely on the status returned by the SDK, as it may not always reflect the final state of the transaction.
{% endhint %}

#### 4. Elements Events

Some events are emitted by payment elements, listening to those events is the only way to communicate with these elements. All events have a payload object with the type of the Element that emitted the event as an elementType property. Following events are emitted by payment elements.

* change
* ready
* focus
* blur

#### 4.1 Calling Elements events

First create instance of widgets using `getElement` function. It will return `null` if no matching type is found.

```js
// Create instance of widgets
var paymentElement = widgets.getElement("payment");

// handle event
if (paymentElement) {
  // in place of "EVENT" use "change", "ready", "focus" etc.
  paymentElement.on("EVENT", callbackFn);
}
```

#### 4.2 "change" event

The "change" event will be triggered when value changes in Payment element.

```js
paymentElement.on("change", function (event) {
  // YOUR CODE HERE
});
```

Callback function will be fired when the event will be triggered. When called it will be passed an event object with the following properties.

```js
{
  elementType: 'payment',   // The type of element that emitted this event.
  complete: false,          // If all required field are complete
  empty: false,             // if the value is empty.
  value: { type: "card" },  // current selected payment method like "card", "klarna" etc
}
```

#### 4.3 "ready" event

The "ready" event will be triggered when payment element is fully rendered and can accept "focus" event calls.

Callback for ready event will be triggered with following event object

```js
{
  ready: boolean,   // true when payment element is fully rendered
}
```

#### 4.4 "focus", "blur" event

Focus and blur event triggered when respective event will be triggered in payment element.

Callback for these event will be triggered with following event object.

```js
// Event object for focus event
{
  focus: boolean,   // true when focused on payment element
}

// Event object for blur event
{
  blur: boolean,
}
```

Congratulations! Now that you have integrated the Hyperswitch SDK on your app, you can customize the payment elements to blend with the rest of your app.

#### 5. Additional Callback Handling for Wallets Payment Process

This document outlines the details and functionality of an optional callback and `onPaymentComplete` that can be provided by merchants during the payment process. These callbacks allow merchants to hook into the payment flow at key stages and handle specific actions or events before continuing the normal flow.

* **onPaymentButtonClick:** This callback is triggered immediately after the user clicks any wallet button.
* **onPaymentComplete:** This callback is triggered after the payment is completed, just before the SDK redirects to `walletReturnUrl` provided. It allows the merchant to handle actions post-payment. If not provided, the SDK's default flow will proceed.

{% hint style="warning" %}
**Redirection Handling:** The `onPaymentComplete` callback should handle redirection or any steps needed after payment, as the SDK no longer does this automatically. You must ensure to implement the necessary redirection logic.
{% endhint %}

{% hint style="info" %}
**Fallback:** If no callbacks are provided by the merchant, the SDK will continue with its default behaviour, including automatic redirection after payment completion.
{% endhint %}

{% hint style="danger" %}
The task within `onPaymentButtonClick` must be completed within 1 second. If an asynchronous callback is used, it must resolve within this time to avoid Apple Pay payment failures.
{% endhint %}

**Example Usage for React Integration**

```jsx
<PaymentElement
  id="payment-element"
  options={options}
  onPaymentButtonClick={() => {
    console.log("This is a SYNC CLICK");
    // Add any custom logic for when the payment button is clicked, such as logging or tracking
  }}
  onPaymentComplete={() => {
    console.log("OnPaymentComplete");
    // Add any custom post-payment logic here, such as redirection or displaying a success message
  }}
/>
```

### Next step:

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}


# HTML with REST API Integration

Integrate Hyperswitch SDK to your HTML Web App using REST API for a seamless payment experience

**Before following these steps, please configure your payment methods** [here](https://hyperswitch.io/docs/paymentMethods/cards). Use this guide to integrate `hyperswitch` SDK to your HTML app. You can also use this demo app as a reference with your Juspay Hyperswitch credentials to test the setup.

### [<mark style="color:blue;">Demo App</mark>](https://github.com/PritishBudhiraja/hyperswitch-demo-app/archive/refs/heads/master.zip)

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on the client

#### 2.1 Load HyperLoader

Use `HyperLoader` to ensure PCI compliant means of accepting payment details from your customer and sending it directly to the Hyperswitch server. Always load `hyperLoader` from `https://beta.hyperswitch.io/v1/HyperLoader.js` to ensure compliance. Please refrain from including the script in a bundle or hosting it yourself.

```js
<script src="https://beta.hyperswitch.io/v1/HyperLoader.js"></script>
```

#### 2.2 Define the payment form

{% hint style="info" %}
This step is recommended for the Unified Checkout for an enhanced user experience. In case you are integrating Express Checkout (mentioned later below), this step is not required.
{% endhint %}

Add one empty placeholder `div` to your checkout form for each Widget that you'll mount. `HyperLoader` inserts an iframe into each `div` to securely collect the customer's email address and payment information.

```js
<form id="payment-form">
  <div id="unified-checkout">
   <!--HyperLoader injects the Unified Checkout-->
  </div>
  <button id="submit">
    <div class="spinner hidden" id="spinner"></div>
    <span id="button-text">Pay now</span>
  </button>
  <div id="payment-message" class="hidden"></div>
</form>
```

#### 2.3 Initialize HyperLoader

Initialize `HyperLoader` onto your app with your publishable key with the `Hyper` constructor. You'll use `HyperLoader` to create the Unified Checkout and complete the payment on the client. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

**Standard Configuration**

```js
const hyper = Hyper("YOUR_PUBLISHABLE_KEY",{
    customBackendUrl: "YOUR_BACKEND_URL",
    //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
});
```

**Advanced / Extended Configuration&#x20;*****(Beta / Upcoming)***

In platform setups or custom deployment environments (e.g., dedicated backend, custom telemetry, or asset routing), you can pass an extended configuration object to `Hyper`:

```js
const hyper = Hyper({
  publishableKey: "YOUR_PUBLISHABLE_KEY",
  profileId: "YOUR_PROFILE_ID",
  platformPublishableKey: "pk_platform_xxxx", // Required for platform or connected account setups
  customConfig: {
    customEndpoint: "https://dev.hyperswitch.io/api",                     // Primary Hyperswitch API base URL
    overrideCustomBackendEndpoint: "https://sandbox.hyperswitch.io",      // Custom backend API endpoint
    // overrideCustomConfirmEndpoint: "https://sandbox.hyperswitch.io",   // Custom payment confirm calls endpoint
    // overrideCustomSDKConfigEndpoint: "https://config.example.com/api", // Custom SDK config fetch endpoint
    // overrideCustomLoggingEndpoint:   "https://logs.example.com/logs",  // Custom beacon/telemetry logging endpoint
    // overrideCustomAssetsEndpoint:    "https://assets.example.com",     // Custom static assets endpoint
  },
});
```

{% tabs %}
{% tab title="UnifiedCheckout" %}
**2.4 Fetch the Payment and create the Unified Checkout**

<figure><img src="/files/N5y0vbdmkMAv3nTD0ZT1" alt=""><figcaption></figcaption></figure>

Immediately make a request to the endpoint on your server to create a new Payment as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.

> Important: Make sure to never share your API key with your client application as this could potentially compromise your payment flow

Following this, create a `unifiedCheckout` and mount it to the placeholder `div` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the `Payment`, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.

**Standard Implementation**

```js
<script src="https://beta.hyperswitch.io/v1/HyperLoader.js"></script>;
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ items: [{ id: "xl-tshirt" }], country: "US" }),
  });
  const { clientSecret } = await response.json();

  const appearance = {
    theme: "midnight",
  };

  widgets = hyper.widgets({ appearance, clientSecret });

  const unifiedCheckoutOptions = {
    layout: "tabs",
    wallets: {
      walletReturnUrl: "https://example.com/complete",
      //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
    },
  };

  const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
  unifiedCheckout.mount("#unified-checkout");
}
```

**Alternative Object Syntax&#x20;*****(Beta / Upcoming)***\
You can also initialize widgets using an integrated configuration object, offering a cleaner structure when configuring widget types and options together:

```js
// Alternative widget creation syntax
const unifiedCheckout = widgets.create({
  type: "payment",
  options: unifiedCheckoutOptions,
});

unifiedCheckout.mount("#unified-checkout");
```

{% endtab %}

{% tab title="ExpressCheckout" %}
**2.4 Fetch the Payment and create the Express Checkout**

<figure><img src="/files/IeqQ5DTtab94K5xekcPW" alt=""><figcaption></figcaption></figure>

> The Express Checkout Element gives you a single integration for accepting payments through one-click payment buttons. Supported payment methods include ApplePay, GooglePay and PayPal.

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to complete the payment.

> Important: Make sure to never share your API key with your client application as this could potentially compromise your payment flow

Create an `expressCheckout` and mount it to the placeholder `div` in your payment form. This embeds an iframe that displays configured payment method types supported by the browser available for the payment, allowing your customer to select a payment method. The payment methods automatically collects the associated payment details for the selected payment method type.

**Standard Implementation**

```js
<script src="https://beta.hyperswitch.io/v1/HyperLoader.js"></script>;
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ items: [{ id: "xl-tshirt" }], country: "US" }),
  });
  const { clientSecret } = await response.json();

  const appearance = {
    theme: "midnight",
  };

  widgets = hyper.widgets({ appearance, clientSecret });

  const expressCheckoutOptions = {
    wallets: {
      walletReturnUrl: "https://example.com/complete",
      //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
    },
  };

  const expressCheckout = widgets.create("expressCheckout", expressCheckoutOptions);
  expressCheckout.mount("#express-checkout");
}
```

**Alternative Object Syntax&#x20;*****(Beta / Upcoming)***

```js
// Alternative widget creation syntax
const unifiedCheckout = widgets.create({
  type: "expressCheckout",
  options: expressCheckoutOptions,
});

unifiedCheckout.mount("#express-checkout");

```

{% endtab %}
{% endtabs %}

### 3. Complete payment on the client

#### 3.1 Handle the submit event and complete the payment

> Note: This step is not required for ExpressCheckout

Listen to the form's submit event to know when to confirm the payment through the hyper API.

Call `confirmPayment()`, passing along the `unifiedCheckout` and a `return_url` to indicate where Hyper should redirect the user after they complete the payment. Hyper redirects the customer to an authentication page depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.

**Standard Implementation**

```js
async function handleSubmit(e) {
  setMessage("");
  e.preventDefault();

  if (!hyper || !widgets) {
    return;
  }
  setIsLoading(true);

  const { error, status } = await hyper.confirmPayment({
    widgets,
    confirmParams: {
      // Make sure to change this to your payment completion page
      return_url: "https://example.com/complete",
    },
    redirect: "always", // if you wish to redirect always, otherwise it is defaulted to "if_required"
  });

  if (error) {
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message);
    } else {
      if (error.message) {
        setMessage(error.message);
      } else {
        setMessage("An unexpected error occurred.");
      }
    }
  }
  if (status) {
    handlePaymentStatus(status); //handle payment status
  }
  setIsLoading(false);
}
```

**Direct Widget Confirmation&#x20;*****(Beta / Upcoming)***

Also if there are any immediate errors (for example, your customer's card is declined), `HyperLoader` returns an error. Show that error message to your customer so they can try again.

```js
async function handleSubmit(e) {
  setMessage("");
  e.preventDefault();

  if (!unifiedCheckout) {
    return;
  }
  setIsLoading(true);

  // Call confirmPayment directly on the unifiedCheckout instance
  const { error, status } = await unifiedCheckout.confirmPayment({
    confirmParams: {
      return_url: "https://example.com/complete",
    },
    redirect: "always",
  });

  if (error) {
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message);
    } else {
      setMessage(error.message || "An unexpected error occurred.");
    }
  }

  if (status) {
    handlePaymentStatus(status);
  }
  setIsLoading(false);
}
```

<details>

<summary>Alternate Implementation: SDK handles the Confirm Button</summary>

For SDK to render the confirm button and handle the confirm payment, in paymentElementOptions, you can send:

```html
const unifiedCheckoutOptions = {
  ...,
  sdkHandleConfirmPayment: {
     handleConfirm: true,
     buttonText: "SDK Pay Now",
     confirmParams: {
       return_url: "https://example.com/complete",
     },
   },
};
```

1. **`handleConfirm (required)`** - A boolean value indicating whether the SDK should handle the confirmation of the payment.
2. **`confirmParams (required)`** - It's an object which takes return\_url. return\_url parameter specifies the URL where the user should be redirected after payment confirmation.
3. **`buttonText (optional)`** - The text to display on the payment button.\
   Default value: **Pay Now**

For customization, please follow the [`Customization docs`](https://docs.hyperswitch.io/hyperswitch-cloud/integration-guide/web/customization#id-5.-confirm-button).

</details>

#### 3.2 Display a payment status message

When Hyper redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by `HyperLoader`. Use this to retrieve the `Payment` to determine what to show to your customer.

```js
// Fetches the payment status after payment submission
async function checkStatus() {
  const clientSecret = new URLSearchParams(window.location.search).get(
    "payment_intent_client_secret"
  );

  if (!clientSecret) {
    return;
  }

  const { payment } = await hyper.retrievePayment(clientSecret);

  switch (payment.status) {
    case "succeeded":
      showMessage("Payment succeeded!");
      break;
    case "processing":
      showMessage("Your payment is processing.");
      break;
    case "requires_payment_method":
      showMessage("Your payment was not successful, please try again.");
      break;
    default:
      showMessage("Something went wrong.");
      break;
  }
}
```

Congratulations! Now that you have integrated the Hyperswitch SDK on your app, you can customize the payment elements to blend with the rest of your app.


# JS with REST API Integration

Integrate Juspay Hyperswitch SDK to any Web App using hyperswitch-node for seamless payment processing

**Before following these steps, please configure your payment methods** [here](https://hyperswitch.io/docs/paymentMethods/cards). Use this guide to integrate Juspay Hyperswitch SDK to your app with any framework. If you are using React framework please go through [React ](/integration-guide/payment-suite/payment-method-card/web/react-with-rest-api-integration)Integration to use a dedicated wrapper.\\

### [<mark style="color:blue;">Demo App</mark>](https://github.com/PritishBudhiraja/hyperswitch-demo-app/archive/refs/heads/master.zip)

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on the client

#### 2.1 Define the payment form

{% hint style="info" %}
This step is recommended for the Unified Checkout for an enhanced user experience. In case you are integrating Express Checkout (mentioned later below), this step is not required.
{% endhint %}

Add one empty placeholder `div` to your checkout form for each Widget that you'll mount. `HyperLoader` inserts an iframe into each `div` to securely collect the customer's email address and payment information.

```js
<form id="payment-form">
  <div id="unified-checkout">
   <!--HyperLoader injects the Unified Checkout-->
  </div>
  <button id="submit">
    <div class="spinner hidden" id="spinner"></div>
    <span id="button-text">Pay now</span>
  </button>
  <div id="payment-message" class="hidden"></div>
</form>
```

{% tabs %}
{% tab title="UnifiedCheckout" %}
**2.2 Fetch the Payment and create the Unified Checkout**

<figure><img src="/files/N5y0vbdmkMAv3nTD0ZT1" alt=""><figcaption></figcaption></figure>

Immediately make a request to the endpoint on your server to create a new Payment as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.

> Important: Make sure to never share your API key with your client application as this could potentially compromise your payment flow

Following this, create a `unifiedCheckout` and mount it to the placeholder `div` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the `Payment`, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.

In case you want the SDK to be loaded on a particular event (like button click), you can call the initialize function on that event.

**Standard Implementation**

```js
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({currency: "USD",amount: 100}),
  });
  const { clientSecret } = await response.json();
  
  // Initialise Hyperloader.js
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";
 
  let hyper; 
  script.onload = () => {
      hyper = window.Hyper("YOUR_PUBLISHABLE_KEY",{
      customBackendUrl: "YOUR_BACKEND_URL",
      //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
      })
      const appearance = {
          theme: "midnight",
      };
      const widgets = hyper.widgets({ appearance, clientSecret });
      const unifiedCheckoutOptions = {
          layout: "tabs",
          wallets: {
              walletReturnUrl: "https://example.com/complete",
              //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
          },
      };
      const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
      unifiedCheckout.mount("#unified-checkout");
  };
  document.body.appendChild(script);
}
```

**Integrated Configuration Object&#x20;*****(Beta / Upcoming)***\
Alternatively, you can create the widget by passing a single configuration object into `widgets.create()`, providing a cleaner structure when passing options:

```js
script.onload = () => {
    const hyper = window.Hyper({
      publishableKey: "YOUR_PUBLISHABLE_KEY",
      profileId: "YOUR_PROFILE_ID",
      platformPublishableKey: "pk_platform_xxxx", // Required for platform or connected account setups
      customConfig: {
        customEndpoint: "https://dev.hyperswitch.io/api",                  // Primary Hyperswitch API base URL
        overrideCustomBackendEndpoint: "https://sandbox.hyperswitch.io",   // Custom backend API endpoint
        // overrideCustomConfirmEndpoint: "https://sandbox.hyperswitch.io",   // Custom payment confirm calls endpoint
        // overrideCustomSDKConfigEndpoint: "https://config.example.com/api", // Custom SDK config fetch endpoint
        // overrideCustomLoggingEndpoint:   "https://logs.example.com/logs",  // Custom beacon/telemetry logging endpoint
        // overrideCustomAssetsEndpoint:    "https://assets.example.com",     // Custom static assets endpoint
      },
    });

    const appearance = { theme: "midnight" };
    const widgets = hyper.widgets({ appearance, clientSecret });

    const unifiedCheckoutOptions = {
      layout: "tabs",
      wallets: {
        walletReturnUrl: "https://example.com/complete",
      },
    };

    // Beta / Upcoming syntax: passing type and options inside a single object
    const unifiedCheckout = widgets.create({
      type: "payment",
      options: unifiedCheckoutOptions,
    });

    unifiedCheckout.mount("#unified-checkout");
  };
```

**2.3 Additional Callback Handling for Wallets Payment Process**

This document outlines the details and functionality of an optional callback `completeDoThis` and `onSDKHandleClick` that can be provided by merchants during the payment process. These callbacks allow merchants to hook into the payment flow at key stages and handle specific actions or events before continuing the normal flow.

* **onSDKHandleClick:** This callback is triggered immediately after the user clicks any wallet button.
* **completeDoThis:** This callback is triggered after the payment is completed, just before the SDK redirects to `walletReturnUrl` provided. It allows the merchant to handle actions post-payment. If not provided, the SDK's default flow will proceed.

{% hint style="warning" %}
**Redirection Handling:** The `onPaymentComplete` callback should handle redirection or any steps needed after payment, as the SDK no longer does this automatically. You must ensure to implement the necessary redirection logic.
{% endhint %}

{% hint style="info" %}
**Fallback:** If no callbacks are provided by the merchant, the SDK will continue with its default behaviour, including automatic redirection after payment completion.
{% endhint %}

{% hint style="danger" %}
The task within `onPaymentButtonClick` must be completed within 1 second. If an asynchronous callback is used, it must resolve within this time to avoid Apple Pay payment failures.
{% endhint %}

**Example Usage**

```javascript
const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
unifiedCheckout.mount("#unified-checkout");

unifiedCheckout.onSDKHandleClick(()=>{
  // Add any custom logic for when the payment button is clicked, such as logging or tracking
  console.log("On Click Wallets")
})

unifiedCheckout.on("completeDoThis",()=>{
  console.log("On Payment Complete")
  // Add any custom post-payment logic here, such as redirection or displaying a success message
})
```

{% endtab %}

{% tab title="ExpressCheckout" %}
**2.2 Fetch the Payment and create the Express Checkout**

<figure><img src="/files/IeqQ5DTtab94K5xekcPW" alt=""><figcaption></figcaption></figure>

> The Express Checkout Element gives you a single integration for accepting payments through one-click payment buttons. Supported payment methods include ApplePay, GooglePay and PayPal.

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to complete the payment.

> Important: Make sure to never share your API key with your client application as this could potentially compromise your payment flow

Create an `expressCheckout` and mount it to the placeholder `div` in your payment form. This embeds an iframe that displays configured payment method types supported by the browser available for the payment, allowing your customer to select a payment method. The payment methods automatically collects the associated payment details for the selected payment method type.\
\
**Standard Implementation**

```js
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({currency: "USD",amount: 100}),
  });
  const { clientSecret } = await response.json();
  
  // Initialise Hyperloader.js
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";
 
  let hyper; 
  script.onload = () => {
      hyper = window.Hyper("YOUR_PUBLISHABLE_KEY")
      const appearance = {
          theme: "midnight",
      };
      const widgets = hyper.widgets({ appearance, clientSecret });
      const expressCheckoutOptions = {
          wallets: {
              walletReturnUrl: "https://example.com/complete",
              //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
          },
      };
      const expressCheckout = widgets.create("expressCheckout", expressCheckoutOptions);
      expressCheckout.mount("#express-checkout");
  };
  document.body.appendChild(script);
}
```

**Integrated Configuration Object&#x20;*****(Beta / Upcoming)***\
Alternatively, you can pass a single configuration object into `widgets.create()` to initialize the Express Checkout element:

```js
script.onload = () => {
    const hyper = window.Hyper({
      publishableKey: "YOUR_PUBLISHABLE_KEY",
      profileId: "YOUR_PROFILE_ID",
      platformPublishableKey: "pk_platform_xxxx", // Required for platform or connected account setups
      customConfig: {
        customEndpoint: "https://dev.hyperswitch.io/api",                  // Primary Hyperswitch API base URL
        overrideCustomBackendEndpoint: "https://sandbox.hyperswitch.io",   // Custom backend API endpoint
        // overrideCustomConfirmEndpoint: "https://sandbox.hyperswitch.io",   // Custom payment confirm calls endpoint
        // overrideCustomSDKConfigEndpoint: "https://config.example.com/api", // Custom SDK config fetch endpoint
        // overrideCustomLoggingEndpoint:   "https://logs.example.com/logs",  // Custom beacon/telemetry logging endpoint
        // overrideCustomAssetsEndpoint:    "https://assets.example.com",     // Custom static assets endpoint
      },
    });

    const appearance = {
      theme: "midnight",
    };
    const widgets = hyper.widgets({ appearance, clientSecret });

    const expressCheckoutOptions = {
      wallets: {
        walletReturnUrl: "https://example.com/complete",
      },
    };

    // Beta / Upcoming syntax: passing type and options inside a single object
    const expressCheckout = widgets.create({
      type: "expressCheckout",
      options: expressCheckoutOptions,
    });

    expressCheckout.mount("#express-checkout");
  };
```

{% endtab %}
{% endtabs %}

### 3. Complete payment on the client

#### 3.1 Handle the submit event and complete the payment

> Note: This step is not required for ExpressCheckout

Listen to the form's submit event to know when to confirm the payment through the hyper API.

Call `confirmPayment()`, passing along the `unifiedCheckout` and a `return_url` to indicate where Hyper should redirect the user after they complete the payment. Hyper redirects the customer to an authentication page depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.

**Standard Implementation**

```js
async function handleSubmit(e) {
  setMessage("");
  e.preventDefault();

  if (!hyper || !widgets) {
    return;
  }
  setIsLoading(true);

  const { error, status } = await hyper.confirmPayment({
    widgets,
    confirmParams: {
      // Make sure to change this to your payment completion page
      return_url: "https://example.com/complete",
    },
    redirect: "always", // if you wish to redirect always, otherwise it is defaulted to "if_required"
  });

  if (error) {
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message);
    } else {
      if (error.message) {
        setMessage(error.message);
      } else {
        setMessage("An unexpected error occurred.");
      }
    }
  }
  if (status) {
    handlePaymentStatus(status); //handle payment status
  }
  setIsLoading(false);
}
```

**Direct Element Confirmation&#x20;*****(Beta / Upcoming)***

```js
async function handleSubmit(e) {
  setMessage("");
  e.preventDefault();

  if (!unifiedCheckout) {
    return;
  }
  setIsLoading(true);

  // Call confirmPayment directly on the unifiedCheckout instance
  const { error, status } = await unifiedCheckout.confirmPayment({
    confirmParams: {
      return_url: "https://example.com/complete",
    },
    redirect: "always",
  });

  if (error) {
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message);
    } else {
      setMessage(error.message || "An unexpected error occurred.");
    }
  }

  if (status) {
    handlePaymentStatus(status);
  }
  setIsLoading(false);
}
```

Also if there are any immediate errors (for example, your customer's card is declined), `HyperLoader` returns an error. Show that error message to your customer so they can try again.

#### 3.2 Display a payment status message

When Hyper redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by `HyperLoader`. Use this to retrieve the `Payment` to determine what to show to your customer.

```js
// Fetches the payment status after payment submission
async function checkStatus() {
  const clientSecret = new URLSearchParams(window.location.search).get(
    "payment_intent_client_secret"
  );

  if (!clientSecret) {
    return;
  }

  const { payment } = await hyper.retrievePayment(clientSecret);

  switch (payment.status) {
    case "succeeded":
      showMessage("Payment succeeded!");
      break;
    case "processing":
      showMessage("Your payment is processing.");
      break;
    case "requires_payment_method":
      showMessage("Your payment was not successful, please try again.");
      break;
    default:
      showMessage("Something went wrong.");
      break;
  }
}
```

Congratulations! Now that you have integrated the Hyperswitch SDK on your app, you can customize the payment elements to blend with the rest of your app.


# Headless SDK

Juspay Hyperswitch is designed to facilitate the integration and management of payment-related functionalities in a decoupled or headless architecture with flexibility to customize your checkout UI.

### Customize the payment experience using Headless functions

#### 1. Initialize the Hyperswitch SDK

Initialize Juspay Hyperswitch Headless SDK onto your app with your publishable key. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

**Standard Implementation**

<pre class="language-javascript"><code class="lang-javascript"><strong>// Source Hyperloader on your HTML file using the &#x3C;script /> tag
</strong>hyper = Hyper.init("YOUR_PUBLISHABLE_KEY",{
    customBackendUrl: "YOUR_BACKEND_URL",
    //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
});
</code></pre>

**Advanced / Extended Configuration&#x20;*****(Beta / Upcoming)***

In platform setups or custom deployment environments (e.g., dedicated backend, custom telemetry, or asset routing), you can pass an extended configuration object to `Hyper`:

```
const hyper = Hyper.init({
  publishableKey: "YOUR_PUBLISHABLE_KEY",
  profileId: "YOUR_PROFILE_ID",
  platformPublishableKey: "pk_platform_xxxx", // Required for platform or connected account setups
  customConfig: {
    customEndpoint: "https://dev.hyperswitch.io/api",                  // Primary Hyperswitch API base URL
    overrideCustomBackendEndpoint: "https://sandbox.hyperswitch.io",   // Custom backend API endpoint
    overrideCustomConfirmEndpoint: "https://sandbox.hyperswitch.io",   // Custom payment confirm calls endpoint
    overrideCustomSDKConfigEndpoint: "https://config.example.com/api", // Custom SDK config fetch endpoint
    overrideCustomLoggingEndpoint:   "https://logs.example.com/logs",  // Custom beacon/telemetry logging endpoint
    overrideCustomAssetsEndpoint:    "https://assets.example.com",     // Custom static assets endpoint
  },
});
```

#### 2. Create a PaymentIntent

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to initialize the payment session.

{% hint style="danger" %}
**Important**: Make sure to never share your API key with your client application as this could potentially compromise your security
{% endhint %}

#### 3. Initialize your Payment Session

Initialize a Payment Session by passing the clientSecret to the `initPaymentSession`

```javascript
paymentSession = hyper.initPaymentSession({
  clientSecret: client_secret,
});
```

| options (Required)                   | Description                                                     |
| ------------------------------------ | --------------------------------------------------------------- |
| `paymentIntentClientSecret (string)` | **Required.** Required to use as the identifier of the payment. |

#### 4. Craft a customized payments experience

Using the `paymentSession` object, the default customer payment method data can be fetched, using which you can craft your own payments experience. The `paymentSession` object also exposes a `confirmWithCustomerDefaultPaymentMethod` and `confirmWithLastUsedPaymentMethod` function, using which you can confirm and handle the payment session.

**4a. Confirm using Customer Default Payment Method:**

```javascript
paymentMethodSession = await paymentSession.getCustomerSavedPaymentMethods();

if (paymentMethodSession.error) {
    // handle the case where no default customer payment method is not present
} else {
    // use the customer_default_saved_payment_method_data to fulfill your usecases (render UI)
    const customer_default_saved_payment_method_data =
        paymentMethodSession.getCustomerDefaultSavedPaymentMethodData();
}

// handle submit for pay button 
function handleSubmit() { 
    if (paymentMethodSession.error) {
        // handle the case where no default customer payment method is not present
    } else {
        // use the confirmWithCustomerDefaultPaymentMethod function to confirm and handle the payment session response
        const { error, status } = await
        paymentMethodSession.
            confirmWithCustomerDefaultPaymentMethod({
                confirmParams: {
                    // Make sure to change this to your payment completion page
                    return_url: "https://example.com/complete"
                },
                // if you wish to redirect always, otherwise it is defaulted to "if_required"
                redirect: "always",
                // Pass the CardCVCElement id
                id: "card-cvc-element"
            });

        // use error, status to complete the payment journey
        if (error) {
            if (error.message) {
                // handle error messages
                setMessage(error.message);
            } else {
                setMessage("An unexpected error occurred.");
            }
        }
        if (status) {
            // handle payment status
            handlePaymentStatus(status);
        }
    }
}
```

**Payload for** `confirmWithCustomerDefaultPaymentMethod(payload)`

<table><thead><tr><th width="296">options (Required)</th><th>Description</th></tr></thead><tbody><tr><td><code>confirmParams (object)</code></td><td>Parameters that will be passed on to the Hyper API.</td></tr><tr><td><code>redirect (string)</code></td><td><p><strong>Can be either 'always' or 'if_required'</strong></p><p>By default, <code>confirmWithCustomerDefaultPaymentMethod()</code> will always redirect to your <code>return_url</code> after a successful confirmation. If you set redirect: "if_required", then this method will only redirect if your user chooses a redirection-based payment method.</p></td></tr><tr><td><code>id (string)</code><strong><code>(optional)</code></strong></td><td>The id used when creating the CardCVCElement.</td></tr></tbody></table>

**ConfirmParams object**

<table><thead><tr><th width="281">confirmParams</th><th>Description</th></tr></thead><tbody><tr><td><code>return_url(string)</code></td><td>The url your customer will be directed to after they complete payment.</td></tr></tbody></table>

**4b. Confirm using Last Used Payment Method:**

```javascript
paymentMethodSession = await paymentSession.getCustomerSavedPaymentMethods();

if (paymentMethodSession.error) {
    // handle the case where no default customer payment method is not present
} else {
    // use the customer_last_used_payment_method_data to fulfill your usecases (render UI)
    const customer_last_used_payment_method_data =
        paymentMethodSession.getCustomerLastUsedPaymentMethodData();
}

// handle submit for pay button 
function handleSubmit() { 
    if (paymentMethodSession.error) {
        // handle the case where no default customer payment method is not present
    } else {
        // use the confirmWithLastUsedPaymentMethod function to confirm and handle the payment session response
        const { error, status } = await
        paymentMethodSession.
            confirmWithLastUsedPaymentMethod({
                confirmParams: {
                    // Make sure to change this to your payment completion page
                    return_url: "https://example.com/complete"
                },
                // if you wish to redirect always, otherwise it is defaulted to "if_required"
                redirect: "always",
                // Pass the CardCVCElement id
                id: "card-cvc-element"
            });

        // use error, status to complete the payment journey
        if (error) {
            if (error.message) {
                // handle error messages
                setMessage(error.message);
            } else {
                setMessage("An unexpected error occurred.");
            }
        }
        if (status) {
            // handle payment status
            handlePaymentStatus(status);
        }
    }
}
```

**Payload for** `confirmWithLastUsedPaymentMethod(payload)`

<table><thead><tr><th width="296">options (Required)</th><th>Description</th></tr></thead><tbody><tr><td><code>confirmParams (object)</code></td><td>Parameters that will be passed on to the Hyper API.</td></tr><tr><td><code>redirect (string)</code></td><td><p><strong>Can be either 'always' or 'if_required'</strong></p><p>By default, <code>confirmWithLastUsedPaymentMethod()</code> will always redirect to your <code>return_url</code> after a successful confirmation. If you set redirect: "if_required", then this method will only redirect if your user chooses a redirection-based payment method.</p></td></tr><tr><td><code>id (string)</code><strong><code>(optional)</code></strong></td><td>The id used when creating the CardCVCElement.</td></tr></tbody></table>

**ConfirmParams object**

<table><thead><tr><th width="281">confirmParams</th><th>Description</th></tr></thead><tbody><tr><td><code>return_url(string)</code></td><td>The url your customer will be directed to after they complete payment.</td></tr></tbody></table>

#### 5. Add CVC Collection (Non PCI Approach)

The `CardCVCElement` renders a secure iframe to collect the customer's CVC without exposing sensitive data to your application. You can follow the [React Integration](https://docs.hyperswitch.io/explore-hyperswitch/payment-experience/payment/web/react-with-rest-api-integration).

```javascript
import React, { useState, useEffect } from "react";
import {
  CardCVCElement,
  useHyper,
} from "@juspay-tech/react-hyper-js";

export default function Checkout() {
  const hyper = useHyper();

 // handle submit for pay button 
 function handleSubmit() {
   // You can follow the same as mentioned in 4. Craft a customized payments experience
 } 

  return (
    <div>
      {/* Render your saved card UI here */}

      {/* CVC Element */}
      <div style={{ marginTop: "16px" }}>
        <CardCVCElement id="card-cvc-element" />
      </div>

      {/* Pay Button */}
      <button onClick={handleSubmit} disabled={isProcessing}>
        {isProcessing ? "Processing..." : "Pay Now"}
      </button>

      {/* Error Message */}
      {message && <div>{message}</div>}
    </div>
  );
}
```


# Customization

Customize your Web unified checkout for Juspay Hyperswitch

### 1. Layouts

Choose a layout that fits well with your UI pattern. There are two types of layout options as listed below. The layout defaults to accordion if not explicitly specified.

#### 1.1 Accordion layout

The accordion layout displays payment methods vertically using an accordion. To use this layout, set the value for layout to accordion. You also have the option to specify other properties, such as those shown in the following example.

```js
var paymentElementOptions = {
  layout: {
    type: 'accordion',
    defaultCollapsed: false,
    radios: true,
    spacedAccordionItems: false
  },
}

--- or ---

var paymentElementOptions = {
  layout: 'accordion'
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

#### 1.2 Tabs layout

The tabs layout displays payment methods horizontally using tabs. To use this layout, set the value for layout to tabs. You also have the option to specify other properties, such as tabs or collapsed.

```js
var paymentElementOptions = {
  layout: 'tabs'
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

#### 1.2.1 Tabs layout - Grid arrangement

By default, the tabs layout shows excess payment methods inside a dropdown. If you want to display all payment methods at once in a grid view, you can customize the tabs layout using `paymentMethodsArrangementForTabs`.

When `paymentMethodsArrangementForTabs` is set to `grid`, the tabs layout switches to a grid style

`paymentMethodsArrangementForTabs` supports the following values:

* `default` – Shows excess payment methods in a dropdown (default).
* `grid` – Shows all payment methods in a grid without a dropdown.

To enable the grid arrangement in tabs layout, configure the layout object as shown below.

```javascript
var paymentElementOptions = {
  layout: {
    type: 'tabs',
    paymentMethodsArrangementForTabs: 'grid' 
  }
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

#### 1.3 Saved Methods Customization

In this layout, by default saved payment methods are shown for a quick checkout. Customers can select an existing method or add a new one using New payment methods, which reveals the payment form inline.

This layout optimizes for faster repeat payments while still supporting new payment method entry in a single, seamless flow.

`hideCardExpiry` - When `hideCardExpiry` is set to true, the expiry date displayed on saved card items is hidden, and the CVC input is rendered inline next to the card details instead of below them. This creates a more compact saved card view.

**One-click wallets** such as Google Pay, Apple Pay, and PayPal are always shown at the top of the checkout to enable faster, low-friction payments. This is available for both Accordion and Tabs layout.

```
var paymentElementOptions = {
   layout: {
    savedMethodCustomization: {
      groupingBehavior: "groupByPaymentMethods",
      hideCardExpiry: true, // default - false
    }
  }
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

#### 1.4 One Click Payment Methods Customization

By default, one-click payment methods such as Google Pay and Apple Pay are always displayed at the top of the checkout, regardless of the selected layout (Accordion or Tabs).

If you want to display one-click payment methods alongside other payment methods inside the layout instead of at the top, you can disable this behavior using `displayOneClickPaymentMethodsOnTop`.

When `displayOneClickPaymentMethodsOnTop` is set to `false`:

* Supported one-click methods are moved into the selected layout (Tabs or Accordion).
* Unsupported one-click methods are hidden.

To customize one-click payment method placement, configure the layout object as shown below.

```javascript
var paymentElementOptions = {
   layout: {
    type: 'tabs',
    displayOneClickPaymentMethodsOnTop: false, //Default - true
  }
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

{% hint style="info" %}
Note: Currently, only Google Pay, Apple Pay, and PayPal (Redirect) support being moved into the layout. Other one-click methods are hidden when this option is disabled.
{% endhint %}

### 2. Wallets

The wallet customization feature lets users configure payment options like Apple Pay, Google Pay, PayPal, and Klarna. It includes a `walletReturnUrl` for post-payment redirects and a `style` property to customize the wallet's appearance, offering flexibility for seamless integration.

<pre class="language-javascript"><code class="lang-javascript">var paymentElementOptions = {
    wallets: {
      walletReturnUrl: `${window.location.origin}`,
      applePay: "auto",
      googlePay: "auto",
      payPal: "auto",
      klarna: "never",
      style: {
        theme: "dark",
        type: "default",
        height: 55,
        buttonRadius: 4,
      },
    },
  }
  
<strong>&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</strong></code></pre>

| Variable                                                                                        | Description                                                                                                                                                                                                                                                                                                                    | Values                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| walletReturnUrl: string                                                                         | Defines the URL to redirect users to after completing a payment.                                                                                                                                                                                                                                                               | This will take a **URL string** as its value                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| <p>applePay: showType<br>googlePay: showType<br>payPal: showType<br>klarna: showType</p>        | Determines the visibility of Apple Pay, Google Pay, PayPal and Klarna.                                                                                                                                                                                                                                                         | <p><code>showType</code> can take two values:</p><ul><li><code>"auto"</code>: Display when supported.</li><li><code>"never"</code>: Always hidden</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                    |
| <p>style: {<br>theme: theme,<br>type: styleType,<br>height: int,<br>buttonRadius: int,<br>}</p> | <p>Configures the wallet's appearance with the following options:</p><ul><li><code>theme</code>: Sets the theme.</li><li><code>type</code>: Defines the style type (e.g. buy).</li><li><code>height</code>: Specifies the height of the wallet.</li><li><code>buttonRadius</code>: Adjusts the button corner radius.</li></ul> | <p><code>theme</code>: It can take values as <code>dark</code>, <code>light</code>, or <code>outline</code>.<br><br><code>type</code>: Specifies the wallet button style with options including <code>checkout</code>, <code>pay</code>, <code>buy</code>, <code>installment</code>, <code>default</code>, <code>book</code>, <code>donate</code>, <code>order</code>, <code>addmoney</code>, <code>topup</code>, <code>rent</code>, <code>subscribe</code>, <code>reload</code>, <code>support</code>, <code>tip</code>, and <code>contribute</code>.<br></p> |

### 3. Styling variables

The Styling APIs could be used to blend the Unified Checkout with the rest of your app or website.

| Variable              | Description                                                                                                                                                        |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| fontFamily            | The font family is used throughout Widgets. Widget supports css fonts and custom fonts by passing the fonts option; reference to elements consumer                 |
| fontSizeBase          | The font size that's set on the root of the Widget. By default, other font size variables like fontSizeXs or fontSizeSm are scaled from this value using rem units |
| spacingUnit           | The base spacing unit that all other spacing is derived from. Increase or decrease this value to make your layout more or less spacious                            |
| borderRadius          | The border radius used for tabs, inputs, and other components in the Widget                                                                                        |
| colorPrimary          | A primary color used throughout the Widget. Set this to your primary brand color                                                                                   |
| colorBackground       | The color used for the background of inputs, tabs, and other components in the Widget                                                                              |
| colorText             | The default text color used in the Widget                                                                                                                          |
| colorDanger           | A color used to indicate errors or destructive actions in the Widget                                                                                               |
| fontVariantLigatures  | The font-variant-ligatures setting of text in the Widget                                                                                                           |
| fontVariationSettings | The font-variation-settings setting of text in the Widget                                                                                                          |
| fontWeightLight       | The font weight used for light text                                                                                                                                |
| fontWeightNormal      | The font weight used for normal text                                                                                                                               |
| fontWeightMedium      | The font weight used for medium text                                                                                                                               |
| fontWeightBold        | The font weight used for bold text                                                                                                                                 |
| fontLineHeight        | The line-height setting of text in the Widget                                                                                                                      |
| fontSizeXl            | The font size of extra-large text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                                |
| fontSizeLg            | The font size of large text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                                      |
| fontSizeSm            | The font size of small text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                                      |
| fontSizeXs            | The font size of extra-small text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                                |
| fontSize2Xs           | The font size of double-extra small text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                         |
| fontSize3Xs           | The font size of triple-extra small text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                         |
| colorSuccess          | A color used to indicate positive actions or successful results in the Element                                                                                     |
| colorWarning          | A color used to indicate potentially destructive actions in the Element                                                                                            |
| colorPrimaryText      | The color of text appearing on top of any a var(--colorPrimary) background                                                                                         |
| colorBackgroundText   | The color of text appearing on top of any a var(--colorBackground) background                                                                                      |
| colorSuccessText      | The color of text appearing on top of any a var(--colorSuccess) background                                                                                         |
| colorDangerText       | The color of text appearing on top of any a var(--colorDanger) background                                                                                          |
| colorWarningText      | The color of text appearing on top of any a var(--colorWarning) background                                                                                         |
| colorTextSecondary    | The color used for text of secondary importance. For example, this color is used for the label of a tab that isn't currently selected                              |
| colorTextPlaceholder  | The color used for input placeholder text in the Widget                                                                                                            |

### 4. Rules

The rules option is a map of CSS-like selectors to CSS properties, allowing granular customization of individual components. After defining your theme and variables, use rules to seamlessly integrate Elements to match the design of your site. The selector for a rule can target any of the public class names in the Element, as well as the supported states, pseudo-classes, and pseudo-elements for each class. For example, the following are valid selectors:

* .Tab, .Label, .Input, .InputLogo, .SaveWalletDetailsLabel, .OrPayUsingLabel, .TermsTextLabel, .InfoElement, .OrPayUsingLine
* .Tab:focus
* .Input--invalid, .Label--invalid, .InputLogo--invalid
* .Input::placeholder
* .billing-section, .billing-details-text
* .Input--empty, .InputLogo--empty

Each class name used in a selector supports an allowlist of CSS properties that you specify using camel case (for example, boxShadow for the box-shadow property). The following is the complete list of supported class names and corresponding states, pseudo-classes, and pseudo-elements.

#### Tabs

<figure><img src="https://hyperswitch.io/img/site/rulesTabs.png" alt=""><figcaption></figcaption></figure>

| Class Name   | States     | Pseudo-Classes                     | Pseudo-Elements |
| ------------ | ---------- | ---------------------------------- | --------------- |
| .Tabs        | --selected | :hover, :focus, :active, :disabled |                 |
| fontSizeBase | --selected | :hover, :focus, :active, :disabled |                 |
| spacingUnit  | --selected | :hover, :focus, :active, :disabled |                 |

* .Tab, .Label, .Input
* .Tab:focus
* .Input--invalid, .Label--invalid
* .Input::placeholder

Each class name used in a selector supports an allowlist of CSS properties that you specify using camel case (for example, boxShadow for the box-shadow property). The following is the complete list of supported class names and corresponding states, pseudo-classes, and pseudo-elements.

```js
const appearance = {
  variables: {
    buttonBackgroundColor: "#FFFFFF",
    buttonTextColor: "#000000",
    // ... along with other variables
  },
  rules: {
    ".TabLabel": {
      overflowWrap: "break-word",
    },
    ".Tab--selected": {
      display: "flex",
      gap: "8px",
      flexDirection: "row",
      justifyContent: "center",
      alignItems: "center",
      padding: "15px 32px",
      background: "linear-gradient(109deg,#f48836,#f4364c)",
      color: "#ffffff",
      fontWeight: "700",
      borderRadius: "25px",
    },
    ".Tab--selected:hover": {
      display: "flex",
      gap: "8px",
      flexDirection: "row",
      justifyContent: "center",
      alignItems: "center",
      padding: "15px 32px",
      background: "linear-gradient(109deg,#f48836,#f4364c)",
      borderRadius: "25px",
      color: "#ffffff !important",
      fontWeight: "700",
    },
  },
};

const elements = hyper.elements({ clientSecret, appearance });
```

#### Form Inputs

<figure><img src="/files/mdReo7hUnvGKMFB7YBCq" alt=""><figcaption></figcaption></figure>

| Class Name | States             | Pseudo-Classes                       | Pseudo-Elements            |
| ---------- | ------------------ | ------------------------------------ | -------------------------- |
| .Label     | --empty, --invalid |                                      |                            |
| .Input     | --empty, --invalid | :hover, :focus, :disabled, :autofill | ::placeholder, ::selection |
| .Error     |                    |                                      |                            |

#### Checkbox

<figure><img src="/files/bf5FxqAsC7oUXLMe9FKW" alt=""><figcaption></figcaption></figure>

| Class Name     | States    | Pseudo-Classes | Pseudo-Elements |
| -------------- | --------- | -------------- | --------------- |
| .Checkbox      | --checked | :hover         |                 |
| .CheckboxLabel | --checked | :hover         |                 |
| .CheckboxInput | --checked | :hover         |                 |

#### InputLogo

| Class Name | States    | Pseudo-Classes | Pseudo-Elements |
| ---------- | --------- | -------------- | --------------- |
| .InputLogo |           | :hover         |                 |
| .InputLogo | --invalid | :hover,        |                 |
| .InputLogo | --empty   | :hover         |                 |

#### SaveWalletDetailsLabel

| Class Name              | States | Pseudo-Classes | Pseudo-Elements |
| ----------------------- | ------ | -------------- | --------------- |
| .SaveWalletDetailsLabel |        | :hover         |                 |

#### OrPayUsingLabel

| Class Name       | States | Pseudo-Classes | Pseudo-Elements |
| ---------------- | ------ | -------------- | --------------- |
| .OrPayUsingLabel |        | :hover         |                 |

#### OrPayUsingLine

| Class Name      | States | Pseudo-Classes | Pseudo-Elements |
| --------------- | ------ | -------------- | --------------- |
| .OrPayUsingLine |        | :hover         |                 |

#### TermsTextLabel

| Class Name      | States | Pseudo-Classes | Pseudo-Elements |
| --------------- | ------ | -------------- | --------------- |
| .TermsTextLabel |        | :hover         |                 |

#### InfoElement

| Class Name   | States | Pseudo-Classes | Pseudo-Elements |
| ------------ | ------ | -------------- | --------------- |
| .InfoElement |        | :hover         |                 |

### 5. Languages

Juspay Hyperswitch Unified Checkout supports localization in 6 languages. By default, the Unified Checkout SDK will detect the locale of the customer's browser and display the localized version of the payment sheet if that locale is supported. In case it is not supported, we default to English. To override, you can send locale in [hyper.elements (options)](/integration-guide/payment-suite/sdk-reference/node)

We support the following locales -

* Arabic (ar)
* Catalan (ca)
* Chinese (zh)
* Deutsch (de)
* Dutch (nl)
* English (en)
* EnglishGB (en-GB)
* FrenchBelgium (fr-BE)
* French (fr)
* Hebrew (he)
* Italian (it)
* Japanese (ja)
* Polish (pl)
* Portuguese (pt)
* Russian (ru)
* Spanish (es)
* Swedish (sv)

If you need support for locales other than the ones mentioned above, please contact the Hyperswitch team. Now you can test the payments on your app and go-live!

### 6. Confirm Button

The Styling APIs could be used to blend the Confirm Payment Button (handled by SDK) with your app.

| Variable              | Description                                                        |
| --------------------- | ------------------------------------------------------------------ |
| buttonBackgroundColor | Sets the background color of the payment button                    |
| buttonHeight          | Define the height of the payment button                            |
| buttonWidth           | Specify the width of the payment button                            |
| buttonBorderRadius    | Adjust the border radius of the payment button for rounded corners |
| buttonBorderColor     | Sets the color of the border surrounding the payment button        |
| buttonTextColor       | Define the color of the text displayed on the payment button       |
| buttonTextFontSize    | Customize the font size of the text on the payment button          |
| buttonTextFontWeight  | Specify the font weight of the text on the payment button          |
| buttonBorderWidth     | Specify the border width of the button                             |

### 7. More Configurations

#### Branding

You can decide whether to display the Hyperswitch branding using the `branding` prop

<pre class="language-javascript"><code class="lang-javascript"><strong>var paymentElementOptions = {
</strong> ...,
  branding: "never", // choose between "never" and "always"
}

&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</code></pre>

#### Payment Methods Header Text

Customize the header text for the section displaying available payment methods.

<pre class="language-javascript"><code class="lang-javascript"><strong>var paymentElementOptions = {
</strong> ...,
  paymentMethodsHeaderText: "Select Payment Method",
}

&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</code></pre>

#### Saved Payment Methods Header Text

Customize the header text for the section displaying saved payment methods.

<pre class="language-javascript"><code class="lang-javascript"><strong>var paymentElementOptions = {
</strong> ...,
  savedPaymentMethodsHeaderText: "Saved Payment Methods",
}

&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</code></pre>

#### Custom Message for Card Terms

{% hint style="warning" %}
This property will be deprecated, please use the newly added **Payment Methods Configuration (**&#x70;aymentMethodsConfi&#x67;**)** property to pass custom messages
{% endhint %}

We provide a default message for card terms i.e.

```rescript
`By providing your card information, you allow ${company_name} to charge your card for future payments in accordance with their terms.`
```

If you would like to customize this message, you can do so by using the `customMessageForCardTerms` property in the `paymentElementOptions` object.

<pre class="language-javascript"><code class="lang-javascript"><strong>var paymentElementOptions = {
</strong> ...,
  customMessageForCardTerms: "Custom message for Card terms",
}

&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</code></pre>

#### Hide Card Nickname Field

The `hideCardNicknameField` property allows you to hide the card nickname field when saving a card.

```javascript
var paymentElementOptions = {
  ...,
  hideCardNicknameField: true,  // default - false
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Hide Expired Saved Payment Methods

The `hideExpiredPaymentMethods` property allows you to control whether expired saved payment methods are hidden or not.

```javascript
var paymentElementOptions = {
  ...,
  hideExpiredPaymentMethods: false, // default - false
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Terms

The `terms` property allows you to configure the display of terms for various payment methods.

```javascript
var paymentElementOptions = {
  ...,
  terms: {
    auBecsDebit: "always",
    bancontact: "auto",
    card: "never",
    ideal: "auto",
    sepaDebit: "always",
    sofort: "never",
    usBankAccount: "auto",
  },
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Display Saved Payment Methods

The `displaySavedPaymentMethods` property determines whether saved payment methods are displayed.

```javascript
var paymentElementOptions = {
  ...,
  displaySavedPaymentMethods: false,
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Display Saved Payment Methods Checkbox

The `displaySavedPaymentMethodsCheckbox` property determines whether the "Save payment methods" checkbox is displayed.

```javascript
var paymentElementOptions = {
  ...,
  displaySavedPaymentMethodsCheckbox: false, 
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Saved Payment Methods Checkbox Checked By Default

The `savedPaymentMethodsCheckboxCheckedByDefault` property determines whether the "Save payment methods" checkbox is checked by default when displayed.

```javascript
var paymentElementOptions = {
  ...,
  savedPaymentMethodsCheckboxCheckedByDefault: false, // default - false
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Payment Method Order

The `paymentMethodOrder` property allows you to specify the order in which payment methods are displayed.

```javascript
var paymentElementOptions = {
  ...,
  paymentMethodOrder: ["card", "ideal", "sepaDebit", "sofort"],
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Business

The `business` property allows you to specify a business name to be attached to the terms. By default merchant name will be taken as business name.

```javascript
var paymentElementOptions = {
  ...,
  business: {
    name: "Example Business",
  },
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Read Only

The `readOnly` property puts the SDK into read-only mode, disabling all interactions.

```javascript
var paymentElementOptions = {
  ...,
  readOnly: true,
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Show Short Surcharge Message

The `showShortSurchargeMessage` property allows merchants to display a short message when a surcharge is applied, instead of the default message provided by the SDK.

{% hint style="success" %}
The short message format will be: **`Fee: {Currency} {Amount}`**
{% endhint %}

```javascript
var paymentElementOptions = {
  ...,
  showShortSurchargeMessage: true, // default - false
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### Payment Methods Configuration

The `paymentMethodsConfig` prop allows you to provide payment-method-specific configurations within the Hyperswitch SDK. Currently, it supports displaying custom messages (or hiding default messages) for individual payment method types.

{% hint style="success" %}
This configuration does **not** apply to one-click wallets. It applies to all other payment method types such as cards, bank debits, bank redirects, etc.
{% endhint %}

```javascript
var paymentElementOptions = {
  ...,
  paymentMethodsConfig: [{
    paymentMethod: string,              // e.g. "card", "bank_debit", "bank_redirect"
    paymentMethodTypes: [{
        paymentMethodType: string,      // e.g. "credit", "debit", "sepa", "ach"
        message: {
          value?: string,               // Custom message text
          displayMode: string           // "default_sdk_message" | "custom_message" | "hidden"
        }
      }]
  }]
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

#### `displayMode` values

| Value                   | Description                                                                    |
| ----------------------- | ------------------------------------------------------------------------------ |
| `"default_sdk_message"` | Show the SDK's default message for this payment method type (default behavior) |
| `"custom_message"`      | Show a custom message provided in `message.value`                              |
| `"hidden"`              | Hide the message entirely                                                      |

If `displayMode` is `"custom_message"` but `value` is empty or not provided, the message is hidden.

#### How it works

The `message` configuration controls the text displayed below each payment method type in the checkout. This is used in two places:

1. **Terms/disclaimer text** — The informational text shown below a payment method (e.g., "By providing your card details, you agree to our terms"). Setting `displayMode` to `"custom_message"` with a `value` replaces this text; setting it to `"hidden"` removes it entirely.
2. **Save card checkbox label** — For card payment methods, if a custom message is provided, it also replaces the default label on the "Save card details" checkbox when on the card form screen.

#### Default behavior

If a payment method type is **not** listed in `paymentMethodsConfig`, or if `displayMode` is set to `"default_sdk_message"`, the SDK shows its default terms message as usual.

### Next step:

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}


# Error Codes

Reference table of client error codes returned by the SDK for graceful error handling in your web application.

The following table lists client error codes that the Juspay Hyperswitch SDK returns to your website for graceful handling.

| Error Type               | Error Message                                   |
| ------------------------ | ----------------------------------------------- |
| invalid\_request\_error  | Invalid api key                                 |
| invalid\_request\_error  | Invalid value for < parameter\_name >           |
| invalid\_request\_error  | Missing required parameter: < parameter\_name > |
| invalid\_request\_error  | Invalid client secret                           |
| invalid\_request\_error  | Invalid promise                                 |
| processing\_error        | Payment failed with the payment processor       |
| internal\_server\_error  | Server is unavailable                           |
| object\_not\_found       | Payment does not exist                          |
| confirm\_payment\_failed | An unknown error occurred                       |


# Mobile

Integrate secure, customizable payments into iOS and Android apps with Juspay Hyperswitch mobile SDKs for native and cross-platform frameworks.

Juspay Hyperswitch SDK offers **powerful and flexible mobile SDKs** to integrate secure, customizable, and high-performance payments into your iOS and Android apps — whether you're building with native frameworks or cross-platform tools like React Native and Flutter.

### Key Features

* **Native & Cross-Platform Support** – iOS, Android, React Native, and Flutter.
* **Lite SDK Mode** – Minimal bundle size with full payment capabilities via web components.
* **Unified Configuration** – Same `PaymentSheet.Configuration` or `PaymentSession` options across platforms:
  * Appearance & branding
  * Billing & shipping details
  * Payment method preferences
* **Secure by Default** – PCI DSS compliant, tokenized transactions.
* **Customizable UI** – Match your app's look and feel.
* **Global Payment Methods** – Cards, wallets, and more.


# Android

Integrate unified checkout on your Android app

<figure><img src="/files/S6rf4U6uYFdWoKQnrHlc" alt="" width="375"><figcaption></figcaption></figure>

#### Checkout the working demo of unified checkout by clicking on the link below

{% embed url="<https://hyperswitch-demo.netlify.app/mobile>" fullWidth="false" %}

Revolutionize your app's payment capabilities with the Juspay Hyperswitch Android SDK, delivering a seamless and tailored Global Checkout Experience. The Hyperswitch Unified Checkout on Android is meticulously designed to provide an all-encompassing, unified, and optimized payment journey, ensuring exceptional conversion rates.

| <img src="/files/tyNieL72lTbK7pq3GeMp" alt="" data-size="original"> | <p><strong>Inclusive</strong></p><p>Global payments, diverse methods - cards, buy now pay later, and digital wallets. Unified Checkout adapts to local preferences, integrates languages for an inclusive solution.</p> |
| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <img src="/files/FHjGGWboL3hjbQ6FgBPM" alt="" data-size="original"> | <p><strong>Consistent</strong></p><p>Consistent payment experience on Web, Android, and iOS with smart forms, minimal redirects, and intelligent retries. Unified Checkout ensures reliability and uniformity.</p>      |
| <img src="/files/2xKa0mysQDpWF0ZexhbI" alt="" data-size="original"> | <p><strong>Blended</strong></p><p>Tailor payment seamlessly with 40+ styling APIs for a native, cohesive, branded checkout in your Android app or website.</p>                                                          |

**Modify and Experiment:** While the Unified Checkout is pre-optimized for maximum conversions, the Hyperswitch Android SDK empowers you to go beyond the standard. Take control with our SDK APIs, allowing you:

* **Include New Fields:** Adapt swiftly to various use cases by adding new fields to the payment form, such as collecting billing addresses or zip codes for additional information.
* **Prioritize Payment Methods:** Impact your payment mix and conversion rates by prioritizing or promoting specific payment methods based on your customer preferences.
* **Switch Themes and Layouts:** Choose from a wide range of pre-designed themes and layouts for the checkout page, aligning the Unified Checkout with your app's aesthetics.

Experience the flexibility to modify and experiment, ensuring your app's payment journey aligns precisely with your business requirements and user expectations. Elevate your Android app's payment experience with the Hyperswitch Android SDK.


# Kotlin with REST API Integration

Integrate hyper SDK to your Kotlin App using hyperswitch-node

<details>

<summary><a href="https://github.com/aashu331998/Hyperswitch-Android-Demo-App/archive/refs/heads/main.zip"><strong>Demo App</strong></a></summary>

You can use this demo app as a reference with your Juspay Hyperswitch credentials to test the setup.

</details>

### Requirements

* Android 7.0 (API level 24) and above
* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) 8.13+
* [Gradle](https://gradle.org/releases/) 8.13+
* [AndroidX](https://developer.android.com/jetpack/androidx/)

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on your app

#### 2.1 Add the Buildscript Classpath

To start integrating the Juspay Hyperswitch SDK, add the following classpath to the `buildscript` block of your project-level `build.gradle` file:

<pre class="language-gradle"><code class="lang-gradle">buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "io.hyperswitch:hyperswitch-gradle-plugin:<a data-footnote-ref href="#user-content-fn-1">$latest_version</a>"
    }
}
</code></pre>

#### 2.2 Add the Plugin

Add the following plugin to the `plugins` block of your app-level `build.gradle` file:

```gradle
plugins {
    // Apply Hyperswitch Plugin
    id 'io.hyperswitch.plugin'
}
```

#### 2.3 Configure the SDK

Configure the Hyperswitch SDK in your app-level `build.gradle` file. You can specify the main SDK version and enable optional features:

```gradle
hyperswitch {
    // Optional: Specify main SDK version (defaults to latest if not specified)
    sdkVersion = "1.1.5"
    
    // Optional features - only add what you need
    features = [HyperFeature.SCANCARD, HyperFeature.NETCETERA]
}
```

{% hint style="warning" %}
Note:

* If you don't specify `sdkVersion`, the plugin will automatically use the latest available version
* You only need to enable the features you plan to use
* Individual feature versions are optional - the plugin will use recommended compatible versions
  {% endhint %}

#### 2.4 Implement the HyperInterface

Next, implement the `HyperInterface` in your `CheckoutActivity`. This involves extending `FragmentActivity` and implementing the `HyperInterface`:

```kotlin
class CheckoutActivity : AppCompatActivity(), HyperInterface {
    // ...
}
```

{% hint style="warning" %}
**Note**:

`PaymentSession` is designed to work with AndroidX activities. Ensure that your `CheckoutActivity` extends `FragmentActivity` or its subclass from the AndroidX library
{% endhint %}

#### 2.5 Setup the SDK and fetch a Payment

Set up the SDK using your publishable key. This is essential for initializing a `PaymentSession`:

```java
val paymentSession = PaymentSession(applicationContext, "YOUR_PUBLISHABLE_KEY");
```

{% hint style="warning" %}
**Note**:

PaymentSession needs to be initialized in onCreate method of your `FragmentActivity`
{% endhint %}

{% hint style="warning" %}
**Note**:

For an open-source setup, use the following parameters:

```kotlin
val paymentSession = PaymentSession(applicationContext, "YOUR_PUBLISHABLE_KEY", "YOUR_CUSTOM_BACKEND_URL", "YOUR_CUSTOM_LOG_URL")
```

{% endhint %}

**Fetch a Payment**

Request your server to fetch a payment as soon as your view is loaded. Store the `client_secret` returned by your server. The `PaymentSession` will use this secret to complete the payment process.

### 3. Complete the payment on your app

**Initialize Payment Session**

Initialize the payment session with the `client_secret`:

```kotlin
paymentSession.initPaymentSession(paymentIntentClientSecret)
```

**Handle Payment Result**

Handle the payment result in the completion block. Display appropriate messages to your customer based on the outcome of the payment:

```kotlin
private fun onPaymentSheetResult(paymentResult: PaymentSheetResult) {
    when (paymentResult) {
        is PaymentSheetResult.Completed -> {
            showToast("Payment complete!")
        }
        is PaymentSheetResult.Canceled -> {
            Log.i(TAG, "Payment canceled!")
        }
        is PaymentSheetResult.Failed -> {
            showAlert("Payment failed", paymentResult.error.localizedMessage)
        }
    }
}
```

{% hint style="danger" %}
Please retrieve the payment status from the Hyperswitch backend to get the terminal status of the payment. Do not rely solely on the status returned by the SDK, as it may not always reflect the final state of the transaction.
{% endhint %}

**Present the Payment Page**

Create a configuration object to customize the payment sheet and present the payment page:

```kotlin
val configuration = PaymentSheet.Configuration("Your_app, Inc.")

// Present Payment Page
paymentSession.presentPaymentSheet(configuration, ::onPaymentSheetResult)
```

#### Final Step

Congratulations! You have successfully integrated the Hyperswitch Android SDK into your app. You can now customize the payment sheet to match the look and feel of your app.

### Next Step:

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}

[^1]: [Get Latest Version](https://central.sonatype.com/artifact/io.hyperswitch/hyperswitch-gradle-plugin/versions)


# Lite SDK

Integrate Hyperswitch Lite SDK to your Kotlin App

### Key Features of Lite SDK

#### Lightweight Integration

* **Smaller artifact size**: <300 KB
* **Faster initialization**: Streamlined setup process
* **Web-based UI**: Uses web components for payment forms
* **Reduced dependencies**: Minimal impact on app size
* **Shared Configuration**: The Lite SDK uses the same `PaymentSheet.Configuration` options as the main SDK, including:
  * Appearance customization
  * Billing details
  * Shipping information
  * Payment method preferences
  * Branding options

### Requirements

* Android 6.0 (API level 23) and above
* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) 8.5+
* [Gradle](https://gradle.org/releases/) 8.8+
* [AndroidX](https://developer.android.com/jetpack/androidx/)

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on your app

#### 2.1 Add the Dependency

Add the Juspay Hyperswitch Lite SDK dependency to your app-level `build.gradle` file:

```gradle
dependencies {
    implementation 'io.hyperswitch:hyperswitch-sdk-android-lite:+'
}
```

#### 2.2 Setup the Lite SDK and fetch a Payment

Set up the Lite SDK using your publishable key. This is essential for initializing a `PaymentSession`:

```kotlin
import io.hyperswitch.lite.PaymentSession

val paymentSession = PaymentSession(applicationContext, "YOUR_PUBLISHABLE_KEY")
```

{% hint style="warning" %}
**Note**:

PaymentSession needs to be initialized in onCreate method of your `FragmentActivity`
{% endhint %}

{% hint style="warning" %}
**Note**:

For an open-source setup, use the following parameters:

```kotlin
val paymentSession = PaymentSession(applicationContext, "YOUR_PUBLISHABLE_KEY", "YOUR_CUSTOM_BACKEND_URL", "YOUR_CUSTOM_LOG_URL")
```

{% endhint %}

**Fetch a Payment**

Request your server to fetch a payment as soon as your view is loaded. Store the `client_secret` returned by your server. The `PaymentSession` (Lite) will use this secret to complete the payment process.

### 3. Complete the payment on your app

**Initialize Payment Session**

Initialize the payment session with the `client_secret`:

```kotlin
paymentSession.initPaymentSession(paymentIntentClientSecret)
```

**Handle Payment Result**

Handle the payment result in the completion block. Display appropriate messages to your customer based on the outcome of the payment:

```kotlin
private fun onPaymentSheetResult(paymentResult: PaymentSheetResult) {
    when (paymentResult) {
        is PaymentSheetResult.Completed -> {
            showToast("Payment complete!")
        }
        is PaymentSheetResult.Canceled -> {
            Log.i(TAG, "Payment canceled!")
        }
        is PaymentSheetResult.Failed -> {
            showAlert("Payment failed", paymentResult.error.localizedMessage)
        }
    }
}
```

{% hint style="danger" %}
Please retrieve the payment status from the Hyperswitch backend to get the terminal status of the payment. Do not rely solely on the status returned by the SDK, as it may not always reflect the final state of the transaction.
{% endhint %}

**Present the Payment Page**

Create a configuration object to customize the payment sheet and present the payment page:

```kotlin
val configuration = PaymentSheet.Configuration("Your_app, Inc.")

// Present Payment Page (Lite SDK)
paymentSession.presentPaymentSheet(configuration, ::onPaymentSheetResult)
```

#### Final Step

Congratulations! You have successfully integrated the Hyperswitch Lite SDK into your app. The Lite SDK provides the same powerful payment processing capabilities with a smaller footprint, making it ideal for apps where bundle size is a concern.

### Next Step:

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}


# Widgets

Integrate Juspay Hyperswitch SDK using individual payment widgets for granular control over your payment flow.

<div align="center"><figure><img src="/files/kUk45xKpWPO7iozMFQp6" alt="" width="375"><figcaption></figcaption></figure></div>

### Requirements

* Android 6.0 (API level 23) and above
* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) 8.5+
* [Gradle](https://gradle.org/releases/) 8.8+
* [AndroidX](https://developer.android.com/jetpack/androidx/)

### 1. Setup the server

```js
$ npm install @juspay-tech/hyperswitch-node
```

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on your app

#### 2.1 Add the Buildscript Classpath

To start integrating the Juspay Hyperswitch SDK, add the following classpath to the `buildscript` block of your project-level `build.gradle` file:

<pre class="language-gradle"><code class="lang-gradle">buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "io.hyperswitch:hyperswitch-gradle-plugin:<a data-footnote-ref href="#user-content-fn-1">$latest_version</a>"
    }
}
</code></pre>

#### 2.2 Apply the Plugin

Add the following plugin to the `plugins` block of your app-level `build.gradle` file:

```gradle
plugins {
    // Apply Hyperswitch Plugin
    id 'io.hyperswitch.plugin'
}
```

#### 2.3 Implement the HyperInterface

Next, implement the `HyperInterface` in your Activity. This involves extending `FragmentActivity` and implementing the `HyperInterface`:

```kotlin
class WidgetActivity : AppCompatActivity(), HyperInterface {
    // ...
}
```

#### 2.4 Initialize Payment Configuration

Set up the SDK using your publishable key:

```kotlin
private fun initialiseSDK() {
    // Initialize Payment Configuration
    PaymentConfiguration.init(applicationContext, publishKey)
}
```

### 3. Implementation

Choose from list of available widgets to integrate:

1. [Card Element](/integration-guide/payment-suite/payment-method-card/mobile/android/widgets/card-element)
2. [Google Pay](/integration-guide/payment-suite/payment-method-card/mobile/android/widgets/google-pay)
3. [PayPal](/integration-guide/payment-suite/payment-method-card/mobile/android/widgets/paypal)
4. [Express Checkout](/integration-guide/payment-suite/payment-method-card/mobile/android/widgets/express-checkout)

#### Final Step

Congratulations! You have successfully integrated Juspay Hyperswitch widgets into your app. This approach gives you granular control over each payment method and allows for custom UI/UX design while leveraging Juspay Hyperswitch's payment processing capabilities.

### Next step:

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}

[^1]: [Get Latest Version](https://central.sonatype.com/artifact/io.hyperswitch/hyperswitch-gradle-plugin/versions)


# Card Element

Learn how to integrate the Card Element widget for accepting card payments in your Android app using Juspay Hyperswitch SDK.

**Purpose:** Card payments with Juspay Hyperswitch

**Add Card Widget to Layout**

```xml
<io.hyperswitch.view.BasePaymentWidget
    android:id="@+id/cardElement"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:paymentMethod="card" />

<Button
    android:id="@+id/confirmButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Pay with Card" />
```

**Initialize Card Launcher**

```kotlin
private lateinit var cardPaymentLauncher: UnifiedPaymentLauncher

private fun setupCardPayment() {
    cardPaymentLauncher = UnifiedPaymentLauncher.createCardLauncher(
        activity = this,
        resultCallback = ::onPaymentResult
    )
}
```

**Handle Card Payment**

```kotlin
private fun processCardPayment() {
    val cardInputWidget: BasePaymentWidget = findViewById(R.id.cardElement)
    val params: PaymentMethodCreateParams = cardInputWidget.paymentMethodCreateParams
    val confirmParams = ConfirmPaymentIntentParams.createWithPaymentMethodCreateParams(
        params,
        paymentIntentClientSecret
    )

    if (::cardPaymentLauncher.isInitialized) {
        cardPaymentLauncher.confirmCardPayment(confirmParams)
    } else {
        Toast.makeText(this, "SDK is not initialized", Toast.LENGTH_SHORT).show()
    }
}

// Handle card payment results
private fun onPaymentResult(paymentResult: PaymentResult) {
    when (paymentResult) {
        is PaymentResult.Completed -> {
            Toast.makeText(this, "Payment completed: ${paymentResult.data}", Toast.LENGTH_SHORT).show()
        }
        is PaymentResult.Canceled -> {
            Toast.makeText(this, "Payment canceled: ${paymentResult.data}", Toast.LENGTH_SHORT).show()
        }
        is PaymentResult.Failed -> {
            Toast.makeText(this, "Payment failed: ${paymentResult.throwable.message}", Toast.LENGTH_SHORT).show()
        }
    }
}
```

### Best Practices

#### Error Handling

Always check if launchers are initialized before using them:

```kotlin
if (::cardPaymentLauncher.isInitialized) {
    cardPaymentLauncher.confirmCardPayment(confirmParams)
} else {
    Toast.makeText(this, "SDK is not initialized", Toast.LENGTH_SHORT).show()
}
```


# Google Pay

Learn how to integrate the Google Pay widget for accepting Google Pay payments in your Android app using Juspay Hyperswitch SDK.

**Purpose:** Google Pay payments with Juspay Hyperswitch

**Add Google Pay Widget to Layout**

```xml
<io.hyperswitch.view.BasePaymentWidget
    android:id="@+id/googlePayButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:paymentMethod="google_pay" />
```

**Initialize Google Pay Launcher**

```kotlin
private lateinit var googlePayButton: BasePaymentWidget
private lateinit var googlePayLauncherInstance: UnifiedPaymentLauncher

private fun setupGooglePayLauncher() {
    googlePayButton = findViewById(R.id.googlePayButton)
    googlePayButton.isEnabled = false
    
    googlePayLauncherInstance = UnifiedPaymentLauncher.createGooglePayLauncher(
        activity = this,
        clientSecret = paymentIntentClientSecret,
        config = GooglePayConfig(
            environment = GooglePayEnvironment.Test, // Use GooglePayEnvironment.Production for live
            merchantCountryCode = "US",
            merchantName = "Your Store Name"
        ),
        readyCallback = ::onGooglePayReady,
        resultCallback = ::onGooglePayResult
    )

    googlePayButton.setOnClickListener {
        if (::googlePayLauncherInstance.isInitialized) {
            googlePayLauncherInstance.presentForPayment(paymentIntentClientSecret)
        } else {
            Toast.makeText(this, "Google Pay Launcher not initialized", Toast.LENGTH_SHORT).show()
        }
    }
}
```

**Handle Google Pay Callbacks**

```kotlin
private fun onGooglePayReady(isReady: Boolean) {
    googlePayButton.isEnabled = isReady
}

private fun onGooglePayResult(result: GooglePayPaymentMethodLauncher.Result) {
    when (result) {
        is GooglePayPaymentMethodLauncher.Result.Completed -> {
            val paymentMethodId = result.paymentMethod.id
            Toast.makeText(this, "Payment successful: $paymentMethodId", Toast.LENGTH_LONG).show()
        }
        is GooglePayPaymentMethodLauncher.Result.Canceled -> {
            Toast.makeText(this, "Payment canceled: ${result.data}", Toast.LENGTH_LONG).show()
        }
        is GooglePayPaymentMethodLauncher.Result.Failed -> {
            Toast.makeText(this, "Payment failed: ${result.error.message}", Toast.LENGTH_LONG).show()
        }
    }
}
```

### Best Practices

#### UI State Management

Disable payment buttons until launchers are ready:

```kotlin
private fun onGooglePayReady(isReady: Boolean) {
    googlePayButton.isEnabled = isReady
}
```


# PayPal

Learn how to integrate the PayPal widget for accepting PayPal payments in your Android app using Juspay Hyperswitch SDK.

PayPal payments with Juspay Hyperswitch.

### Add PayPal Widget to Layout

```xml
<io.hyperswitch.view.BasePaymentWidget
    android:id="@+id/payPalButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:paymentMethod="paypal" />
```

### Initialize PayPal Launcher

```kotlin
private lateinit var payPalButton: BasePaymentWidget
private lateinit var payPalLauncherInstance: UnifiedPaymentLauncher

private fun setupPayPalLauncher() {
    payPalButton = findViewById(R.id.payPalButton)
    payPalButton.isEnabled = false
    
    payPalLauncherInstance = UnifiedPaymentLauncher.createPayPalLauncher(
        activity = this,
        clientSecret = paymentIntentClientSecret,
        readyCallback = ::onPayPalReady,
        resultCallback = ::onPayPalResult
    )

    payPalButton.setOnClickListener {
        if (::payPalLauncherInstance.isInitialized) {
            payPalLauncherInstance.presentForPayment(paymentIntentClientSecret)
        } else {
            Toast.makeText(this, "PayPal Launcher not initialized", Toast.LENGTH_SHORT).show()
        }
    }
}
```

### Handle PayPal Callbacks

```kotlin
private fun onPayPalReady(isReady: Boolean) {
    payPalButton.isEnabled = isReady
}

private fun onPayPalResult(result: PayPalPaymentMethodLauncher.Result) {
    when (result) {
        is PayPalPaymentMethodLauncher.Result.Completed -> {
            val paymentMethodId = result.paymentMethod.id
            Toast.makeText(this, "PayPal payment successful: $paymentMethodId", Toast.LENGTH_LONG).show()
        }
        is PayPalPaymentMethodLauncher.Result.Canceled -> {
            Toast.makeText(this, "PayPal payment canceled: ${result.data}", Toast.LENGTH_LONG).show()
        }
        is PayPalPaymentMethodLauncher.Result.Failed -> {
            Toast.makeText(this, "PayPal payment failed: ${result.error.message}", Toast.LENGTH_LONG).show()
        }
    }
}
```


# Express Checkout

Learn how to integrate the Express Checkout widget for one-click payments using saved payment methods with Juspay Hyperswitch SDK.

One-click solution for last used saved payment method with Juspay Hyperswitch.

### Add Express Checkout Widget to Layout

```xml
<io.hyperswitch.view.BasePaymentWidget
    android:id="@+id/expressCheckoutWidget"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:paymentMethod="expressCheckout" />

<Button
    android:id="@+id/confirmEC"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Confirm EC" />
```

### Initialize Express Checkout Launcher

```kotlin
private lateinit var ecLauncherInstance: UnifiedPaymentLauncher

private fun setupECLauncher() {
    ecLauncherInstance = UnifiedPaymentLauncher.createExpressCheckoutLauncher(
        activity = this,
        clientSecret = paymentIntentClientSecret,
        readyCallback = ::onExpressCheckoutReady,
        resultCallback = ::onExpressCheckoutResult
    )

    findViewById<View>(R.id.confirmEC).setOnClickListener {
        if (::ecLauncherInstance.isInitialized) {
            ecLauncherInstance.presentForPayment(paymentIntentClientSecret)
        } else {
            Toast.makeText(this, "Express Checkout Launcher not initialized", Toast.LENGTH_SHORT).show()
        }
    }
}
```

### Handle Express Checkout Callbacks

```kotlin
private fun onExpressCheckoutReady(isReady: Boolean) {
    findViewById<View>(R.id.confirmEC).isEnabled = isReady
}

private fun onExpressCheckoutResult(result: ExpressCheckoutPaymentMethodLauncher.Result) {
    when (result) {
        is ExpressCheckoutPaymentMethodLauncher.Result.Completed -> {
            Toast.makeText(this, "Express checkout successful: ${result.paymentMethod}", Toast.LENGTH_LONG).show()
        }
        is ExpressCheckoutPaymentMethodLauncher.Result.Canceled -> {
            Toast.makeText(this, "Express checkout canceled: ${result.data}", Toast.LENGTH_LONG).show()
        }
        is ExpressCheckoutPaymentMethodLauncher.Result.Failed -> {
            Toast.makeText(this, "Express checkout failed: ${result.error.message}", Toast.LENGTH_LONG).show()
        }
    }
}
```


# Headless SDK

Hyperswitch is designed to facilitate the integration and management of payment-related functionalities in a decoupled or headless architecture with flexibility to customize your checkout UI.

### Customize the payment experience using Headless functions

#### 1. Initialize the Juspay Hyperswitch SDK

Initialize Juspay Hyperswitch Headless SDK onto your app with your publishable key. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

```kotlin
// dependencies: implementation 'io.hyperswitch:hyperswitch-sdk-android:+' val 
paymentSession = PaymentSession(applicationContext, "YOUR_PUBLISHABLE_KEY")
```

#### 2. Create a Payment Intent

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to initialize the payment session.

{% hint style="danger" %}
**Important**: Make sure to never share your API key with your client application as this could potentially compromise your security
{% endhint %}

#### 3. Initialize your Payment Session

Initialize a Payment Session by passing the clientSecret to the `initPaymentSession`

```kotlin
paymentSession.initPaymentSession(paymentIntentClientSecret)
```

| options (Required)                   | Description                                                     |
| ------------------------------------ | --------------------------------------------------------------- |
| `paymentIntentClientSecret (string)` | **Required.** Required to use as the identifier of the payment. |

#### 4. Craft a customized payments experience

Using the `paymentSession` object, the default customer payment method data can be fetched, using which you can craft your own payments experience. The `paymentSession` object also exposes a `confirmWithCustomerDefaultPaymentMethod` function, using which you can confirm and handle the payment session.

<pre class="language-kotlin"><code class="lang-kotlin"><strong>var handler: PaymentSessionHandler? = null
</strong>
paymentSession.getCustomerSavedPaymentMethods { paymentSessionHandler ->
    handler = paymentSessionHandler
}

val savedPaymentMethod = handler!!.getCustomerLastUsedSavedPaymentMethodData()

button.setOnClickListener { 
    handler!!.confirmWithCustomerLastUsedPaymentMethod { paymentResult -> 
        println(paymentResult)
    }
}
</code></pre>

**Payload for** `confirmWithCustomerLastUsedPaymentMethod(callback)`

<table><thead><tr><th width="296">options (Required)</th><th>Description</th></tr></thead><tbody><tr><td><code>callback (method)</code></td><td>Callback to get confirm response.</td></tr></tbody></table>


# Customization

Customize your Android Unified checkout with fonts, colors, shapes and layouts to match your brand guidelines.

{% hint style="info" %}
You can customize the Android Unified Checkout to support your checkout context and brand guidelines by changing fonts, colors, shapes and layouts.
{% endhint %}

Juspay Hyperswitch allows you to create a `PaymentSheet.Configuration` object with an `appearance` object to match the design of your app.

### Fonts

Set `typography.fontResId` to your custom font's resource ID to customize your font. Set a `typography.sizeScaleFactor` multiplier to increase or decrease the font size.

```kotlin
val appearance = PaymentSheet.Appearance(
  typography = PaymentSheet.Typography(10.0f, R.font.MY_FONT)
)
```

### Colors

Modify the color categories in `PaymentSheet.Colors` to customize the colors on the mobile payment sheet as follows:

| Color Category   | Usage                                                                          |
| ---------------- | ------------------------------------------------------------------------------ |
| appBarIcon       | Color used for icons in the payment page ex: close (x) button                  |
| component        | Background color of inputs, tabs and other components                          |
| componentBorder  | Border color for inputs, tabs and other components                             |
| componentDivider | Color for divider lines used inside inputs, tabs and other components          |
| error            | Color for error messages to the user on the payment page                       |
| onComponent      | Color of text and other elements inside components                             |
| onSurface        | Color for items appearing on the surface of the payment page, Ex: text prompts |
| placeholderText  | Color for input fields placeholder text                                        |
| primary          | The primary color to be used across the payment page                           |
| subtitle         | Color of secondary text like prompts for input fields                          |
| surface          | Color of the payment page                                                      |

### Shapes

Modify the corner radius and border width used across the payment page using `appearance.shapes`.

| Shape Category      | Usage                                                                                          |
| ------------------- | ---------------------------------------------------------------------------------------------- |
| borderStrokeWidthDp | Width of the border used to across input fields, tabs and other components of the payment page |
| cornerRadiusDp      | Corner radius of the input fields, tabs and other components                                   |

Now you can test the payments on your app and go-live!

### Next Steps

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}


# iOS

Integrate unified checkout with your iOS app

<figure><img src="/files/7GQS5DlJnm9nmoT3JoYx" alt="" width="563"><figcaption></figcaption></figure>

#### Checkout the working demo of unified checkout by clicking on the link below

{% embed url="<https://hyperswitch-demo.netlify.app/mobile>" %}

Revolutionize your app's payment capabilities with the Juspay Hyperswitch iOS SDK, delivering a seamless and tailored Global Checkout Experience. The Hyperswitch Unified Checkout on iOS is meticulously designed to provide an all-encompassing, unified, and optimized payment journey, ensuring exceptional conversion rates.

| <img src="/files/tyNieL72lTbK7pq3GeMp" alt="" data-size="original"> | **Inclusive:** Supporting a diverse array of global payment methods, including cards, buy now pay later, and digital wallets, the Unified Checkout adapts to local preferences. Customize the experience further with the ability to integrate local languages, creating a truly inclusive payment solution. |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <img src="/files/FHjGGWboL3hjbQ6FgBPM" alt="" data-size="original"> | **Consistent:** Enjoy a singular and consistent payment experience across platforms, whether on the web, Android, or iOS. Driven by smart payment forms, minimal redirections, and intelligent retries, the Unified Checkout ensures a reliable and uniform payment process.                                 |
| <img src="/files/2xKa0mysQDpWF0ZexhbI" alt="" data-size="original"> | **Blended:** Tailor the payment experience to seamlessly integrate with your product using 40+ styling APIs. Achieve a fully native and embedded payment experience within your iOS app or website, creating a cohesive and branded checkout environment.                                                    |

**Modify and Experiment:** While the Unified Checkout is pre-optimized for maximum conversions, the Hyperswitch iOS SDK empowers you to go beyond the standard. Take control with our SDK APIs, allowing you to:

* **Include New Fields:** Adapt swiftly to various use cases by adding new fields to the payment form, such as collecting billing addresses or zip codes for additional information.
* **Prioritize Payment Methods:** Impact your payment mix and conversion rates by prioritizing or promoting specific payment methods based on your customer preferences.
* **Switch Themes and Layouts:** Choose from a wide range of pre-designed themes and layouts for the checkout page, aligning the Unified Checkout with your app's aesthetics.

Experience the flexibility to modify and experiment, ensuring your app's payment journey aligns precisely with your business requirements and user expectations. Elevate your iOS app's payment experience with the Hyperswitch iOS SDK.


# Swift with REST API Integration

Integrate hyper SDK to your Swift App using hyperswitch-node

{% hint style="info" %}
Use this guide to integrate Juspay Hyperswitch SDK to your iOS app. You can use the following [app](https://github.com/aashu331998/Hyperswitch-iOS-Demo-App/archive/refs/heads/main.zip) as a reference with your Hyperswitch credentials to test the setup. You can also checkout the [app on Apple Testflight](https://testflight.apple.com/join/WhPLmrT6) to test the payment flow.
{% endhint %}

### Requirements

* iOS 15.1 and above
* CocoaPods
* npm

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on your app

#### 2.1 Configure your repository with Hyperswitch dependency

CocoaPods Setup (only required if not already done)

1. Install the latest version of CocoaPods
2. To create a Podfile run the following command

```
pod init
```

SDK Setup

Add these lines to your Podfile:

```ruby
#use_frameworks!
#target 'YourAPP' do
  pod 'hyperswitch-sdk-ios'
#end

```

Run the following command:

```
pod install
```

**Remember that moving forward, you should open your project in Xcode using the .xcworkspace file rather than the .xcodeproj file.**

To update to the latest version of the SDK, run:

```
pod install --repo-update
```

#### 2.2 Setup the SDK and fetch a Payment

Set up the SDK using your publishable key. This is essential for initializing a `PaymentSession`.

<pre class="language-swift"><code class="lang-swift"><strong>import Hyperswitch
</strong><strong>paymentSession = PaymentSession(publishableKey: &#x3C;YOUR_PUBLISHABLE_KEY>)
</strong></code></pre>

{% hint style="warning" %}
Note: For Open Source Setup, initialise your custom Backend app & log URL as:

```swift
paymentSession = PaymentSession(publishableKey: <YOUR_PUBLISHABLE_KEY>, 
                                customBackendUrl: <YOUR_SERVER_URL>,
                                customLogUrl: <YOUR_LOG_URL>)
```

{% endhint %}

#### 2.3 Complete the payment on your app

**Fetch a Payment**

Request your server to fetch a payment as soon as your view is loaded. Store the client\_secret returned by your server. The `PaymentSession` will use this secret to complete the payment process.

{% tabs %}
{% tab title="Swift" %}

```swift
var paymentSession: PaymentSession?

paymentSession?.initPaymentSession(paymentIntentClientSecret: paymentIntentClientSecret)
```

{% endtab %}

{% tab title="SwiftUI" %}

```swift
@ObservedObject var model = BackendModel()
@Published var paymentSheet: PaymentSession?
@Published var paymentResult: PaymentSheetResult?

// handle result
func onPaymentCompletion(result: PaymentSheetResult) {
        DispatchQueue.main.async {
            self.paymentResult = result
        }
}
paymentSession?.initPaymentSession(paymentIntentClientSecret: paymentIntentClientSecret)
```

{% endtab %}
{% endtabs %}

**Handle Payment Result**

Handle the payment result in the completion block and display appropriate messages to your customer based on whether the payment fails with an error or succeeds.

{% tabs %}
{% tab title="Swift" %}

```swift
@objc
func openPaymentSheet(_ sender: Any) { //present payment sheet

var configuration = PaymentSheet.Configuration()
configuration.merchantDisplayName = "Example, Inc."

    paymentSession?.presentPaymentSheet(viewController: self, 
                                        configuration: configuration, 
                                        completion: { result in
        switch result {
        case .completed:
            print("Payment complete")
        case .failed(let error):
            print("Payment failed: \(error.localizedDescription)")
        case .canceled:
            print("Payment canceled.")
        }
    })
}
```

{% hint style="danger" %}
Please retrieve the payment status from the Hyperswitch backend to get the terminal status of the payment. Do not rely solely on the status returned by the SDK, as it may not always reflect the final state of the transaction.
{% endhint %}
{% endtab %}

{% tab title="SwiftUI" %}

```swift
VStack {
  if let paymentSession = model.paymentSession {
    PaymentSheet.PaymentButton(paymentSession: paymentSession, 
                                               configuration: configuration(),
                                               onCompletion: model.onPaymentCompletion)
    {
     Text("Hyper Payment Sheet")
        .padding()
        .background(.blue)
        .foregroundColor(.white)
        .cornerRadius(10.0)
    }

    if let result = model.paymentResult {
        switch result {
          case .completed:
            Text("Payment complete")
          case .failed(let error):
            Text("Payment failed: \(error.domain)")
          case .canceled:
            Text("Payment canceled.")
          }
      }
  }
}.onAppear { model.preparePaymentSheet() }

// setup configuration for payment sheet
func configuration() -> PaymentSheet.Configuration {
        var configuration = PaymentSheet.Configuration()
        configuration.merchantDisplayName = "Example, Inc."
        return configuration
}
```

{% endtab %}
{% endtabs %}

### 3. Card Element (Beta)

Create a card element view and pay button and handle the payment result in the completion block and display appropriate messages to your customer based on whether the payment fails with an error or succeeds.

{% tabs %}
{% tab title="Swift" %}

<pre class="language-swift"><code class="lang-swift"><strong>//Create a card element view and pay button.
</strong><strong>lazy var hyperCardTextField: PaymentCardTextField = {
</strong>    let cardTextField = PaymentCardTextField()
    return cardTextField
}()

lazy var payButton: UIButton = {
    let button = UIButton(type: .custom)
    button.layer.cornerRadius = 5
    button.backgroundColor = .systemBlue
    button.setTitle("Pay", for: .normal)
    button.addTarget(self, action: #selector(pay), for: .touchUpInside)
    return button
}()


@objc
func pay() {
    guard let paymentIntentClientSecret = model.paymentIntentClientSecret else {
        return
    }
    let paymentIntentParams = PaymentIntentParams(clientSecret: paymentIntentClientSecret)
let paymentHandler = PaymentHandler.shared()

    paymentHandler.confirmPayment(paymentIntentParams, with: self) { 
        (status, paymentIntent, error) in
            switch (status) {
                case .failed:
                    break
                case .canceled:
                    break
                case .succeeded:
                    break
                @unknown default:
                    fatalError()
                    break
            }
    }
}
</code></pre>

{% endtab %}

{% tab title="SwiftUI" %}

```swift
@ObservedObject var model = BackendModel()
@State var paymentMethodParams: PaymentMethodParams?

VStack {
  PaymentCardTextField.Representable(paymentMethodParams: $paymentMethodParams)
    .padding()
  //Create a card element view and pay button.
  if let paymentIntent = model.paymentIntentParams {
    Button("Buy")
    {
      paymentIntent.paymentMethodParams = paymentMethodParams
      isConfirmingPayment = true
    }
    .disabled(isConfirmingPayment || paymentMethodParams == nil)
    .paymentConfirmationSheet(
        isConfirmingPayment: $isConfirmingPayment,
        paymentIntentParams: paymentIntent,
        onCompletion: model.onCompletion
        )
  }
  else {
    ProgressView()
  }
  if let paymentStatus = model.paymentStatus {
    PaymentHandlerStatusView(actionStatus: paymentStatus,
                             lastPaymentError: model.lastPaymentError)
  }
}.onAppear { model.preparePaymentIntent() }
```

{% endtab %}
{% endtabs %}

Congratulations! Now that you have integrated the iOS SDK, you can customize the payment sheet to blend with the rest of your app.

### Next Step:

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}


# Lite SDK

Integrate Hyperswitch Lite SDK to your iOS app

### Key Features of Lite SDK

#### Lightweight Integration

* **Smaller artifact size**: <300 KB
* **Faster initialization**: Streamlined setup process
* **Web-based UI**: Uses web components for payment forms
* **Reduced dependencies**: Minimal impact on app size
* **Shared Configuration**: The Lite SDK uses the same `PaymentSession` options as the main SDK, including:
  * Appearance customization
  * Billing details
  * Shipping information
  * Payment method preferences
  * Branding options

### Requirements

* iOS 15.1+
* CocoaPods

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build Checkout in Your App

#### 2.1 Add the Dependency

In your **`Podfile`**:

**Lite SDK only**

```ruby
pod 'hyperswitch-sdk-ios-lite'
```

**Lite SDK with Scan Card functionality**

```ruby
pod 'hyperswitch-sdk-ios-lite/scancard'
```

> **Note:** The Lite SDK and the regular SDK share a codebase. Their versions **must** match at all times. Replace `Latest_version` with the actual version number.

#### 2.2 Setup the Lite SDK and Fetch a Payment

**Initialize PaymentSession:**

```swift
import HyperswitchLite
paymentSession = PaymentSession(publishableKey: <YOUR_PUBLISHABLE_KEY>)

// Initialize with client secret
paymentSession.initPaymentSession(paymentIntentClientSecret: paymentIntentClientSecret)
```

**Complete Payment**

```swift
// Present the PaymentSheet Lite
paymentSession.presentPaymentSheetLite(
    viewController: self, 
    configuration: configuration, 
    completion: { 
        result in
            DispatchQueue.main.async {
                switch result {
                case .completed:
                    self.statusLabel.text = "Payment complete"
                case .failed(let error):
                    self.statusLabel.text =  "Payment failed: \(error)"
                case .canceled:
                    self.statusLabel.text = "Payment canceled."
            }
    }
})
```

#### Final Step

You have successfully integrated the **Juspay Hyperswitch Lite SDK** into your iOS app. The Lite SDK delivers **full payment processing** capabilities with a **smaller footprint**, perfect for apps where bundle size matters.


# Headless SDK

Hyperswitch is designed to facilitate the integration and management of payment-related functionalities in a decoupled or headless architecture with flexibility to customize your checkout UI.

### Customize the payment experience using Headless functions

#### 1. Initialize the Juspay Hyperswitch SDK

Initialize Hyperswitch Headless SDK onto your app with your publishable key. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

```swift
// pod 'hyperswitch-sdk-ios'
paymentSession = PaymentSession(publishableKey: publishableKey)
```

#### 2. Create a Payment Intent

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to initialize the payment session.

{% hint style="danger" %}
**Important**: Make sure to never share your API key with your client application as this could potentially compromise your security
{% endhint %}

#### 3. Initialize your Payment Session

Initialize a Payment Session by passing the clientSecret to the `initPaymentSession`

```swift
paymentSession?.initPaymentSession(paymentIntentClientSecret: paymentIntentClientSecret)
```

| options (Required)      | Description                                                     |
| ----------------------- | --------------------------------------------------------------- |
| `clientSecret (string)` | **Required.** Required to use as the identifier of the payment. |

#### 4. Craft a customized payments experience

Using the `paymentSession` object, the default customer payment method data can be fetched, using which you can craft your own payments experience. The `paymentSession` object also exposes a `confirmWithCustomerDefaultPaymentMethod` function, using which you can confirm and handle the payment session.

<pre class="language-swift"><code class="lang-swift">private var handler: PaymentSessionHandler?
 
func initSavedPaymentMethodSessionCallback(handler: PaymentSessionHandler)-> Void {
    self.handler = handler
}
    
@objc func launchHeadless(_ sender: Any) {
    paymentSession!.getCustomerSavedPaymentMethods(initSavedPaymentMethodSessionCallback)
<strong>}
</strong>
@objc func confirmPayment(_ sender: Any) {
    let paymentMethod = self.handler!.getCustomerLastUsedSavedPaymentMethodData(callback)
}
    
@objc func confirmPayment(_ sender: Any) {
    self.handler!.confirmWithLastUsedSavedPaymentMethodData(callback)
}
</code></pre>

**Payload for** `confirmWithCustomerLastUsedPaymentMethod(callback)`

| options (Required)    | Description                       |
| --------------------- | --------------------------------- |
| `callback (function)` | Callback to get confirm response. |


# Customization

Customize your iOS Unified Checkout with fonts, colors, shapes and layouts to match your brand guidelines.

{% hint style="info" %}
You can customize the iOS Unified Checkout to support your checkout context and brand guidelines by changing fonts, colours, shapes and layouts.
{% endhint %}

Juspay Hyperswitch allows you to create a `PaymentSheet.Configuration` object with an `appearance` object to match the design of your app.

### Fonts

Set `typography.fontResId` to your custom font's resource ID to customize your font. Set a `typography.sizeScaleFactor` multiplier to increase or decrease the font size.

```swift
var configuration = PaymentSheet.Configuration()
configuration.appearance?.font?.base? = UIFont(name: "Helvetica", size: UIFont.systemFontSize)!
configuration.allowsDelayedPaymentMethods = true
configuration.defaultBillingDetails =
    [
      "address":
        [ "city": "San Francisco",
          "country": "US",
          "line1": "1467",
          "line2": "Harrison Street",
          "postalCode": "94122",
          "state": "California"
        ],
      "email": "johndoe@hyperswitch.io",
      "name": "John",
      "phone": "1234567890"
    ]
```

### Colors

Modify the colour categories in `PaymentSheet.Colors` to customize the colours on the mobile payment sheet as follows:

| Colour Category  | Usage                                                                          |
| ---------------- | ------------------------------------------------------------------------------ |
| appBarIcon       | Color used for icons in the payment page ex: close (x) button                  |
| component        | Background colour of inputs, tabs and other components                         |
| componentBorder  | Border color for inputs, tabs and other components                             |
| componentDivider | Color for divider lines used inside inputs, tabs and other components          |
| error            | Color for error messages to the user on the payment page                       |
| onComponent      | Color of text and other elements inside components                             |
| onSurface        | Color for items appearing on the surface of the payment page, Ex: text prompts |
| placeholderText  | Color for input fields placeholder text                                        |
| primary          | The primary color to be used across the payment page                           |
| subtitle         | Color of secondary text like prompts for input fields                          |
| surface          | Color of the payment page                                                      |

### Shapes

Modify the corner radius and border width used across the payment page using `appearance.shapes`.

| Shape Category      | Usage                                                                                          |
| ------------------- | ---------------------------------------------------------------------------------------------- |
| borderStrokeWidthDp | Width of the border used to across input fields, tabs and other components of the payment page |
| cornerRadiusDp      | Corner radius of the input fields, tabs and other components                                   |

Now you can test the payments on your app and go-live!


# Cross Platform

Build cross-platform payments with React Native and Flutter SDKs

Juspay Hyperswitch provides **seamless cross-platform payment integrations** for both **React Native** and **Flutter**, enabling you to deliver a consistent payment experience across iOS, Android, and Web.

### Key Benefits

* **Unified API Design** – Minimal changes when switching between platforms.
* **Feature Parity** – Same payment capabilities on React Native, Flutter, and native SDKs.
* **Lite SDK Support** – Reduce app bundle size without sacrificing features.
* **Customization Options** – Branding, appearance, billing, and payment method preferences are fully configurable.

{% content-ref url="/pages/fn2rnSp8ZXCQvgSgVf3X" %}
[React Native](/integration-guide/payment-suite/payment-method-card/mobile/cross-platform/react-native)
{% endcontent-ref %}

{% content-ref url="/pages/GgThW061NEsmgK3YBvXY" %}
[Flutter](/integration-guide/payment-suite/payment-method-card/mobile/cross-platform/flutter)
{% endcontent-ref %}


# React Native

Integrate unified checkout with your react native app

<figure><img src="/files/S6rf4U6uYFdWoKQnrHlc" alt="" width="375"><figcaption></figcaption></figure>

Revolutionize your app's payment capabilities with the Juspay Hyperswitch React Native SDK, delivering a seamless and tailored Global Checkout Experience. The Juspay Hyperswitch Unified Checkout on React native is meticulously designed to provide an all-encompassing, unified, and optimized payment journey, ensuring exceptional conversion rates.

**Inclusive:** Supporting a diverse array of global payment methods, including cards, buy now pay later, and digital wallets, the Unified Checkout adapts to local preferences. Customize the experience further with the ability to integrate local languages, creating a truly inclusive payment solution.

**Consistent:** Enjoy a singular and consistent payment experience across platforms, whether on the web, Android, or iOS. Driven by smart payment forms, minimal redirections, and intelligent retries, the Unified Checkout ensures a reliable and uniform payment process.

**Blended:** Tailor the payment experience to seamlessly integrate with your product using 40+ styling APIs. Achieve a fully native and embedded payment experience within your Android app or website, creating a cohesive and branded checkout environment.

**Modify and Experiment:** While the Unified Checkout is pre-optimized for maximum conversions, the Juspay Hyperswitch React Native SDK empowers you to go beyond the standard. Take control with our SDK APIs, allowing you to:

* **Include New Fields:** Adapt swiftly to various use cases by adding new fields to the payment form, such as collecting billing addresses or zip codes for additional information.
* **Prioritize Payment Methods:** Impact your payment mix and conversion rates by prioritizing or promoting specific payment methods based on your customer preferences.
* **Switch Themes and Layouts:** Choose from a wide range of pre-designed themes and layouts for the checkout page, aligning the Unified Checkout with your app's aesthetics.

Experience the flexibility to modify and experiment, ensuring your app's payment journey aligns precisely with your business requirements and user expectations. Elevate your Android app's payment experience with the Juspay Hyperswitch React Native SDK.


# React Native with REST API Integration

Integrate Juspay Hyperswitch SDK to your React Native App using hyperswitch-node

{% hint style="info" %}
Use this guide to integrate the Juspay Hyperswitch React Native SDK to your React Native app. You can use the following Demo App as a reference with your Hyperswitch credentials to test the setup.
{% endhint %}

### Find the Demo App

Find the demo app [here](https://github.com/juspay/react-native-hyperswitch)

Before proceeding with these steps, please ensure that your payment methods are configured [here](/other-features/payment-orchestration/quickstart/payment-methods-setup/cards).

### Requirements

* Android 7.0 (API level 24) and above
* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) 7.3.1
* [Gradle](https://gradle.org/releases/) 7.5.1+
* [AndroidX](https://developer.android.com/jetpack/androidx/)
* iOS 12.4 and above
* CocoaPods
* npm

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on the client

#### 2.1 Install the `@juspay-tech/react-native-hyperswitch` library

Install the packages and import it into your code

```bash
yarn add @juspay-tech/react-native-hyperswitch
or
npm install @juspay-tech/react-native-hyperswitch
```

#### 2.2 Peer Dependencies

Install the following dependencies

```js
yarn add react-native-inappbrowser-reborn
yarn add react-native-svg
yarn add @sentry/react-native
```

#### 2.3 iOS Only

Run `pod install` in iOS folder

```js
pod install
```

#### 2.4 Use `HyperProvider`

To initialize Juspay Hyperswitch in your React Native app, wrap your payment screen with the **HyperProvider** component. The only required configuration is the **API publishable key**, which should be provided through the `publishableKey` prop.

```js
import { HyperProvider } from '@juspay-tech/react-native-hyperswitch';
function App() {
  return (
    <HyperProvider publishableKey="YOUR_PUBLISHABLE_KEY" profileId="YOUR_PROFILE_ID">
      // Your app code here
    </HyperProvider>
  );
}
```

### 3. Complete the checkout on the client

#### 3.1 import useHyper to your checkout page

In your checkout screen, import and use the **`useHyper()`** hook to access Juspay Hyperswitch payment methods and functionality.

```js
import { useHyper } from '@juspay-tech/react-native-hyperswitch';
```

#### 3.2 Fetch the PaymentIntent client Secret

Send a network request to the backend endpoint created in the previous step to retrieve the **clientSecret**. The **clientSecret** returned by this endpoint is required to complete the payment.

```js
const fetchPaymentParams = async () => {
  const response = await fetch(`${API_URL}/create-payment`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ items: [{ id: "xl-tshirt" }], country: "US" }),
  });
  const val = await response.json();
  return val;
};
```

#### 3.3 Collect Payment details

Call **`initPaymentSession`** from the **`useHyper`** hook to initialize the Payment Sheet and configure options such as **appearance, billing details, or shipping address** before presenting the payment flow.

```js
const { initPaymentSession, presentPaymentSheet } = useHyper();
const [ paymentSession, setPaymentSession ]=React.useState(null);
const initializePaymentSheet = async () => {
  const { clientSecret, sdkAuthorization } = await fetchPaymentParams();

  const customAppearance = {
    colors: {
      light: {
        primary: "#00FF00",
      },
    },
  };
  const params={
      merchantDisplayName: "Example, Inc.",
      clientSecret: clientSecret,
      sdkAuthorization: sdkAuthorization,
      appearance: customAppearance
  }
  const result = await initPaymentSession(params);
  if (result.error) {
        console.error('Payment session initialization failed:', result.error);
  } else {
      setPaymentSession(_ => paymentSession)
  }
};

useEffect(() => {
  initializePaymentSheet();
}, []);
```

#### 3.4 Handle Payment Response

To display the **Payment Sheet**, add a **"Pay Now"** button to your checkout page. When the button is pressed, call the **`presentPaymentSheet()`** function.

This function returns an **asynchronous response** containing the payment result, including the payment status.

```js
  const openPaymentSheet = async () => {
    const result = await presentPaymentSheet(paymentSession);

    if (result.error) {
      console.log(`Error code: ${error.code}`, error.message);
    } else if (result.status) {
      switch (result.status) {
        case 'succeeded':
          console.log('succeeded', `Your order is succeeded`);
          break;
        case 'requires_capture':
          console.log('requires_capture', `Your order is requires_capture`);
          break;
        case 'cancelled':
          console.log('cancelled', `Payment is cancelled`);
        case 'failed':
          console.log('failed', `Payment is failed');
        default:
          console.log('status not captured', 'Please check the integration');
          break;
      }
    } else {
      console.log('Something went wrong', 'Please check the integration');
    }
  };


return (
  <Screen>
    <Button variant="primary" title="Checkout" onPress={openPaymentSheet} />
  </Screen>
);
```

{% hint style="danger" %}
Retrieve the **payment status from the Juspay Hyperswitch backend** to determine the final (terminal) status of the transaction. Do not rely solely on the status returned by the SDK, as it may not always represent the definitive outcome of the payment.
{% endhint %}

Congratulations! Now that you have integrated the payment sheet


# Payment Widget

Implement embedded payment widget in React Native applications

The **PaymentWidget** component from Juspay Hyperswitch renders an **embedded, inline payment form directly inside your screen**, instead of opening a modal payment sheet. This approach is useful for **custom checkout pages** where you want full control over layout and UI.

### Find the Demo App

Find the demo app [here](https://github.com/juspay/react-native-hyperswitch/tree/main/example)

### 1. Basic Usage

#### 1.1 Install the react native sdk

```shellscript
npm install @juspay-tech/react-native-hyperswitch
# or
yarn add @juspay-tech/react-native-hyperswitch
```

#### 1.1.1 Install Peer Dependencies

The SDK requires the following peer dependencies to be installed in your project:

```shellscript
yarn add react-native-inappbrowser-reborn
yarn add react-native-svg
yarn add @sentry/react-native
# or
npm install react-native-inappbrowser-reborn
npm install react-native-svg
npm install @sentry/react-native
```

#### 1.2 Wrap your app with `HyperProvider`

To initialize Hyperswitch in a React Native application, wrap your payment screen with the **HyperProvider** component. The **publishable key** is required and must be provided to the `HyperProvider` during initialization.

```js
import { HyperProvider } from "@juspay-tech/react-native-hyperswitch";

function App() {
  return (
    <HyperProvider publishableKey="YOUR_PUBLISHABLE_KEY" profileId="YOUR_PROFILE_ID">
      // Your app code here
    </HyperProvider>
  );
}
```

#### 1.3 Fetch the PaymentIntent client Secret

Send a network request to the backend endpoint created in the previous step to retrieve the **clientSecret**. This **clientSecret** returned from the endpoint is required to complete the payment.

```js
useEffect(() => {
    fetch('https://your-server.com/create-payment-intent', { method: 'POST' })
      .then((res) => res.json())
      .then(({ clientSecret, sdkAuthorization, }) => {
        setClientSecret(clientSecret);
        setAuthorization(sdkAuthorization);
      }
}, []);
```

#### 1.4 Render your Payment widget

Use the **Hyperswitch `PaymentWidget`** component to render an embedded payment form

```js
import { PaymentWidget } from '@juspay-tech/react-native-hyperswitch';

export default function PaymentUI() {
  // rest of your logic
  return (
    <PaymentWidget
      widgetId="checkout-widget"
      options={{
        clientSecret,
        sdkAuthorization,
        appearance: { theme: 'light' },
      }}
      onPaymentResult={(result) => {
        if (result.errorMessage) {
          // Payment failed
          console.error('Payment failed:', result.errorMessage);
        } else if (result.status === 'succeeded') {
          // Payment succeeded
          console.log('Payment succeeded!');
        } else if (result.status === 'cancelled') {
          // User cancelled the payment
        }
      }}
      style={{ width: '100%', height: 600 }}
    />
  );
}
```

Avoid placing the `PaymentWidget` inside a `ScrollView`. If necessary, ensure that the parent scroll is disabled while the user interacts with the widget to prevent scrolling conflicts.

#### 1.5 `onPaymentResult` Callback

The `onPaymentResult` callback is triggered when the payment flow finishes. It provides a result object containing the payment outcome.

```
onPaymentResult={(result) => {
  console.log(result);
}}
```

```
// type PaymentWidgetResult:  {
    status?: string;        // "succeeded", "cancelled", or "Failed"
    errorMessage?: string;  // Present if an error occurred
}
```

#### **Congratulations! You have successfully integrated the Payment Widget into your application.**

### Props

**`widgetId`** `string` · Required

A unique identifier for the widget instance.

***

**`options`** `PresentPaymentSheetParams` · Required

Configuration and appearance options.

When using `PaymentWidget`, pass the `clientSecret` & `sdkAuthorization` here.

For more customizations follow [this](/integration-guide/payment-suite/payment-method-card/mobile/cross-platform/react-native/customization)

***

**`onPaymentResult`** `(result: PaymentWidgetResult) => void` · Optional

Callback triggered when the payment completes, fails, or is cancelled.

***

**`style`** `StyleProp<ViewStyle>` · `width` & `height` required

Defines the size and layout of the widget container.


# Headless SDK

Juspay Hyperswitch is designed to facilitate the integration and management of payment-related functionalities in a decoupled or headless architecture with flexibility to customize your checkout UI.

### Customize the payment experience using Headless functions

#### 1. Initialize the Hyperswitch SDK

Initialize Juspay Hyperswitch Headless SDK onto your app with your publishable key. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

```javascript
import { HyperProvider } from "@juspay-tech/hyperswitch-react-native";

function App() {
  return (
    <HyperProvider publishableKey="YOUR_PUBLISHABLE_KEY">
      // Your app code here
    </HyperProvider>
  );
}
```

#### 2. Create a Payment Intent

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to initialize the payment session.

{% hint style="danger" %}
**Important**: Make sure to never share your API key with your client application as this could potentially compromise your security
{% endhint %}

#### 3. Initialize your Payment Session

Initialize a Payment Session by passing the clientSecret to the `initPaymentSession`

```javascript
import { useHyper } from "@juspay-tech/react-native-hyperswitch";

const { initPaymentSession } = useHyper();
const [paymentSession,setPaymentSession] = React.useState(null);

const initializeHeadless = async() => {
  const { clientSecret } = await fetchPaymentParams();
  const params = {clientSecret:clientSecret}
  const paymentSession = await initPaymentSession(params);
  setPaymentSession(_ => paymentSession)
};

useEffect(() => {
  initializeHeadless();
}, []);

```

| options (Required)                   | Description                                                     |
| ------------------------------------ | --------------------------------------------------------------- |
| `paymentIntentClientSecret (string)` | **Required.** Required to use as the identifier of the payment. |

#### 4. Craft a customized payments experience

Using the `paymentSession` object, the default customer payment method data can be fetched, using which you can craft your own payments experience. The `paymentSession` object also exposes a `confirmWithCustomerDefaultPaymentMethod` function, using which you can confirm and handle the payment session.

```javascript
import { useHyper } from "@juspay-tech/react-native-hyperswitch";

const { getCustomerSavedPaymentMethods,
        getCustomerDefaultSavedPaymentMethodData,
        confirmWithCustomerDefaultPaymentMethod } = useHyper();

const [defaultPaymentMethodData,setDefaultPaymentMethodData]=React.useState(null)

React.useEffect(()=>{
    const getPaymentMethods = async() => {
        const paymentMethodSession 
                = await getCustomerSavedPaymentMethods(paymentSession);
        const customer_default_saved_payment_method_data 
                = await getCustomerLastUsedSavedPaymentMethodData(paymentMethodSession);
        setDefaultPaymentMethodData(_=>customer_default_saved_payment_method_data)
    }
    getPaymentMethods()
},[])

let confirmDefaultPaymentMethod = () => {
const status = await confirmWithCustomerLastUsedPaymentMethod(paymentMethodSession);
    // handle status of payment   
    if (status != null) {
        const message = status.message;
        console.log(message)
    }
}

return (
    //build the ui using defaultPaymentMethodData
    //on click of pay use confirmDefaultPaymentMethod()
)
```

**Payload for** `confirmWithCustomerLastUsedPaymentMethod(callback)`

<table><thead><tr><th width="296">options (Required)</th><th>Description</th></tr></thead><tbody><tr><td><code>callback (function)</code></td><td>Callback to get confirm response.</td></tr></tbody></table>


# Customization

Visual customization: Colors, shapes, specific UI components

{% hint style="info" %}
You can customize the Juspay Hyperswitch React Native Unified Checkout to support visual customization, which allows you to match the design of your app
{% endhint %}

### Appearance

Use the `appearance` parameter to customize colors, fonts, and more when calling `initPaymentSheet()` or via the `options` prop when using `PaymentWidget`.

### Colors

Customize the colors in the mobile Payment Element by modifying the color categories. Each color category determines the color of one or more components in the UI. For example, primary defines the color of the Pay button

<table><thead><tr><th width="274.89453125">Color Category</th><th>Usage</th></tr></thead><tbody><tr><td>primary</td><td>Primary defines the color of the Pay button and selected items</td></tr><tr><td>background</td><td>The color used for the background of your Payment page</td></tr><tr><td>componentBackground</td><td>The color used for the background of inputs, tabs, and other components</td></tr><tr><td>componentBorder</td><td>The color used for the external border of inputs, tabs, and other components in your PaymentSheet</td></tr><tr><td>componentDivider</td><td>The color used for the internal border (meaning the border is shared with another component) of inputs, tabs, and other components in your PaymentSheet</td></tr><tr><td>primaryText</td><td>The color of the header text in your Payment page</td></tr><tr><td>secondaryText</td><td>The color of the label text of input fields</td></tr><tr><td>componentText</td><td>The color of the input text in your PaymentSheet components, such as the user's card number or zip code</td></tr><tr><td>placeholderText</td><td>The color of the placeholder text of input fields</td></tr><tr><td>icon</td><td>The color used for icons in your Payment Sheet, such as the close (x) button</td></tr><tr><td>error</td><td>The color used to indicate errors or destructive actions in your Payment Sheet</td></tr></tbody></table>

```js
appearance: {
   colors: {
   primary: '#F8F8F2',
   background: '#ffffff',
   componentBackground: '#E6DB74',
   componentBorder: '#FD971F',
   componentDivider: '#FD971F',
   primaryText: '#F8F8F2',
   secondaryText: '#75715E',
   componentText: '#AE81FF',
   placeholderText: '#E69F66',
   icon: '#F92672',
   error: '#FF0000',
 }
}
```

> Note: To support dark mode, pass maps for both `light` and `dark` colors maps to `colors`

```js
colors: {
   light:{
      primary: '#F8F8F2',
      background: '#00FF00',
      componentBackground: '#E6DB74',
      componentBorder: '#FD971F',
      componentDivider: '#FD971F',
      primaryText: '#F8F8F2',
      secondaryText: '#75715E',
      componentText: '#AE81FF',
      placeholderText: '#E69F66',
      icon: '#F92672',
      error: '#F92672',
   },
   dark: {
      primary: '#00ff0099',
      background: '#ff0000',
      componentBackground: '#ff0080',
      componentBorder: '#62ff08',
      componentDivider: '#d6de00',
      primaryText: '#5181fc',
      secondaryText: '#ff7b00',
      componentText: '#00ffff',
      placeholderText: '#00ffff',
      icon: '#f0f0f0',
      error: '#0f0f0f',
    },
 },
```

### Shapes

Customize the border radius, border width, and shadow used across the payment UI.

| Shape Category | Usage                                                             |
| -------------- | ----------------------------------------------------------------- |
| borderRadius   | Corner radius of input fields, tabs, and other components.        |
| borderWidth    | Border thickness across input fields, tabs, and other components. |

```js
shapes: {
    borderRadius: 10,
    borderWidth: 1,
  },
```

### Specific UI components

The sections above describe customization options that affect the mobile Payment Element broadly, across multiple UI components. We also provide customization options specifically for the primary button (for example, the Pay button).

Customization options for specific UI components take precedence over other values. For example, `primaryButton.shapes.borderRadius` overrides the value of `shapes.borderRadius`.

#### Primary Button

Overrides global `colors` and `shapes` for the primary button (e.g. the Pay button). Takes precedence over global values.

```js
primaryButton: {
    colors: {
      background: '#000000',
      text: '#ffffff',
      border: '#ff00ff',
    },
    shapes: {
      borderRadius: 10,
      borderWidth: 1.5,
    },
  },

```

#### Google Pay Button

```
googlePay: {
  buttonType: 'BUY',   // BUY | BOOK | CHECKOUT | DONATE | ORDER | PAY | SUBSCRIBE | PLAIN
  buttonStyle: {
    light: 'dark',
    dark: 'light',
  }
}
```

### Apple Pay Button

```
applePay: {
  buttonType: 'buy',   // buy | setUp | inStore | donate | checkout | book | subscribe | plain
  buttonStyle: {
    light: 'black',    // white | whiteOutline | black
    dark: 'white',
  }
}
```

Now you can test the payments on your app and go-live!


# Expo integration

Integrate Juspay Hyperswitch SDK with Expo for React Native apps

{% hint style="info" %}
**Note:** **Expo Go is not supported.**\
The Juspay Hyperswitch SDK uses native modules, so the app must be built with native Android and iOS code.
{% endhint %}

### 1. Install Required Dependencies

The Juspay Hyperswitch SDK has peer dependencies that must be installed before installing the SDK.

```
# Install peer dependencies
yarn add @sentry/react-native react-native-inappbrowser-reborn react-native-svg

# Install Hyperswitch SDK
yarn add @juspay-tech/react-native-hyperswitch
```

### 2. Prebuild the App

Generate the native **Android** and **iOS** folders:

```
npx expo prebuild --clean
```

This command will:

* Generate **Android and iOS native folders**
* Run **CocoaPods** for iOS dependencies
* Configure **TurboModule code generation**
* **Auto-link native modules**

### 3. Implement the Payment Flow

After completing the Expo setup, **follow the same steps as the React Native integration** to implement the payment flow:

1. Wrap your app with **HyperProvider**
2. Use the **useHyper()** hook
3. Initialize the payment session using **initPaymentSession**
4. Present the payment sheet using **presentPaymentSheet**

Refer to the [**React Native integration steps**](/integration-guide/payment-suite/payment-method-card/mobile/cross-platform/react-native/react-native-with-rest-api-integration) for the complete payment flow implementation.


# Troubleshooting

Troubleshoot common issues with React Native and Flutter SDKs

This guide helps you resolve common issues encountered when integrating Juspay Hyperswitch React Native and Flutter SDKs.

### Android

1. If you encounter issues related to the **Android browser dependency**, ensure that the required AndroidX Browser version is defined in your project.

Add the following versions in your **root `build.gradle`** (or version catalog equivalent):

```
ext {
    androidXBrowser = "1.8.0"
    androidXAnnotation = "1.7.1"
}
```

### iOS

If you are using the **old architecture (Fabric/TurboModules disabled)**, run the pod install with the following command:

```
RCT_NEW_ARCH_ENABLED=0 pod install --verbose
```

This ensures that **React Native installs pods with the old architecture configuration**.


# Flutter

Integrate unified checkout with your Flutter app

<figure><img src="/files/S6rf4U6uYFdWoKQnrHlc" alt="" width="375"><figcaption></figcaption></figure>

Revolutionize your app's payment capabilities with the Juspay Hyperswitch Flutter SDK, delivering a seamless and tailored Global Checkout Experience. The Juspay Hyperswitch Unified Checkout on Flutter is meticulously designed to provide an all-encompassing, unified, and optimized payment journey, ensuring exceptional conversion rates.

**Inclusive:** Supporting a diverse array of global payment methods, including cards, buy now pay later, and digital wallets, the Unified Checkout adapts to local preferences. Customize the experience further with the ability to integrate local languages, creating a truly inclusive payment solution.

**Consistent:** Enjoy a singular and consistent payment experience across platforms, whether on the web, Android, or iOS. Driven by smart payment forms, minimal redirections, and intelligent retries, the Unified Checkout ensures a reliable and uniform payment process.

**Blended:** Tailor the payment experience to seamlessly integrate with your product using styling APIs. Achieve a fully native and embedded payment experience within your Android app or website, creating a cohesive and branded checkout environment.

**Modify and Experiment:** While the Unified Checkout is pre-optimized for maximum conversions, the Juspay Hyperswitch Flutter SDK empowers you to go beyond the standard. Take control with our SDK APIs, allowing you to:

* **Include New Fields:** Adapt swiftly to various use cases by adding new fields to the payment form, such as collecting billing addresses or zip codes for additional information.
* **Prioritize Payment Methods:** Impact your payment mix and conversion rates by prioritizing or promoting specific payment methods based on your customer preferences.
* **Switch Themes and Layouts:** Choose from a wide range of pre-designed themes and layouts for the checkout page, aligning the Unified Checkout with your app's aesthetics.

Experience the flexibility to modify and experiment, ensuring your app's payment journey aligns precisely with your business requirements and user expectations. Elevate your app's payment experience with the Juspay Hyperswitch Flutter SDK.


# Flutter with REST API Integration

Integrate Juspay Hyperswitch SDK to your Flutter App using hyperswitch-node

{% hint style="info" %}
Use this guide to integrate Juspay Hyperswitch SDK to your Flutter app.
{% endhint %}

**Before following these steps, please configure your payment methods** [here](/other-features/payment-orchestration/quickstart/payment-methods-setup/cards).

### Requirements

* Android 7.0 (API level 24) and above
* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) 8.5+
* [Gradle](https://gradle.org/releases/) 8.8+
* [AndroidX](https://developer.android.com/jetpack/androidx/)
* iOS 13.0 and above
* CocoaPods
* npm

### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-suite/payment-method-card/server-setup) section.

### 2. Build checkout page on the client

#### 2.1 Install the `flutter_hyperswitch` library

Add `flutter_hyperswitch` to your `pubspec.yaml` file

```yaml
dependencies:
  flutter_hyperswitch: ^version_number
```

Run the following command to fetch and install the dependencies.

```sh
flutter pub get
```

{% hint style="info" %}
To apply plugins using Flutter, run the following command:

```sh
dart run flutter_hyperswitch:apply_plugins
```

This command configures the necessary Flutter plugins for your project using the `flutter_hyperswitch` package. Ensure you have the package installed and configured correctly in your project. If you encounter any issues, check the package documentation for more details.
{% endhint %}

### 3. Complete the checkout on the client

#### 3.1 Initialize the Hyperswitch SDK

Initialize `Hyper` onto your app with your publishable key with the `Hyper` constructor. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

```dart
import 'package:flutter_hyperswitch/flutter_hyperswitch.dart';
final _hyper = FlutterHyperswitch();
_hyper.init(HyperConfig(publishableKey: 'YOUR_PUBLISHABLE_KEY', customBackendUrl: 'YOUR_CUSTOM_BACKEND_URL'));
```

{% hint style="info" %}
When utilizing a custom backend or logging system, you can add the customBackendUrl to HyperConfig
{% endhint %}

#### 3.2 Create a Payment Intent

Make a network request to the backend endpoint you created in the [previous step](#id-1.2-create-a-payment). The clientSecret returned by your endpoint is used to complete the payment.

```dart
Future<String> fetchPaymentParams() async {
    try {
      var response = await http.get(Uri.parse("$API_URL/create-payment"));
      return jsonDecode(response.body)["clientSecret"];
    } catch (error) {
      throw Exception("Create Payment API call failed");
    }
  }
```

#### 3.3 Initialize your Payment Session

Initialize a Payment Session by passing the clientSecret to the `initPaymentSession`

```dart
final params = PaymentMethodParams(clientSecret: 'YOUR_PAYMENT_INTENT_CLIENT_SECRET');
Session? _sessionId = await _hyper.initPaymentSession(params);
```

#### 3.4 Present payment sheet and handle response

To display the Payment Sheet, integrate a "**Pay Now**" button within the checkout page, which, when clicked, invokes the `presentPaymentSheet()` method and handles the payment response.

Consider the below function, it invokes `presentPaymentSheet` and handles payment results.

{% code fullWidth="false" %}

```dart
Future<void> _presentPaymentSheet() async {
  final presentPaymentSheetResponse = await _hyper.presentPaymentSheet(_sessionId!);
  if (presentPaymentSheetResponse != null) {
    final message = presentPaymentSheetResponse.message;
    setState(() {
      if (message.isLeft) {
        _statusText =
            "${presentPaymentSheetResponse.status.name}\n${message.left!.name}";
      } else {
        _statusText =
            "${presentPaymentSheetResponse.status.name}\n${message.right}";
      }
    });
  }
}
```

{% endcode %}

Congratulations! Now that you have integrated the Flutter SDK, you can [**customize**](/integration-guide/payment-suite/payment-method-card/mobile/cross-platform/flutter/customization) the payment sheet to blend with the rest of your app.

{% hint style="danger" %}
Please retrieve the payment status from the Juspay Hyperswitch backend to get the terminal status of the payment. Do not rely solely on the status returned by the SDK, as it may not always reflect the final state of the transaction.
{% endhint %}

### Next Step

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}


# Headless SDK

Juspay Hyperswitch is designed to facilitate the integration and management of payment-related functionalities in a decoupled or headless architecture with flexibility to customize your checkout UI.

### Customize the payment experience using Headless functions

#### 1. Initialize the Hyperswitch SDK

Initialize Juspay Hyperswitch Headless SDK onto your app with your publishable key. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

```dart
// dependencies: flutter_hyperswitch: ^version_number
// run the following command to fetch and install the dependencies flutter pub get
import 'package:flutter_hyperswitch/flutter_hyperswitch.dart';
_hyper.init(HyperConfig(publishableKey: 'YOUR_PUBLISHABLE_KEY'));
```

#### 2. Create a Payment Intent

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to initialize the payment session.

{% hint style="danger" %}
**Important**: Make sure to never share your API key with your client application as this could potentially compromise your security
{% endhint %}

#### 3. Initialize your Payment Session

Initialize a Payment Session by passing the clientSecret to the `initPaymentSession`

```dart
final params = PaymentMethodParams(clientSecret: 'YOUR_PAYMENT_INTENT_CLIENT_SECRET')
Session _sessionId = await hyper.initPaymentSession(params);
```

| options (Required)                   | Description                                                     |
| ------------------------------------ | --------------------------------------------------------------- |
| `paymentIntentClientSecret (string)` | **Required.** Required to use as the identifier of the payment. |

#### 4. Craft a customized payments experience

Using the `paymentSession` object, the default customer payment method data can be fetched, using which you can craft your own payments experience. The `paymentSession` object also exposes a `confirmWithCustomerDefaultPaymentMethod` function, using which you can confirm and handle the payment session.

```dart
SavedSession? _savedSessionId = await _hyper.getCustomerSavedPaymentMethods(_sessionId!);

// use the customer_default_saved_payment_method_data to fulfill your usecases
final customer_last_used_saved_payment_method_data = await _hyper.getCustomerLastUsedSavedPaymentMethodData(_savedSessionId!);
if (customer_last_used_saved_payment_method_data != null) {
    final paymentMethod = customer_last_used_saved_payment_method_data.left;
    if (paymentMethod != null) {
       final card = paymentMethod.left;
    }
  }
}

// use the confirmWithCustomerDefaultPaymentMethod function to confirm and handle the payment session response
Future<void> _confirmPayment() async {
  final confirmWithLastUsedPaymentMethodResponse = 
    await _hyper.confirmWithLastUsedPaymentMethod(_savedSessionId!);
  if (confirmWithLastUsedPaymentMethodResponse != null) {
    final message = confirmWithLastUsedPaymentMethodResponse.message;
    if (message.isLeft) {
      _confirmStatusText = "${confirmWithLastUsedPaymentMethodResponse.status.name}\n${message.left!.name}";
    } else {
      _confirmStatusText = "${confirmWithLastUsedPaymentMethodResponse.status.name}\n${message.right}";
    }
  }
}
```

**Payload for** `confirmWithCustomerLastUsedPaymentMethod(callback)`

<table><thead><tr><th width="296">options (Required)</th><th>Description</th></tr></thead><tbody><tr><td><code>callback (function)</code></td><td>Callback to get confirm response.</td></tr></tbody></table>


# Customization

Visual customization: Colors, shapes, specific UI components

{% hint style="info" %}
You can customize the Juspay Hyperswitch Flutter Unified Checkout to support visual customization, which allows you to match the design of your app.
{% endhint %}

You can modify colors, fonts, and more by using the instance of `appearance` class.

### Colors

Customize the colors in the mobile Payment Element by modifying the color categories. Each color category determines the color of one or more components in the UI. For example, primary defines the color of the Pay button.

| Color Category      | Usage                                                                                                                                                   |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| primary             | Primary defines the color of the Pay button and selected items                                                                                          |
| background          | The color used for the background of your Payment page                                                                                                  |
| componentBackground | The color used for the background of inputs, tabs, and other components                                                                                 |
| componentBorder     | The color used for the external border of inputs, tabs, and other components in your PaymentSheet                                                       |
| componentDivider    | The color used for the internal border (meaning the border is shared with another component) of inputs, tabs, and other components in your PaymentSheet |
| primaryText         | The color of the header text in your Payment page                                                                                                       |
| secondaryText       | The color of the label text of input fields                                                                                                             |
| componentText       | The color of the input text in your PaymentSheet components, such as the user's card number or zip code                                                 |
| placeholderText     | The color of the placeholder text of input fields                                                                                                       |
| icon                | The color used for icons in your Payment Sheet, such as the close (x) button                                                                            |
| error               | The color used to indicate errors or destructive actions in your Payment Sheet                                                                          |

For using custom colors for SDK, you should create an instance of `ColorsObject` class by passing the above attributes to its constructor. Now, you have to create an instance of `DynamicColors` class by invoking its constructor and passing the object of `ColorsObject` class created earlier. Finally, you have to create an instance of `Appearance` class by passing the object of `DynamicColors` class.

Consider the below code for your reference.

```dart
ColorsObject colorsObject = ColorsObject(
     primary: '#F8F8F2',
      background: '#00FF00',
      componentBackground: '#E6DB74',
      componentBorder: '#FD971F',
      componentDivider: '#FD971F',
      primaryText: '#F8F8F2',
      secondaryText: '#75715E',
      componentText: '#AE81FF',
      placeholderText: '#E69F66',
      icon: '#F92672',
      error: '#F92672'
    );

    DynamicColors colors =
        DynamicColors(light: colorsObject);
    PrimaryButton primaryButton = PrimaryButton(colors: colors);

    Appearance appearance = Appearance(
      colors: colors,
      primaryButton: primaryButton,
    );
```

### Configuration and Appearance

Now, create an instance of `Configuration` class by invoking its constructor and passing the object of `Appearance` class created above. Then, you have to create an instance of `PaymentSheetParams` class by invoking its constructor and passing the object of `Configuration` class created earlier.

Consider the below code for your reference.

```dart
  Configuration configuration= Configuration(appearance: appearance)
  configuration.displaySavedPaymentMethods: true,
  configuration.displaySavedPaymentMethodsCheckbox: true,
 
  PaymentSheetParams params = PaymentSheetParams(
      publishableKey: "YOUR_PUBLISHABLE_KEY",
      clientSecret: clientSecret,
      configuration: configuration,
    );
```

{% hint style="info" %}
Set `displaySavedPaymentMethods` to false to disable saved cards.

Set `displaySavedPaymentMethodsCheckbox` to false to stop your users from saving their payment methods. Set `disableBranding` to false to disable Juspay Hyperswitch branding. Set `primaryButtonLabel` to "Pay Button Text" to display custom text Set `paymentSheetHeaderLabel` to "Heading Text" to display custom heading
{% endhint %}

### Custom Placeholders And Branding

To set custom placeholder text for card number, expiry date or cvv input fields, you may set the `placeholder` property for these as shown below.

```dart
configuration.placeholder.cardNumber = "YOUR_CUSTOM_CARD_NUMBER_PLACEHOLDER"
configuration.placeholder.expiryDate = "YOUR_CUSTOM_EXPIRY_DATE_PLACEHOLDER"
configuration.placeholder.cvv = "YOUR_CUSTOM_CVV_PLACEHOLDER"
```

To disable Juspay Hyperswitch branding in the SDK, you may set the `disableBranding` property to true

```dart
configuration.disableBranding = true
```

Finally, you can pass the object of PaymentSheetParams to `initPaymentSheet` as shown in the previous [section](https://docs.hyperswitch.io/integration-guide/payment-suite/payment-method-card/mobile/cross-platform/flutter/pages/ebHaowJXpQAe8i2eaL8X#id-3.3-collect-payment-details).

{% hint style="info" %}
Note: To support dark mode, pass objects of `ColorsObject` class for both light and dark colors to constructor of `DynamicColors` class like below.
{% endhint %}

```dart
ColorsObject lightColorsObject = ColorsObject(
     primary: '#F8F8F2',
      background: '#00FF00',
      componentBackground: '#E6DB74',
      componentBorder: '#FD971F',
      componentDivider: '#FD971F',
      primaryText: '#F8F8F2',
      secondaryText: '#75715E',
      componentText: '#AE81FF',
      placeholderText: '#E69F66',
      icon: '#F92672',
      error: '#F92672'
    );
    
 ColorsObject darkColorsObject = ColorsObject(
      primary: '#00ff0099',
      background: '#ff0000',
      componentBackground: '#ff0080',
      componentBorder: '#62ff08',
      componentDivider: '#d6de00',
      primaryText: '#5181fc',
      secondaryText: '#ff7b00',
      componentText: '#00ffff',
      placeholderText: '#00ffff',
      icon: '#f0f0f0',
      error: '#0f0f0f',
    );

DynamicColors colors = DynamicColors(light: lightColorsObject,dark: darkColorsObject);

```

### Shadow

You can customize the border radius, border width, and shadow used throughout the mobile Payment Element. Using an Object of inbuilt class `Shapes`.

| Shape Category | Usage                                                           |
| -------------- | --------------------------------------------------------------- |
| color          | shadow color of components of the payment page                  |
| intensity      | shadow intensity across input fields, tabs and other components |

```dart
Shadow shadow = Shadow(color:10.0, intensity: 10.0);
```

### Shapes

You can customize the border radius, border width, and shadow used throughout the mobile Payment Element. Using an Object of inbuilt class `Shapes`.

| Shape Category | Usage                                                                                   |
| -------------- | --------------------------------------------------------------------------------------- |
| borderRadius   | radius of the border of the input fields, tabs and other components of the payment page |
| borderWidth    | width of the border used to across input fields, tabs and other components              |
| shadow         | add Shadow to components                                                                |

```dart
Shapes shapes = Shapes(borderRadius:10.0, borderWidth: 10.0, shadow: shadow);
```

Now you can test the payments on your app and go-live!

### Languages

Juspay Hyperswitch Flutter SDK supports localization in 30+ languages. The default locale is English (en). To override, you can send locale in the appearance object. You may refer the below code for your reference.

```dart
Appearance appearance = Appearance(
     ...
      locale: 'LOCALE_CODE'
    );
```

We support the following locales -

* Arabic (ar)
* Hebrew (he)
* German (de)
* English (en)
* English (en-GB)
* Japanese (ja)
* French (fr)
* French (Belgium) (fr-BE)
* Spanish (es)
* Catalan (ca)
* Portuguese (pt)
* Italian (it)
* Polish (pl)
* Dutch (nl)
* Dutch (Belgium) (nl-BE)
* Swedish (sv)
* Russian (ru)
* Lithuanian (lt)
* Czech (cs)
* Slovak (sk)
* Icelandic (is)
* Welsh (cy)
* Greek (el)
* Estonian (et)
* Finnish (fi)
* Norwegian (nb)
* Bosnian (bs)
* Danish (da)
* Malay (ms)
* Turkish (tr-CY)

### Next Step

{% content-ref url="/pages/rC86PKskoru41ra6XehR" %}
[Setup Payment Methods](/other-features/payment-orchestration/quickstart/payment-methods-setup)
{% endcontent-ref %}


# Server Setup

Set up server-side payment creation and SDK integration for Juspay Hyperswitch

### Create a payment using S2S Call

To create a payment intent, send a request to either our sandbox or production endpoint. For detailed information, refer to the [**API Reference**](https://api-reference.hyperswitch.io/v1/payments/payments--create) documentation.

Upon successful creation, you will receive a `client_secret`, which must be provided to the SDK to render it properly.

```javascript
// Example Usage :- Can be Modified
async function createPaymentIntent(request) {
  /* Add respective env endpoints
   - Sandbox - https://sandbox.hyperswitch.io
   - Prod - https://api.hyperswitch.io
  */
  const url = "https://sandbox.hyperswitch.io";
  const apiResponse = await fetch(`${url}/payments`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Accept: "application/json",
      "api-key": `API_KEY`,
    },
    body: JSON.stringify(request),
  });
  const paymentIntent = await apiResponse.json();

  if (paymentIntent.error) {
    console.error("Error - ", paymentIntent.error);
    throw new Error(paymentIntent?.error?.message ?? "Something went wrong.");
  }
  return paymentIntent;
}
```

### Integrate Web SDK

*To integrate Web SDK, follow React, HTML and JS with REST API Integration.*

### Integrate Mobile SDK

*To integrate mobile SDK, follow Kotlin, Swift, React Native, and Flutter with REST API Integration*

{% hint style="info" %}
In case you're integrating the ExpressCheckout (mentioned later below), instead of creating multiple paymentIntents for the same customer session, you can also use [paymentsUpdate API](https://api-reference.hyperswitch.io/v1/payments/payments--update) for better analytics.
{% endhint %}


# Payment Links

Low-code solution to accept payments

Introducing Payment Links - Seamlessly integrate into Juspay Hyperswitch without writing much code. This feature allows you to generate secure and personalised payment links, enabling swift and hassle-free transactions for your customers. Elevate your payment experience with the efficiency and flexibility of Payment Links, streamlining the way you conduct business transactions.

### Use cases for Payment links

* Email/SMS marketing or selling online with a website.
* Having multiple customer segments - to create tailored payment pages that are optimized for each bucket of customers.
* Fundraising or collecting donations.
* Accepting payments in person but don't have the hardware.
* Social Media Commerce
* Cross-channel customer reactivation
* Automated Payment Reminders to automate collections
* Substitute for Cash-on-delivery and point-of-sale
* Streamlining over-the-phone transactions

{% embed url="<https://www.youtube.com/watch?v=8SGyP3kIpQo>" %}
API Level Overview of Payment Links with Hyperswitch
{% endembed %}

### FAQ

<details>

<summary>Can I create a payment link pointing to my custom domain?</summary>

Yes. Your custom domain can be included in the default payment\_link\_config object as part of the business profile update.

This involves adding CNAME records and TLS certificates which ends up being a slightly complex process. Please reach out to our [Support](https://join.slack.com/t/hyperswitch-io/shared_invite/zt-1k6cz4lee-SAJzhz6bjmpp4jZCDOtOIg) to test this feature out with your custom domain.

</details>

<details>

<summary>Can I configure Payment links through Hyperswitch Control centre?</summary>

Currently, the Control centre's capability to create payment links is under development and will be available by Q1'24.

</details>

<details>

<summary>Can I create a static payment link which can be used across users?</summary>

No, at the moment we do not support creation of static payment links ([request for feature](https://github.com/juspay/hyperswitch/discussions/new?category=ideas-feature-requests))

</details>

<details>

<summary>How long is the Payment link valid for?</summary>

The payment link is valid for 15 minutes by default. However you can increase the validity to up to 3-months (7890000) by passing the time in seconds in `session_expiry` in the create payment link call.

</details>

<details>

<summary>How can I send Payment links via Emails?</summary>

Hyperswitch supports generation of the payment link. We are not integrated with any email servers. You'll need to have a mail server integration at your end and ingest the payment links to the emails being sent.

</details>

### Next step

{% content-ref url="/pages/4SfV3RulRTFy5St1WfkO" %}
[Configurations](/integration-guide/payment-suite/payment-method-card/payment-links/configurations)
{% endcontent-ref %}


# Configurations

Configure Payment Links UI

> **Note:** Payment Links can currently only be configured via APIs. Configuration through the Juspay Hyperswitch dashboard is under development, and this section will be updated once it is available.

### Available configurations

#### UI configurations

Payment link UI can be configured at a business profile level and the same configuration will be used when payment links are created for that profile. This UI can be configured during payment links creation as well, doing this overrides any configuration that was set in the business profile.

```
{
    theme: String, /// Primary color for the payment link
    logo: String, /// Logo displayed in the details section
    seller_name: String, /// Merchant's name in the details section
    transaction_details: Vec<PaymentLinkTransactionDetails>, /// Dynamic details related to merchant to be rendered in details section
    background_image: PaymentLinkBackgroundImageConfig, /// Configurations for the background image for details section
    details_layout: api_enums::PaymentLinkDetailsLayout, /// Custom layout for details section
    sdk_layout: String, /// Custom layout for the payment widget
    display_sdk_only: bool, /// Display only the payment widget
    enabled_saved_payment_method: bool, /// Render option to save the payment method for payment widget (works only in secure payment links)
    hide_card_nickname_field: bool, /// Hide card nickname field in payment widget
    show_card_form_by_default: bool, /// Show card form by default in payment widget
    payment_button_text: String, /// Custom text to be rendered on the SDK pay button
}
```

#### Primary color

The primary color of the payment link UI can be set using the `theme` field in the configuration. This color is represented as a hex value.

Example: **#2167AE**

<figure><img src="/files/U5y6OWLCI2yDWcWaXdhf" alt=""><figcaption><p>Primary theme</p></figcaption></figure>

#### Merchant logo

You can display a custom logo in the details section of the payment links by providing a URL.

Example: <https://hyperswitch.io/favicon.ico>

<figure><img src="/files/9UEuPujWmeLTQyC9RWyV" alt=""><figcaption><p>Primary theme</p></figcaption></figure>

#### Merchant name

Customize the display name shown in the details section of the payment links.

Example: **Juspay Hyperswitch Inc.**

<figure><img src="/files/9UEuPujWmeLTQyC9RWyV" alt=""><figcaption><p>Custom seller name</p></figcaption></figure>

#### Dynamic details

Include a list of key-value pairs in the details section of payment links. This list can be customized with optional configurations for each entry.

> **Note:** The list is displayed in the specified order. Use the position attribute to control the sequence of entries.

Example:

```
[
    {
        "key": "Business Country",
        "value": "Germany" 
    },
    {
        "key": "Policy Number",
        "value": "938478327648",
        "ui_configuration": {
            "is_key_bold": false,
            "is_value_bold": false,
            "position": 2
        }
    },
    {
        "key": "Product Name",
        "value": "Life Insurance Elite"
    }
]
```

<figure><img src="/files/11hW7UUVgPavl83WiIZQ" alt=""><figcaption><p>Dynamic details</p></figcaption></figure>

#### Background image

Customize the details section with a background image.

Example:

```
{
  "url": "https://img.freepik.com/free-photo/abstract-blue-geometric-shapes-background_24972-1841.jpg",
  "position": "bottom",
  "size": "cover"
}
```

The url specifies the image source, while position and size define its placement and scaling.

For available options, refer to the API reference [**here**](https://api-reference.hyperswitch.io/v1/payments/payments--create#body-payment-link-config-background-image).

<figure><img src="/files/O20Pz09mraeYHOLy6zgo" alt=""><figcaption><p>Background image</p></figcaption></figure>

#### Details section layout

Choose a layout for the details section of the payment links.

<figure><img src="/files/orMNrIEW0onnXOoT55IK" alt=""><figcaption><p>Default layout</p></figcaption></figure>

<figure><img src="/files/rJULJtSqgpldfifM2PD9" alt=""><figcaption><p>Layout 2</p></figcaption></figure>

Please reach out to our [**Support**](https://join.slack.com/t/hyperswitch-io/shared_invite/zt-2wpd0of0y-j61LQxcOsUEAeNMgFnSmxg) for adding any custom layouts needed for this.

#### SDK layout

Configure layout for the payment widget of the payment links. For a list of available options, refer to this section - [**SDK layouts**](https://docs.hyperswitch.io/integration-guide/payment-suite/payment-method-card/payment-links/pages/wh9FmgOtGk5Wc1Wa41z3#id-1.-layouts).

<figure><img src="/files/pjqYocUolzCbtYj31aCP" alt=""><figcaption><p>Accordion layout</p></figcaption></figure>

#### Render only payment widget

Set a boolean value to render only the payment widget in the payment links. Defaults to false.

<figure><img src="/files/6UTuwabOemTxa6A2dU20" alt=""><figcaption><p>Render only the payment widget</p></figcaption></figure>

#### Saved payment methods

Enable rendering of saved payment methods and allow customers to save new ones in the payment widget. This is available only for secure payment links.

<figure><img src="/files/RoNeiDnB3ZOsLSbwyZ5u" alt=""><figcaption><p>Save payment method checkbox</p></figcaption></figure>

<figure><img src="/files/mgPqnZro9rTSnHtVcMgu" alt=""><figcaption><p>Saved payment methods</p></figcaption></figure>

#### Hide card nickname input

Toggle the visibility of the card nickname input field in the payment widget.

<figure><img src="/files/uIZpjsXiwsPb3Oy9s5k6" alt=""><figcaption><p>Hidden card nickname field when card is requested to be saved</p></figcaption></figure>

<figure><img src="/files/URxkyWackX8RldAFIpsH" alt=""><figcaption><p>Visible card nickname field when card is requested to be saved</p></figcaption></figure>

#### Show card form by default

Set a boolean value to control the default form rendered in the payment widget. Enabling this shows the card payment form by default when a payment link is opened.

#### Payment button text

Customize the text displayed on the "Pay Now" button in the payment widget.

<figure><img src="/files/EGeJYkKU0j4ST4SMEzNA" alt=""><figcaption><p>Custom text for payment widget's button</p></figcaption></figure>

#### Other configurations

These configurations can only be made at business profile level and cannot be overridden during payment links creation.

```
{
    domain_name: String, /// Custom domain name to be used for hosting the link
    business_specific_configs: HashMap<String, PaymentLinkConfigRequest>, /// List of UI configs for multi theme setup
    allowed_domains: HashSet<String>, /// A list of allowed domains (glob patterns) where secure links can be embedded in
    branding_visibility: bool, /// Toggle for Juspay Hyperswitch branding visibility
}
```

#### Domain name

A custom domain for hosting payment links.

> **Note:** custom domains must be enabled before setting the custom domain name. Refer to this section for setting up custom domain names - [custom domain name for payment links](/integration-guide/payment-suite/payment-method-card/payment-links/setup-custom-domain).

#### Multiple style IDs

This is for configuring multiple styles. This is a key value pair where key represents the style ID and value is the UI configurations which were mentioned above.

{% hint style="info" %}
For comprehensive guidance on Style IDs, text consistency best practices, and multi-brand customization strategies, see the [Theme configurations Guide](/integration-guide/payment-suite/payment-method-card/payment-links/theme-configurations-guide).
{% endhint %}

Example:

```
{
    "style1": {
        "theme": "#3B845E",
        "logo": "https://hyperswitch.io/favicon.ico",
        "seller_name": "Juspay Hyperswitch Inc.",
        "display_sdk_only": true
    },
    "style2": {
        "theme": "#B202FF",
        "logo": "https://i.pinimg.com/736x/4d/83/5c/4d835ca8aafbbb15f84d07d926fda473.jpg",
        "seller_name": "Shopping Store",
        "enabled_saved_payment_method": true
    }
}
```

Style IDs are used during payment link creation, which can be specified using `payment_link_config_id` in the create request.

#### Allowed domains

This is a list of trusted domains where payment links can be embedded in an iframe. This is used only for secure payment links. More info on secure links [here](/integration-guide/payment-suite/payment-method-card/payment-links/secure-payment-links).

Example: `["localhost:5500", "my.custom.domain.com"]`

#### Branding visibility

A boolean value for toggling the visibility of Juspay Hyperswitch branding in the payment links.

<figure><img src="/files/FNnxX9dOiLHMLygsFRcH" alt=""><figcaption><p>Visible branding (default behaviour)</p></figcaption></figure>

<figure><img src="/files/YLWZX15LBSKIAquSxSUU" alt=""><figcaption><p>Hidden branding</p></figcaption></figure>

### Configure Payment links in business profile

Use the API to configure payment link settings at the business profile level. These settings are automatically applied to any payment link created for the associated profile.

Refer to API reference for updating business profile [here](https://api-reference.hyperswitch.io/v1/business-profile/business-profile--update#response-payment-link-config).

```
curl --location '{{BASE_URL}}/account/{{MERCHANT_ID}}/business_profile/{{PROFILE_ID}}' \
    --header 'Content-Type: application/json' \
    --header 'api-key: {{ADMIN_API_KEY}}' \
    '{
        "payment_link_config": {
            "theme": "#4E6ADD",
            "logo": "https://hyperswitch.io/favicon.ico",
            "seller_name": "Juspay Hyperswitch Inc.",
            "sdk_layout": "accordion",
            "display_sdk_only": true,
            "enabled_saved_payment_method": true,
            "hide_card_nickname_field": true,
            "show_card_form_by_default": true,
            "payment_button_text": "Proceed to Payment!",
            "transaction_details": [
                {
                    "key": "Policy Number",
                    "value": "297472368473924",
                    "ui_configuration": {
                        "position": 5,
                        "is_key_bold": true,
                        "is_value_bold": true
                    }
                }
            ],
            "business_specific_configs": {
                "style1": {
                    "theme": "#3B845E",
                    "logo": "https://hyperswitch.io/favicon.ico",
                    "seller_name": "Juspay Hyperswitch Inc.",
                    "display_sdk_only": true
                },
                "style2": {
                    "theme": "#B202FF",
                    "logo": "https://i.pinimg.com/736x/4d/83/5c/4d835ca8aafbbb15f84d07d926fda473.jpg",
                    "seller_name": "Shopping Store",
                    "enabled_saved_payment_method": true
                }
            },
            "allowed_domains": [
                "localhost:5500"
            ],
            "domain_name": "my.custom.domain.com",
            "branding_visibility": false
        }
    }'
```

### List of defaults for the payment link UI config

```
{
    theme: "#212E46",
    logo: "https://live.hyperswitch.io/payment-link-assets/Merchant_placeholder.png",
    seller_name: "merchant_name", /// merchant name configured during account creation with Juspay Hyperswitch,
    transaction_details: null,
    background_image: null,
    details_layout: "layout1",
    sdk_layout: "tabs",
    display_sdk_only: false,
    enabled_saved_payment_method: false,
    hide_card_nickname_field: false,
    show_card_form_by_default: true,
    payment_button_text: "Pay Now", /// This text is available in the requested locale
}
```

### Next step:

{% content-ref url="/pages/JYEQbxeEn1Fmf5LhoiJI" %}
[Create Payment Links](/integration-guide/payment-suite/payment-method-card/payment-links/create-payment-links)
{% endcontent-ref %}


# Theme configurations Guide

Payment Links & Theme Customization Guide

Juspay Hyperswitch payment links use Style IDs as design templates, allowing you to create different themes for different purposes - separate looks for your premium brand, holiday sales, or regional markets.

**What you can customize in each theme:**

* Your brand's visual identity (colors, logos, backgrounds, button styles)
* Custom messaging and terms & conditions
* Display preferences (how forms behave)
* Language preferences (we support 19+ languages including English, Hebrew, Arabic, Japanese, German, Spanish, Chinese, and more!)

{% hint style="info" %}
**Important:** Custom terms and conditions can only be configured when using a custom domain for your payment links. By default, payment links are hosted on the Hyperswitch domain. To use custom domains and unlock the ability to set custom terms and conditions, please refer to our [Setup Custom Domain](/integration-guide/payment-suite/payment-method-card/payment-links/setup-custom-domain) guide.
{% endhint %}

**How it works:** When creating a payment link, simply specify which style ID you want to use (via the `payment_link_config_id` parameter), and your customers will see that themed experience.

**Examples of Style IDs you might create:**

* `brand-default` - Your main brand theme
* `brand-premium` - Elevated experience for premium customers
* `holiday-2024` - Special theme for seasonal promotions

### 2. Configuration Hierarchy & Cascading

Payment link configurations work in a flexible, cascading manner that gives you control at multiple levels:

**Three levels of configuration:**

1. **Default Style ID** - Set at the business profile level
   * Applied to all payment links by default
   * Your baseline theme and settings
2. **Named Style IDs** - Also configured at business profile level
   * Create multiple pre-defined themes (e.g., `premium`, `holiday-2024`, `regional-eu`)
   * Reference by name when creating payment links
3. **API configuration which overrides** - Applied during payment link creation
   * Override any configuration for maximum granular control
   * Perfect for one-off customizations or special cases

**How cascading works:**

```
Default Style ID
    ↓
Named Style ID (if specified in payment link creation)
    ↓
API config overrides (if provided during creation)
    ↓
Final Payment Link Appearance
```

**Example workflow:**

1. Set your default theme at business profile level with your standard brand colors
2. Create a `holiday-sale` style ID with special promotional colors
3. When creating a payment link:
   * Use default: Don't specify any `payment_link_config_id` → gets default theme
   * Use named style: Specify `payment_link_config_id: "holiday-sale"` → gets holiday theme
   * One-off customization: Specify `payment_link_config_id: "holiday-sale"` AND provide API config overrides → gets holiday theme with your custom tweaks

This cascading approach means you can maintain consistency while having flexibility for special cases!

### 3. Smart Text Handling

**The system works intelligently by default:**

Out of the box, the payment link automatically:

* Adapts text based on the purpose of the payment link (payment, authorization, or payment method storage)
* Changes button text to match the transaction type
* Translates everything into your customer's language automatically (across 19+ languages!)

**Important consideration when customizing text:**

If you decide to write your own custom text for terms and conditions, here's what changes:

* 💡 The system will use your exact text across all scenarios
* 🌍 Automatic translations stop working - you'll need to provide translations for each language you support
* 📝 Automatic text inference is lost since a single text is configured for all transaction types

**If you do customize text, here's a pro tip:**

Write in a way that works for any scenario your customers might encounter:

* ❌ **Don't say:** "By clicking Pay Now, you authorize..." (too specific - button might say something different!)
* ✅ **Instead say:** "By submitting your payment information, you authorize..."
* ✅ **Or even better:** "By completing this form, you authorize..."

**Universal example that works everywhere:**

```
"By submitting your payment information, you authorize [Your Business Name] to 
charge your payment method or store your payment details as applicable."
```

This works whether your customer is paying now, setting up a subscription, or just saving their card!

### 4. Choosing Your Approach

You have two ways to set up your payment link themes:

**Option A: Keep It Simple**

* Use one universal theme with messaging that works for everything
* Easier to manage and maintain
* Consistent brand experience for all customers
* Recommended for streamlined operations

**Option B: Get Specific for Each Flow**

* Create different themes for different purposes:
  * `payment-flow-theme` - For regular purchases
  * `authorization-flow-theme` - For payment verification
  * `storage-flow-theme` - For saving payment methods
* Use precise messaging for each scenario (like "By clicking 'Pay Now'..." for actual payments)
* When creating a payment link, choose which theme fits that transaction
* **What to know:** More control and precision, but more themes to keep updated

**When specialized themes make sense:**

* You want different experiences for different flows (like a simpler look for quick payments vs detailed for subscriptions)
* You're optimizing conversion rates and want to test different approaches
* You have the resources to maintain multiple themes

### 5. Real-World Use Cases

**Running multiple brands?** Create a style ID for each brand (like `brand-a-default`, `brand-b-default`). When you create a payment link, just specify which brand's theme to use. Each brand keeps its own look and feel!

**Operating in different regions?** Set up region-specific themes (`us-theme`, `eu-theme`, `apac-theme`) with appropriate languages, currency displays, and localized messaging. Route your customers to the right theme based on where they are.

**Planning a seasonal promotion?** Create a special campaign theme (`holiday-2024`, `summer-sale`) that you can easily turn on for promotional periods and turn off when the campaign ends.

### 6. Handling Different Transaction Types

Payment links support three main transaction types. Here's the recommended messaging for each:

[**0 amount authorizations**](/integration-guide/payment-suite/payments/authorizations/zero-amount-authorization-1) **(doing 0 amount auth (CIT) for future MITs):**

Universal messaging that works for this flow:

```
"By submitting your payment information, you authorize [Your Business Name] to 
charge your payment method or store your payment details as applicable."
```

**Manual captures:**

Authorization happens first, capture occurs later. Use messaging that acknowledges this two-step process:

```
"By submitting your payment information, you authorize [Your Business Name] to 
reserve and later capture payment from your payment method."
```

**Normal payments (immediate capture):**

Authorization and capture happen together. Use straightforward messaging about the immediate charge:

```
"By submitting your payment information, you authorize [Your Business Name] to 
charge your payment method."
```

**Saving payment methods / Subscriptions:**

Cover both storing credentials and future charges with universal language:

```
"By submitting your payment information, you authorize [Your Business Name] to 
charge your payment method or store your payment details as applicable."
```


# Create Payment Links

Create Payment Links

Payment links are created using [Payments Create](https://api-reference.hyperswitch.io/v1/payments/payments--create) API. `payment_link` field should be sent as true in the request. Payment links cannot be confirmed during creation, hence `confirm` cannot be true.

Each field in the request uses a fallback logic. Below is the order of preference -

* Config sent during payment link creation
* Config set for the business profile
* Default values for payment link config

Refer to [this](https://github.com/juspay/hyperswitch-docs/tree/main/integration-guide/payment-experience/payment-links/configurations.md#list-of-defaults-for-the-payment-link-ui-config) section for a default UI for payment links.

### Create Payment link using business profile config

Creating a payment link uses the UI config set for the given profile in the request.

```
curl --location '{{BASE_URL}}/payments' \
    --header 'Content-Type: application/json' \
    --header 'api-key: {{API_KEY}}' \
    '{
        "amount": 100,
        "currency": "USD",
        "payment_link": true,
        "profile_id": "pro_YXlbYtgiANENrZgxdL8Q"
    }'
```

### Configure UI during Payment link creation

You can set payment link's UI during payment link creation.

```
curl --location '{{BASE_URL}}/payments' \
    --header 'Content-Type: application/json' \
    --header 'api-key: {{API_KEY}}' \
    '{
        "amount": 100,
        "currency": "USD",
        "payment_link": true,
        "profile_id": "pro_YXlbYtgiANENrZgxdL8Q",
        "payment_link_config": {
            "theme": "#4E6ADD",
            "logo": "https://hyperswitch.io/favicon.ico",
            "seller_name": "Juspay Hyperswitch Inc.",
            "sdk_layout": "accordion",
            "display_sdk_only": true,
            "enabled_saved_payment_method": true,
            "hide_card_nickname_field": true,
            "show_card_form_by_default": true,
            "payment_button_text": "Proceed to Payment!",
            "transaction_details": [
                {
                    "key": "Policy Number",
                    "value": "297472368473924",
                    "ui_configuration": {
                        "position": 5,
                        "is_key_bold": true,
                        "is_value_bold": true
                    }
                }
            ]
        }
    }'
```

### For using a specific style ID

If you've set multiple payment link configs in the profile, the style ID can be sent in `payment_link_config_id` during payment link creation.

```
curl --location '{{BASE_URL}}/payments' \
    --header 'Content-Type: application/json' \
    --header 'api-key: {{API_KEY}}' \
    '{
        "amount": 100,
        "currency": "USD",
        "payment_link": true,
        "profile_id": "pro_YXlbYtgiANENrZgxdL8Q",
        "payment_link_config_id": "style1"
    }'
```

### Next step:

{% content-ref url="/pages/S0wbXQZU6nSWa80JcAfv" %}
[Secure Payment Links](/integration-guide/payment-suite/payment-method-card/payment-links/secure-payment-links)
{% endcontent-ref %}


# Secure Payment Links

Learn how to configure and use secure payment links embedded within iframes of trusted domains for safe payment method storage.

Juspay Hyperswitch secure payment links are those embedded within the iframe of a trusted domain. These links cannot be directly opened in a browser tab and are designed to provide a safe environment for users to view and save their payment methods.

### Using Secure Payment Links

To use secure payment links, you need to configure a list of trusted domains in the business profile under the `allowed_domains` field. Once set up, any payment link you create will include two URLs:

1. An open link for direct browser access.
2. A secure link intended for embedding in an iframe.

The domain of the parent webpage embedding the secure link must match one of the domains listed in `allowed_domains`.

**Steps for using secure payment links**

**1. Configure `allowed_domains` in business profile**

Set up a trusted domain, such as `localhost:5500`, by updating the business profile configuration.

```
curl --location '{{BASE_URL}}/account/{{MERCHANT_ID}}/business_profile/{{PROFILE_ID}}' \
    --header 'Content-Type: application/json' \
    --header 'api-key: {{ADMIN_API_KEY}}' \
    '{
        "payment_link_config": {
            "allowed_domains": [
                "localhost:5500"
            ]
        }
    }'
```

**2. Create payment links**

Use the following API request to create payment links, which will return both the open and secure links.

```
curl --location '{{BASE_URL}}/payments' \
    --header 'Content-Type: application/json' \
    --header 'api-key: {{API_KEY}}' \
    '{
        "amount": 100,
        "currency": "USD",
        "payment_link": true,
        "profile_id": "pro_YXlbYtgiANENrZgxdL8Q"
    }'
```

The response includes the following fields:

```
{
  ...

  "payment_link": {
    "link": "http://localhost:8080/payment_link/merchant_1734676749/pay_Dw4CBoUWGGkvSXcfz1Mu?locale=en",
    "secure_link": "http://localhost:8080/payment_link/s/merchant_1734676749/pay_Dw4CBoUWGGkvSXcfz1Mu?locale=en",
    "payment_link_id": "plink_lF9deXMRrdIEs1drMVhF"
  },

  ...
}
```

**3. Embedding secure payment links in an iframe**

To embed a secure payment link, include it in an iframe within your HTML:

```
<html>
  <head>
    <style>
      html,
      body {
        margin: 0;
        height: 100vh;
        width: 100vw;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: bisque;
      }
      iframe {
        border-radius: 4px;
        height: 80vh;
        width: 80vw;
      }
    </style>
  </head>
  <body>
    <iframe
      src="http://localhost:8080/payment_link/s/merchant_1734676749/pay_Dw4CBoUWGGkvSXcfz1Mu?locale=en"
      frameborder="0"
    ></iframe>
  </body>
</html>
```

### Next Steps

{% content-ref url="/pages/SU838yh962hoMG7D47E6" %}
[Setup Custom Domain](/integration-guide/payment-suite/payment-method-card/payment-links/setup-custom-domain)
{% endcontent-ref %}


# Setup Custom Domain

Learn how to configure custom domains for payment links with DNS records, CNAME, and TXT verification for secure payment processing.

A custom domain name can be used for payment links with Juspay Hyperswitch. This is your own domain name which is configured at our side. For doing this, contact us and we will get it configured and give you a TLS certificate.

### How to Setup Custom Domain Within Your Cloud

* Identify your DNS provider

> First, determine which service is handling your DNS records. This will guide you to the correct platform where you can log in and set up the new records.

> Your DNS provider may be the same as your domain registrar, but it's possible they are different entities.

> If you're unsure about your DNS provider, you can search for your domain's nameservers using the following command, replacing "hyperswitch.com" with your own domain:

```shell
$ nslookup -querytype=NS hyperswitch.com
```

> You'll see a list of name servers for your domain in the output.

* Create required DNS records

> In this segment, you'll generate the necessary DNS records to link your domain. Follow the following steps to enable the same.

Step 1: Sign into your DNS provider

> DNS providers offer a control panel where you can log in to manage your DNS settings. Locate your provider's control panel page and sign in.

Step 2: Locate the page to manage the DNS for your domain

> Now that you've successfully logged in, locate the section within your provider's control panel where you can manage the DNS records for your domain.

Step 3: Create CNAME record

> In your DNS control panel, create a new record that associates your chosen subdomain with 'hyperswitch payment link'. Your DNS provider will typically prompt you to specify the record type, name, value, and TTL (Time To Live) or expiration when adding a new record.

Enter the following values and save the new DNS record.

| FIELD      | INSTRUCTIONS                                                        | DESCRIPTION                                                                                                                                                                                                                           |
| ---------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Type       | Select `CNAME` from the dropdown                                    | What kind of DNS record this is.                                                                                                                                                                                                      |
| Name       | if your custom domain is `paymentlink.xyz.com`, enter `paymentlink` | For CNAME records, this field is the first part of your subdomain (the part leading up to the first period).                                                                                                                          |
| Value      | Enter `sandbox.hyperswitch.io`                                      | This is what the new subdomain record points to–in this case, Hyperswitch. Some providers may expect a trailing period (.) after the CNAME value. Make sure to verify that your CNAME value matches the format your provider expects. |
| TTL/Expiry | Enter `300`                                                         | An expiration of 5 minutes (300 seconds) is OK. Your DNS provider might not allow you to change the TTL value. If this field is missing or you can't change it, it's safe to ignore this part of the configuration.                   |

Step 4: Create your TXT record

> Navigate to your DNS control panel and proceed to add a new TXT record.

> > This TXT record is essential for domain ownership verification. It's a necessary step to obtain TLS certificates for your domain, ensuring secure payment processing.

> Enter these values and save the new DNS record:

| FIELD      | INSTRUCTIONS                                                                        | DESCRIPTION                                                                                                                                                                                                         |
| ---------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Type       | Select `TXT` from the dropdown                                                      | What kind of DNS record this is.                                                                                                                                                                                    |
| Name       | If your custom domain is `paymentlink.xyz.com`, enter `_acme-challenge.paymentlink` | For TXT records, this field is the subdomain portion of your domain.                                                                                                                                                |
| Value      | Copy the TXT value that is given by us and paste                                    | This is a long, unique string used for domain verification                                                                                                                                                          |
| TTL/Expiry | Enter `300`                                                                         | An expiration of 5 minutes (300 seconds) is OK. Your DNS provider might not allow you to change the TTL value. If this field is missing or you can't change it, it's safe to ignore this part of the configuration. |

Step 5: Verify your CNAME record setup

> After you save your DNS record, verify that it has the correct values.

> > Please allow up to 10 minutes for your DNS provider to update its name servers. Replace "pay.xyz.com" with your custom domain in the command below, and then run it in your terminal:

```shell
$ nslookup -querytype=CNAME paymentlink.xyz.com
```

You should get an output like this:

```shell
<your subdomain> 	canonical name = sandbox.hyperswitch.io.
```

Once you observe the output, proceed to the next step.

Step 6: Verify your TXT record

> After you save your DNS record, verify that it has the correct values.

> > Please allow up to 10 minutes for your DNS provider to update its nameservers. Replace pay.xyz.com with your custom domain in the following command and run it from your terminal:

```shell
$ nslookup -querytype=TXT _acme-challenge.paymentlink
```

You should get an output like this:

```shell
_acme-challenge.<your domain>   text = "<your unique TXT record value>"
```

> If you don't observe your unique TXT record value in the output, please wait a little longer and then attempt running the command again.

> Upon completing this step, your DNS records will be configured.

* Now that you've established and verified your DNS records, Hyperswitch proceeds to verify the connection and provision your domain on our end. You will receive an email from us once the domain is ready for you to enable it.

### How to Use Wallets Like Apple Pay & Google Pay in Payment Links

To enable wallet flows such as Apple Pay or Google Pay for payment links, domain validation from Apple or Google is required respectively to obtain session tokens. This validation can be facilitated by utilizing the custom domain feature available for payment links, which can be configured at the business profile level.

After you have setup custom domain in your cloud, you need to get respective Google Pay, Apple Pay certificate for your new domain, and register the same in our dashboard.


# Payment Experience

Learn about integration options for accepting payments online.

Optimize your payments integration and unlock higher revenue with the Optimized Checkout Suite by Juspay Hyperswitch. It includes customizable payment UIs, dynamic payment method presentation, and one-click checkout. Get started by choosing the integration that fits your business requirements

{% hint style="info" %}
[Explore the demo](https://hyperswitch-demo-store.netlify.app/)
{% endhint %}

#### Learn which payments integration fits your business <a href="#learn-which-payments-integration-fits-your-business" id="learn-which-payments-integration-fits-your-business"></a>

Use Hyperswitch to accept payments for your business globally. The below variations allow you to learn about the different integration options available

[**Accept payments without code**](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment/payment-links)

Use payment links to accept payments without building any integration onto a website or an app.

[**Build a checkout**](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment/web)

Integrate the checkout in your website and [customize](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment/web/customization) it as per your requirements.

[**Build advanced integration**](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment/web/headless)

Use our headless SDK to have full control over your checkout while using the payment-related functionalities in a decoupled architecture.

[**Build an in-app integration**](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment/mobile)

Use our mobile SDK to accept payments in [Android](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment/mobile/android) or [iOS](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment/mobile/ios) apps.

[**Build an APM-only integration**](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment/enable-alternate-payment-method-widgets)

Use our Alternate Payment Method widget (APM widget) to power the global APMs in the unified format. This augments your existing checkout in a low code manner.

[**Build a Vault SDK integration**](https://sites.gitbook.com/preview/site_gbSsq/~/revisions/Bk4ZQ060dHFoocGBrSEZ/integration-guide/payment-experience/payment-method)

Use our Vault SDK to tokenize the card first and then proceed with payment using a vault token. The Vault SDK is flexible to work with [Hyperswitch unified payments API](https://api-reference.hyperswitch.io/v1/payments/payments--create) as well as the [Proxy or forwarding](https://api-reference.hyperswitch.io/v2/proxy/proxy-v1) API of Hyperswitch

#### Intelligent Payment Method Display & Experience

Our SDK intelligently displays payment methods based on device, geo, and merchant configuration:

<table data-view="cards"><thead><tr><th align="center"></th><th align="center"></th></tr></thead><tbody><tr><td align="center"><strong>Device-aware</strong></td><td align="center">Apple Pay and Google Pay are shown only on supported devices. The SDK auto-detects features like Touch ID / Face ID, no merchant logic needed.</td></tr><tr><td align="center"><strong>Geo-specific filtering</strong></td><td align="center">Methods like EPS, Giropay, or SEPA and features such as co-brand cards are shown only in supported regions, using device location or merchant provided locale and context.</td></tr><tr><td align="center"><strong>Config-based enable or disable</strong></td><td align="center">Payment methods, card scanning, and third-party SDKs (e.g., Klarna, Netcetera) are enabled via static or connector-based configuration.</td></tr><tr><td align="center"><strong>Dynamic ordering</strong></td><td align="center">Methods can be prioritized based on rules. Presenting users with their preferred payment methods boosts convenience and conversion rates.</td></tr><tr><td align="center"><strong>Dynamic Fields</strong></td><td align="center">Fields like cardholder name, billing/shipping address, email, and phone are dynamically rendered based on connector requirements.</td></tr><tr><td align="center"><strong>Cross-platform &#x26; multi-tenant</strong></td><td align="center">Unified SDK across iOS, Android, Flutter, and React Native. Works across SaaS and self-hosted setups.</td></tr><tr><td align="center"><strong>Full Control Over Design &#x26; Functionality</strong></td><td align="center">Customize both the appearance and behavior of the checkout experience.</td></tr><tr><td align="center"><strong>Advanced Security, No Redirection</strong></td><td align="center">Seamlessly integrate native 3DS and Click to Pay for secure, frictionless transactions.</td></tr><tr><td align="center"><strong>Session level overrides</strong></td><td align="center">All configurations with respect to payment method display, look-and-feel, and behavior can be overridden at session level.</td></tr></tbody></table>


# Pay-Then-Vault

Process one-time and recurring payments with multiple flow patterns

Juspay Hyperswitch provides flexible payment processing with multiple flow patterns to accommodate different business needs. The system supports one-time payments, saved payment methods, and recurring billing through a comprehensive API design.

{% hint style="info" %}
**Integration Path**

**Client-Side SDK Payments**

Refer to Payments (Cards) section if your flow requires the SDK to initiate payments directly. In this model, the SDK handles the payment trigger and communicates downstream to the Hyperswitch server and your chosen Payment Service Providers (PSPs). This path is ideal for supporting dynamic, frontend-driven payment experiences.
{% endhint %}

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-5488973c66c60d28c0d7cde47c7a479455933c64%252Fimage%2520%28167%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=913fa83b\&sv=2)

#### One-Time Payment Patterns <a href="#one-time-payment-patterns" id="one-time-payment-patterns"></a>

**1. Instant Payment (Automatic Capture)**

**Use Case:** Simple, immediate payment processing

**Endpoint:** `POST /payments`

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-e61ebf7b2846582278b74f9f2ab31ce1f21d3195%252Fimage%2520%28168%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=269ebedf\&sv=2)

**Required Fields:**

* `confirm: true`
* `capture_method: "automatic"`
* `payment_method`

**Final Status:** `succeeded`

**2. Two-Step Manual Capture**

**Use Case:** Deferred capture (e.g., ship before charging)

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-67e537f14bfd445467c8f272b90655f5dd9698fb%252Fimage%2520%28170%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=8f9f7e07\&sv=2)

**Flow:**

1. **Authorize:** `POST /payments` with `capture_method: "manual"`
2. **Status:** `requires_capture`
3. **Capture:** `POST /payments/{payment_id}/capture`
4. **Final Status:** `succeeded`

Read more - [here](https://docs.hyperswitch.io/~/revisions/2M8ySHqN3pH3rctBK2zj/about-hyperswitch/payment-suite-1/payments-cards/manual-capture)

**3. Fully Decoupled Flow**

**Use Case:** Complex checkout journeys with multiple modification steps. Useful in headless checkout or B2B portals where data is filled progressively.

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-a6c4453837660d02246bd75a346253e5c312c546%252Fimage%2520%28171%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=c1396971\&sv=2)

**Endpoints:**

* **Create:** `POST /payments`
* **Update:** `POST /payments/{payment_id}`
* **Confirm:** `POST /payments/{payment_id}/confirm`
* **Capture:** `POST /payments/{payment_id}/capture` (if manual)

**4. 3D Secure Authentication Flow**

**Use Case:** Enhanced security with customer authentication

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-c7fa93ddd123c9c4b969bb39f439f14df454a190%252Fimage%2520%28172%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=8b16bef6\&sv=2)

**Additional Fields:**

* `authentication_type: "three_ds"`

**Status Progression:** `processing` → `requires_customer_action` → `succeeded`

Read more - [link](https://docs.hyperswitch.io/~/revisions/9QlGypixZFcbkq8oGjaF/explore-hyperswitch/workflows/3ds-decision-manager)

#### Recurring payments and Payment storage <a href="#recurring-payments-and-payment-storage" id="recurring-payments-and-payment-storage"></a>

**1. Saving Payment Methods**

**During Payment Creation:**

* Add `setup_future_usage: "off_session"` or `"on_session"`
* Include `customer_id`
* **Result:** `payment_method_id` returned on success

**Understanding `setup_future_usage`:**

* **`on_session`**: Use when the customer is actively present during the transaction. This is typical for scenarios like saving card details for faster checkouts in subsequent sessions where the customer will still be present to initiate the payment (e.g., card vaulting for e-commerce sites).
* **`off_session`**: Use when you intend to charge the customer later without their active involvement at the time of charge. This is suitable for subscriptions, recurring billing, or merchant-initiated transactions (MITs) where the customer has pre-authorized future charges.

**2. Using Saved Payment Methods**

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-d82f0cc65ff2e569bb82711ec5ce86123a78542d%252Fimage%2520%28173%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=6698b515\&sv=2)

**Steps:**

1. **Initiate:** Create payment with `customer_id`
2. **List:** Get saved cards via `GET /customers/payment_methods`
3. **Confirm:** Use selected `payment_token` in confirm call

**PCI Compliance and `payment_method_id`**

Storing `payment_method_id` (which is a token representing the actual payment instrument, which could be a payment token, network token, or payment processor token) significantly reduces your PCI DSS scope. Hyperswitch securely stores the sensitive card details and provides you with this token. While you still need to ensure your systems handle `payment_method_id` and related customer data securely, you avoid the complexities of storing raw card numbers. Always consult with a PCI QSA to understand your specific compliance obligations.

#### Recurring Payment Flows <a href="#recurring-payment-flows" id="recurring-payment-flows"></a>

**3. Customer-Initiated Transaction (CIT) Setup**

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-abd9b3e7c0c1d24d61e4a99cd7586670841e1f3c%252Fimage%2520%28174%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=b6b295b\&sv=2)

Read more - [link](https://docs.hyperswitch.io/~/revisions/j00Urtz9MpwPggJzRCsi/about-hyperswitch/payment-suite-1/payments-cards/recurring-payments)

**4. Merchant-Initiated Transaction (MIT) Execution**

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-cc0a650c7ce3f037c769bf94776a7c9dac0a08c9%252Fimage%2520%28175%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=844c48d4\&sv=2)

Read more - [link](https://docs.hyperswitch.io/~/revisions/j00Urtz9MpwPggJzRCsi/about-hyperswitch/payment-suite-1/payments-cards/recurring-payments)

#### Status Flow Summary <a href="#status-flow-summary" id="status-flow-summary"></a>

![](https://sites.gitbook.com/preview/site_gbSsq/~gitbook/image?url=https%3A%2F%2F1943537505-files.gitbook.io%2F%7E%2Ffiles%2Fv0%2Fb%2Fgitbook-x-prod.appspot.com%2Fo%2Fspaces%252Fkf7BGdsPkCw9nalhAIlE%252Fuploads%252Fgit-blob-d5398451bd689564978c796db3690c4dd3aae69a%252Fimage%2520%28179%29.png%3Falt%3Dmedia\&width=768\&dpr=3\&quality=100\&sign=e3226751\&sv=2)

#### Notes <a href="#notes" id="notes"></a>

* **Terminal States:** `succeeded`, `failed`, `cancelled`, `partially_captured` are terminal states requiring no further action
* **Capture Methods:** System supports `automatic` (funds captured immediately), `manual` (funds captured in a separate step), `manual_multiple` (funds captured in multiple partial amounts via separate steps), and `scheduled` (funds captured automatically at a future predefined time) capture methods.
* **Authentication:** 3DS authentication automatically resumes payment processing after customer completion
* **MIT Compliance:** Off-session recurring payments follow industry standards for merchant-initiated transactions

<br>


# Web

Integrate Juspay Hyperswitch unified checkout with your web app for a seamless payment experience

#### Global Checkout Experience

Juspay Hyperswitch Unified Checkout is an inclusive, consistent and blended payment experience optimized for the best conversion rates.

<table data-header-hidden><thead><tr><th data-type="image"></th><th></th></tr></thead><tbody><tr><td><a href="/files/AXMCQgXc2vMsBEsXcw5L">/files/AXMCQgXc2vMsBEsXcw5L</a></td><td><strong>Inclusive</strong><br>A variety of global payment methods including cards, buy now pay later and digital wallets are supported by the Unified Checkout, with adaptation to local preferences and ability to local language customization.</td></tr><tr><td><a href="/files/AXMCQgXc2vMsBEsXcw5L">/files/AXMCQgXc2vMsBEsXcw5L</a></td><td><strong>Consistent</strong><br>With a diverse set of payment methods supported, the Unified Checkout provides a singular consistent payment experience across platforms (web, android and ios) powered by smart payment forms, minimal redirections and intelligent retries.</td></tr><tr><td><a href="/files/Q3A2l8aZ4v4blbhV6KtA">/files/Q3A2l8aZ4v4blbhV6KtA</a></td><td><strong>Blended</strong><br>The Unified Checkout includes 40+ styling APIs, which could be tweaked to make the payment experience blend with your product. Your users will get a fully native and embedded payment experience within your app or website</td></tr></tbody></table>

#### Modify and Experiment

While the Unified Checkout is pre-optimized for maximum conversions, Hyperswitch does not restrict you to stick to a one-size-fits-all approach. Using Hyperswitch SDK APIs, you get complete control over modifying the payment experience by,

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td><strong>Prioritizing payment methods</strong><br>You can make an impact on the payment mix or conversion rates by prioritizing/ promoting specific payment methods for your customers.</td><td></td><td></td><td></td><td><a href="/files/Vo9U3DsiQaVJgEUJYe5C">/files/Vo9U3DsiQaVJgEUJYe5C</a></td></tr><tr><td><p><strong>Switching themes and layouts of checkout page</strong></p><p>The Unified Checkout comes with a wide range of pre-designed themes and layouts which you can choose from.</p></td><td></td><td></td><td></td><td><a href="/files/AgnVOivkJHZmZNrIuyUr">/files/AgnVOivkJHZmZNrIuyUr</a></td></tr></tbody></table>

#### Optimize

You can further optimize Unified Checkout web SDK by preloading all the resources that are needed by the iframe. By the time iframe is to be mounted (checkout button), everything that is required can be fetched from their server and stored in the disk cache.

* `<Elements/>` wrapper has to be used in the top-level of the merchants app, say web app has two pages eg: homepage and checkout page, the wrapper must be added in the homepage itself.
* `<Elements/>` has the required props to load our Hyperloader (script) which will
  1. Preload all the resources that are required by the SDK ie. files, svgs, icons, css, fonts etc.
  2. Prefetch the two main API calls and is ready with response

{% hint style="success" %}
**This will significantly decrease the SDK load time from \~10-15s (in slow 3G network) to just \~1-5ms.**
{% endhint %}


# React with REST API Integration

Integrate Hyperswitch SDK with React and REST API for web checkout

**Before following these steps, please configure your payment methods** [here](https://app.hyperswitch.io/dashboard/connectors). Use this guide to integrate `hyperswitch` SDK to your React app. You can also use this demo app as a reference with your Juspay Hyperswitch credentials to test the setup.

<details>

<summary><a href="https://github.com/PritishBudhiraja/hyperswitch-react-demo-app/archive/refs/heads/main.zip"><strong>Demo App</strong></a></summary>

You can use this demo app as a reference with your Hyperswitch credentials to test the setup.

</details>

#### 1. Setup the server

Follow the Server Setup section.

#### 2. Build checkout page on the client

**2.1 Install the** [**`hyper-js`**](https://www.npmjs.com/package/@juspay-tech/hyper-js) **and** [**`react-hyper-js`**](https://www.npmjs.com/package/@juspay-tech/react-hyper-js) **libraries**

Install the packages and import it into your code

```bash
npm install @juspay-tech/hyper-js
npm install @juspay-tech/react-hyper-js
```

**2.2 Add `hyper` to your React app**

Use `hyper-js` to ensure that you stay PCI compliant by sending payment details directly to Hyperswitch server.

```js
import React, { useState, useEffect } from "react";
import { loadHyper } from "@juspay-tech/hyper-js";
import { hyperElements } from "@juspay-tech/react-hyper-js";
```

**2.3 Load `hyper-js`**

Call `loadHyper` with your publishable API keys to configure the library. To get a publishable Key please find it [here](https://app.hyperswitch.io/developers).

```js
const hyperPromise = loadHyper("YOUR_PUBLISHABLE_KEY",{
    customBackendUrl: "YOUR_BACKEND_URL",
    //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
});
```

**2.4 Fetch the Payment and Initialise `hyperElements`**

Immediately make a request to the endpoint on your server to create a new Payment as soon as your checkout page loads. The clientSecret returned by your endpoint is used to complete the payment.

```js
useEffect(() => {
  // Create PaymentIntent as soon as the page loads
  fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ items: [{ id: "xl-tshirt" }], country: "US" }),
  })
    .then((res) => res.json())
    .then((data) => setClientSecret(data.clientSecret));
}, []);
```

**2.5 Initialise `HyperElements`**

Pass the promise from `loadHyper` to the `HyperElements` component. This allows the child components to access the Hyper service via the `HyperElements` parent component. Additionally, pass the client secret as an [options](https://hyperswitch.io/docs/sdkIntegrations/unifiedCheckoutWeb/customization) to the `HyperElements` component.

```js
<div className="App">
  {clientSecret && (
    <HyperElements options={options} hyper={hyperPromise}>
      <CheckoutForm />
    </HyperElements>
  )}
</div>
```

**2.6 Setup the state (optional)**

Initialize a state to keep track of payment, display errors and control the user interface.

```js
const [message, setMessage] = useState(null);
const [isLoading, setIsLoading] = useState(false);
```

**2.7 Store a reference to `Hyper`**

Access the `hyper-js` library in your CheckoutForm component by using the `useHyper()` and `useWidgets()` hooks. If you need to access Widgets via a class component, use the `WidgetsConsumer` instead. You can find the API for these methods here.

```js
const hyper = useHyper();
const widgets = useWidgets();
```

#### 3. Complete the checkout on the client

{% tabs %}
{% tab title="ExpressCheckout" %}
**Key Features of Hyperswitch's Express Checkout**

* Fast Performance: One-click payment at checkout enables a smooth and frictionless payment experience to customers.
* Multiple Payment Options: Supports ApplePay, PayPal, Klarna, and GooglePay, giving customers a variety of payment choices on top of the speed in checkout.
* Easy Integration: Our SDK can be easily integrated with web applications.

**Benefits of Hyperswitch's Express Checkout Feature**

* Better User Experience: One-click payment makes shopping easier, leading to more sales and fewer abandoned carts.
* Time Savings: Speeds up the checkout process, saving time for both customers and merchants.
* Great for Mobile: Optimized for mobile shopping with ApplePay, PayPal and GooglePay integration for quick purchases on smartphones.
* Collect billing and shipping details directly from ApplePay, Klarna, GooglePay, PayPal

**3.1 Add the ExpressCheckout**

> The Express Checkout Element gives you a single integration for accepting payments through one-click payment buttons. Supported payment methods include ApplePay, GooglePay and PayPal.

Add the `ExpressCheckout` to your Checkout. This embeds an iframe that displays configured payment method types supported by the browser available for the Payment, allowing your customer to select a payment method. The payment methods automatically collects the associated payment details for the selected payment method type.

Define paymentElementOptions:

```js
var expressCheckoutOptions = {
  wallets: {
    walletReturnUrl: "https://example.com/complete",
    //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
  },
};
```

```js
<ExpressCheckoutElement id="express-checkout" options={expressCheckoutOptions} />
```

{% endtab %}

{% tab title="UnifiedCheckout" %}
**3.1.A Add the UnifiedCheckout**

Add the `UnifiedCheckout` to your Checkout. This embeds an iframe with a dynamic form that displays configured payment method types available for the Payment, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.

(Optional) Define paymentElementOptions:

```js
var unifiedCheckoutOptions = {
  wallets: {
    walletReturnUrl: "https://example.com/complete",
    //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
  },
};
```

```js
<UnifiedCheckout id="unified-checkout" options={unifiedCheckoutOptions} />
```

**3.1.B Complete the payment and handle errors**

Call `confirmPayment()`, passing along the `UnifiedCheckout` and a return\_url to indicate where `hyper` should redirect the user after they complete the payment. For payments that require additional authentication, `hyper` redirects the customer to an authentication page depending on the payment method. After the customer completes the authentication process, they're redirected to the return\_url.

If there are any immediate errors (for example, your customer's card is declined), `hyper-js` returns an error. Show that error message to your customer so they can try again.

```js
const handleSubmit = async (e) => {
  setMessage("");
  //e.preventDefault();

  if (!hyper || !widgets) {
    return;
  }
  setIsLoading(true);

  const { error, status } = await hyper.confirmPayment({
    elements,
    confirmParams: {
      // Make sure to change this to your payment completion page
      return_url: "https://example.com/complete",
    },
    redirect: "always", // if you wish to redirect always, otherwise it is defaulted to "if_required"
  });

  if (error) {
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message);
    } else {
      if (error.message) {
        setMessage(error.message);
      } else {
        setMessage("An unexpected error occurred.");
      }
    }
  }
  if (status) {
    handlePaymentStatus(status); //handle payment status
  }
  setIsLoading(false);
};
```

<details>

<summary>Alternate Implementation: SDK handles the Confirm Button</summary>

For SDK to render the confirm button and handle the confirm payment, in paymentElementOptions, you can send:

```javascript
var unifiedCheckoutOptions = {
  ...,
  sdkHandleConfirmPayment: {
     handleConfirm: true,
     buttonText: "SDK Pay Now",
     confirmParams: {
       return_url: "https://example.com/complete",
     },
   },
};
```

1. **`handleConfirm (required)`** - A boolean value indicating whether the SDK should handle the confirmation of the payment.
2. **`confirmParams (required)`** - It's an object which takes return\_url. return\_url parameter specifies the URL where the user should be redirected after payment confirmation.
3. **`buttonText (optional)`** - The text to display on the payment button.\
   Default value: **Pay Now**

For customization, please follow the [`Customization docs`](https://docs.hyperswitch.io/hyperswitch-cloud/integration-guide/web/customization#id-5.-confirm-button).

</details>
{% endtab %}
{% endtabs %}

**3.2 Display payment status message**

When Hyperswitch redirects the customer to the `return_url`, the `payment_client_secret` query parameter is appended by hyper-js. Use this to retrieve the Payment to determine what to show to your customer.

```js
//Look for a parameter called `payment_intent_client_secret` in the url which gives a payment ID, which is then used to retrieve the status of the payment

const paymentID = new URLSearchParams(window.location.search).get(
  "payment_intent_client_secret"
);

if (!paymentID) {
  return;
}

hyper.retrievePaymentIntent(paymentID).then(({ paymentIntent }) => {
  switch (paymentIntent.status) {
    case "succeeded":
      setMessage("Payment succeeded!");
      break;
    case "processing":
      setMessage("Your payment is processing.");
      break;
    case "requires_payment_method":
      setMessage("Your payment was not successful, please try again.");
      break;
    default:
      setMessage("Something went wrong.");
      break;
  }
});
```

{% hint style="danger" %}
Please retrieve the payment status from the Hyperswitch backend to get the terminal status of the payment. Do not rely solely on the status returned by the SDK, as it may not always reflect the final state of the transaction.
{% endhint %}

**4. Elements Events**

Some events are emitted by payment elements, listening to those events is the only way to communicate with these elements. All events have a payload object with the type of the Element that emitted the event as an elementType property. Following events are emitted by payment elements.

* change
* ready
* focus
* blur

**4.1 Calling Elements events**

First create instance of widgets using `getElement` function. It will return `null` if no matching type is found.

```js
// Create instance of widgets
var paymentElement = widgets.getElement("payment");

// handle event
if (paymentElement) {
  // in place of "EVENT" use "change", "ready", "focus" etc.
  paymentElement.on("EVENT", callbackFn);
}
```

**4.2 "change" event**

The "change" event will be triggered when value changes in Payment element.

```js
paymentElement.on("change", function (event) {
  // YOUR CODE HERE
});
```

Callback function will be fired when the event will be triggered. When called it will be passed an event object with the following properties.

```js
{
  elementType: 'payment',   // The type of element that emitted this event.
  complete: false,          // If all required field are complete
  empty: false,             // if the value is empty.
  value: { type: "card" },  // current selected payment method like "card", "klarna" etc
}
```

**4.3 "ready" event**

The "ready" event will be triggered when payment element is fully rendered and can accept "focus" event calls.

Callback for ready event will be triggered with following event object

```js
{
  ready: boolean,   // true when payment element is fully rendered
}
```

**4.4 "focus", "blur" event**

Focus and blur event triggered when respective event will be triggered in payment element.

Callback for these event will be triggered with following event object.

```js
// Event object for focus event
{
  focus: boolean,   // true when focused on payment element
}

// Event object for blur event
{
  blur: boolean,
}
```

Congratulations! Now that you have integrated the Hyperswitch SDK on your app, you can customize the payment elements to blend with the rest of your app.

**5. Additional Callback Handling for Wallets Payment Process**

This document outlines the details and functionality of an optional callback and `onPaymentComplete` that can be provided by merchants during the payment process. These callbacks allow merchants to hook into the payment flow at key stages and handle specific actions or events before continuing the normal flow.

* **onPaymentButtonClick:** This callback is triggered immediately after the user clicks any wallet button.
* **onPaymentComplete:** This callback is triggered after the payment is completed, just before the SDK redirects to `walletReturnUrl` provided. It allows the merchant to handle actions post-payment. If not provided, the SDK's default flow will proceed.

{% hint style="warning" %}
**Redirection Handling:** The `onPaymentComplete` callback should handle redirection or any steps needed after payment, as the SDK no longer does this automatically. You must ensure to implement the necessary redirection logic.
{% endhint %}

{% hint style="info" %}
**Fallback:** If no callbacks are provided by the merchant, the SDK will continue with its default behaviour, including automatic redirection after payment completion.
{% endhint %}

{% hint style="danger" %}
The task within `onPaymentButtonClick` must be completed within 1 second. If an asynchronous callback is used, it must resolve within this time to avoid Apple Pay payment failures.
{% endhint %}

**Example Usage for React Integration**

```jsx
<PaymentElement
  id="payment-element"
  options={options}
  onPaymentButtonClick={() => {
    console.log("This is a SYNC CLICK");
    // Add any custom logic for when the payment button is clicked, such as logging or tracking
  }}
  onPaymentComplete={() => {
    console.log("OnPaymentComplete");
    // Add any custom post-payment logic here, such as redirection or displaying a success message
  }}
/>
```

#### Next step:


# HTML with REST API Integration

Integrate Hyperswitch SDK to your HTML Web App using REST API for a seamless payment experience

**Before following these steps, please configure your payment methods** [here](https://hyperswitch.io/docs/paymentMethods/cards). Use this guide to integrate `hyperswitch` SDK to your HTML app. You can also use this demo app as a reference with your Juspay Hyperswitch credentials to test the setup.

#### [<mark style="color:blue;">Demo App</mark>](https://github.com/PritishBudhiraja/hyperswitch-demo-app/archive/refs/heads/master.zip)

#### 1. Setup the server

Follow the Server Setup section.

#### 2. Build checkout page on the client

**2.1 Load HyperLoader**

Use `HyperLoader` to ensure PCI compliant means of accepting payment details from your customer and sending it directly to the Hyperswitch server. Always load `hyperLoader` from `https://beta.hyperswitch.io/v1/HyperLoader.js` to ensure compliance. Please refrain from including the script in a bundle or hosting it yourself.

```js
<script src="https://beta.hyperswitch.io/v1/HyperLoader.js"></script>
```

**2.2 Define the payment form**

{% hint style="info" %}
This step is recommended for the Unified Checkout for an enhanced user experience. In case you are integrating Express Checkout (mentioned later below), this step is not required.
{% endhint %}

Add one empty placeholder `div` to your checkout form for each Widget that you'll mount. `HyperLoader` inserts an iframe into each `div` to securely collect the customer's email address and payment information.

```js
<form id="payment-form">
  <div id="unified-checkout">
   <!--HyperLoader injects the Unified Checkout-->
  </div>
  <button id="submit">
    <div class="spinner hidden" id="spinner"></div>
    <span id="button-text">Pay now</span>
  </button>
  <div id="payment-message" class="hidden"></div>
</form>
```

**2.3 Initialize HyperLoader**

Initialize `HyperLoader` onto your app with your publishable key with the `Hyper` constructor. You'll use `HyperLoader` to create the Unified Checkout and complete the payment on the client. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

```js
const hyper = Hyper("YOUR_PUBLISHABLE_KEY",{
    customBackendUrl: "YOUR_BACKEND_URL",
    //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
});
```

{% tabs %}
{% tab title="UnifiedCheckout" %}
**2.4 Fetch the Payment and create the Unified Checkout**

Immediately make a request to the endpoint on your server to create a new Payment as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.

> Important: Make sure to never share your API key with your client application as this could potentially compromise your payment flow

Following this, create a `unifiedCheckout` and mount it to the placeholder `div` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the `Payment`, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.

```js
<script src="https://beta.hyperswitch.io/v1/HyperLoader.js"></script>;
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ items: [{ id: "xl-tshirt" }], country: "US" }),
  });
  const { clientSecret } = await response.json();

  const appearance = {
    theme: "midnight",
  };

  widgets = hyper.widgets({ appearance, clientSecret });

  const unifiedCheckoutOptions = {
    layout: "tabs",
    wallets: {
      walletReturnUrl: "https://example.com/complete",
      //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
    },
  };

  const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
  unifiedCheckout.mount("#unified-checkout");
}
```

{% endtab %}

{% tab title="ExpressCheckout" %}
**2.4 Fetch the Payment and create the Express Checkout**

> The Express Checkout Element gives you a single integration for accepting payments through one-click payment buttons. Supported payment methods include ApplePay, GooglePay and PayPal.

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to complete the payment.

> Important: Make sure to never share your API key with your client application as this could potentially compromise your payment flow

Create an `expressCheckout` and mount it to the placeholder `div` in your payment form. This embeds an iframe that displays configured payment method types supported by the browser available for the payment, allowing your customer to select a payment method. The payment methods automatically collects the associated payment details for the selected payment method type.

```js
<script src="https://beta.hyperswitch.io/v1/HyperLoader.js"></script>;
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ items: [{ id: "xl-tshirt" }], country: "US" }),
  });
  const { clientSecret } = await response.json();

  const appearance = {
    theme: "midnight",
  };

  widgets = hyper.widgets({ appearance, clientSecret });

  const expressCheckoutOptions = {
    wallets: {
      walletReturnUrl: "https://example.com/complete",
      //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
    },
  };

  const expressCheckout = widgets.create("expressCheckout", expressCheckoutOptions);
  expressCheckout.mount("#express-checkout");
}
```

{% endtab %}
{% endtabs %}

#### 3. Complete payment on the client

**3.1 Handle the submit event and complete the payment**

> Note: This step is not required for ExpressCheckout

Listen to the form's submit event to know when to confirm the payment through the hyper API.

Call `confirmPayment()`, passing along the `unifiedCheckout` and a `return_url` to indicate where Hyper should redirect the user after they complete the payment. Hyper redirects the customer to an authentication page depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.

```js
async function handleSubmit(e) {
  setMessage("");
  e.preventDefault();

  if (!hyper || !widgets) {
    return;
  }
  setIsLoading(true);

  const { error, status } = await hyper.confirmPayment({
    widgets,
    confirmParams: {
      // Make sure to change this to your payment completion page
      return_url: "https://example.com/complete",
    },
    redirect: "always", // if you wish to redirect always, otherwise it is defaulted to "if_required"
  });

  if (error) {
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message);
    } else {
      if (error.message) {
        setMessage(error.message);
      } else {
        setMessage("An unexpected error occurred.");
      }
    }
  }
  if (status) {
    handlePaymentStatus(status); //handle payment status
  }
  setIsLoading(false);
}
```

Also if there are any immediate errors (for example, your customer's card is declined), `HyperLoader` returns an error. Show that error message to your customer so they can try again.

<details>

<summary>Alternate Implementation: SDK handles the Confirm Button</summary>

For SDK to render the confirm button and handle the confirm payment, in paymentElementOptions, you can send:

```html
const unifiedCheckoutOptions = {
  ...,
  sdkHandleConfirmPayment: {
     handleConfirm: true,
     buttonText: "SDK Pay Now",
     confirmParams: {
       return_url: "https://example.com/complete",
     },
   },
};
```

1. **`handleConfirm (required)`** - A boolean value indicating whether the SDK should handle the confirmation of the payment.
2. **`confirmParams (required)`** - It's an object which takes return\_url. return\_url parameter specifies the URL where the user should be redirected after payment confirmation.
3. **`buttonText (optional)`** - The text to display on the payment button.\
   Default value: **Pay Now**

For customization, please follow the [`Customization docs`](https://docs.hyperswitch.io/hyperswitch-cloud/integration-guide/web/customization#id-5.-confirm-button).

</details>

**3.2 Display a payment status message**

When Hyper redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by `HyperLoader`. Use this to retrieve the `Payment` to determine what to show to your customer.

```js
// Fetches the payment status after payment submission
async function checkStatus() {
  const clientSecret = new URLSearchParams(window.location.search).get(
    "payment_intent_client_secret"
  );

  if (!clientSecret) {
    return;
  }

  const { payment } = await hyper.retrievePayment(clientSecret);

  switch (payment.status) {
    case "succeeded":
      showMessage("Payment succeeded!");
      break;
    case "processing":
      showMessage("Your payment is processing.");
      break;
    case "requires_payment_method":
      showMessage("Your payment was not successful, please try again.");
      break;
    default:
      showMessage("Something went wrong.");
      break;
  }
}
```

Congratulations! Now that you have integrated the Hyperswitch SDK on your app, you can customize the payment elements to blend with the rest of your app.


# JS with REST API Integration

Integrate Juspay Hyperswitch SDK to any Web App using hyperswitch-node for seamless payment processing

**Before following these steps, please configure your payment methods** [here](https://hyperswitch.io/docs/paymentMethods/cards). Use this guide to integrate Juspay Hyperswitch SDK to your app with any framework. If you are using React framework please go through React Integration to use a dedicated wrapper.\\

#### [<mark style="color:blue;">Demo App</mark>](https://github.com/PritishBudhiraja/hyperswitch-demo-app/archive/refs/heads/master.zip)

#### 1. Setup the server

Follow the Server Setup section.

#### 2. Build checkout page on the client

**2.1 Define the payment form**

{% hint style="info" %}
This step is recommended for the Unified Checkout for an enhanced user experience. In case you are integrating Express Checkout (mentioned later below), this step is not required.
{% endhint %}

Add one empty placeholder `div` to your checkout form for each Widget that you'll mount. `HyperLoader` inserts an iframe into each `div` to securely collect the customer's email address and payment information.

```js
<form id="payment-form">
  <div id="unified-checkout">
   <!--HyperLoader injects the Unified Checkout-->
  </div>
  <button id="submit">
    <div class="spinner hidden" id="spinner"></div>
    <span id="button-text">Pay now</span>
  </button>
  <div id="payment-message" class="hidden"></div>
</form>
```

{% tabs %}
{% tab title="UnifiedCheckout" %}
**2.2 Fetch the Payment and create the Unified Checkout**

Immediately make a request to the endpoint on your server to create a new Payment as soon as your checkout page loads. The `clientSecret` returned by your endpoint is used to complete the payment.

> Important: Make sure to never share your API key with your client application as this could potentially compromise your payment flow

Following this, create a `unifiedCheckout` and mount it to the placeholder `div` in your payment form. This embeds an iframe with a dynamic form that displays configured payment method types available from the `Payment`, allowing your customer to select a payment method. The form automatically collects the associated payment details for the selected payment method type.

In case you want the SDK to be loaded on a particular event (like button click), you can call the initialize function on that event.

```js
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({currency: "USD",amount: 100}),
  });
  const { clientSecret } = await response.json();
  
  // Initialise Hyperloader.js
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";
 
  let hyper; 
  script.onload = () => {
      hyper = window.Hyper("YOUR_PUBLISHABLE_KEY",{
      customBackendUrl: "YOUR_BACKEND_URL",
      //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
      })
      const appearance = {
          theme: "midnight",
      };
      const widgets = hyper.widgets({ appearance, clientSecret });
      const unifiedCheckoutOptions = {
          layout: "tabs",
          wallets: {
              walletReturnUrl: "https://example.com/complete",
              //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
          },
      };
      const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
      unifiedCheckout.mount("#unified-checkout");
  };
  document.body.appendChild(script);
}
```

**2.3 Additional Callback Handling for Wallets Payment Process**

This document outlines the details and functionality of an optional callback `completeDoThis` and `onSDKHandleClick` that can be provided by merchants during the payment process. These callbacks allow merchants to hook into the payment flow at key stages and handle specific actions or events before continuing the normal flow.

* **onSDKHandleClick:** This callback is triggered immediately after the user clicks any wallet button.
* **completeDoThis:** This callback is triggered after the payment is completed, just before the SDK redirects to `walletReturnUrl` provided. It allows the merchant to handle actions post-payment. If not provided, the SDK's default flow will proceed.

{% hint style="warning" %}
**Redirection Handling:** The `onPaymentComplete` callback should handle redirection or any steps needed after payment, as the SDK no longer does this automatically. You must ensure to implement the necessary redirection logic.
{% endhint %}

{% hint style="info" %}
**Fallback:** If no callbacks are provided by the merchant, the SDK will continue with its default behaviour, including automatic redirection after payment completion.
{% endhint %}

{% hint style="danger" %}
The task within `onPaymentButtonClick` must be completed within 1 second. If an asynchronous callback is used, it must resolve within this time to avoid Apple Pay payment failures.
{% endhint %}

**Example Usage**

```javascript
const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
unifiedCheckout.mount("#unified-checkout");

unifiedCheckout.onSDKHandleClick(()=>{
  // Add any custom logic for when the payment button is clicked, such as logging or tracking
  console.log("On Click Wallets")
})

unifiedCheckout.on("completeDoThis",()=>{
  console.log("On Payment Complete")
  // Add any custom post-payment logic here, such as redirection or displaying a success message
})
```

{% endtab %}

{% tab title="ExpressCheckout" %}
**2.2 Fetch the Payment and create the Express Checkout**

> The Express Checkout Element gives you a single integration for accepting payments through one-click payment buttons. Supported payment methods include ApplePay, GooglePay and PayPal.

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to complete the payment.

> Important: Make sure to never share your API key with your client application as this could potentially compromise your payment flow

Create an `expressCheckout` and mount it to the placeholder `div` in your payment form. This embeds an iframe that displays configured payment method types supported by the browser available for the payment, allowing your customer to select a payment method. The payment methods automatically collects the associated payment details for the selected payment method type.

```js
// Fetches a payment intent and captures the client secret
async function initialize() {
  const response = await fetch("/create-payment", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({currency: "USD",amount: 100}),
  });
  const { clientSecret } = await response.json();
  
  // Initialise Hyperloader.js
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = "https://beta.hyperswitch.io/v1/HyperLoader.js";
 
  let hyper; 
  script.onload = () => {
      hyper = window.Hyper("YOUR_PUBLISHABLE_KEY")
      const appearance = {
          theme: "midnight",
      };
      const widgets = hyper.widgets({ appearance, clientSecret });
      const expressCheckoutOptions = {
          wallets: {
              walletReturnUrl: "https://example.com/complete",
              //Mandatory parameter for Wallet Flows such as Googlepay, Paypal and Applepay
          },
      };
      const expressCheckout = widgets.create("expressCheckout", expressCheckoutOptions);
      expressCheckout.mount("#express-checkout");
  };
  document.body.appendChild(script);
}
```

{% endtab %}
{% endtabs %}

#### 3. Complete payment on the client

**3.1 Handle the submit event and complete the payment**

> Note: This step is not required for ExpressCheckout

Listen to the form's submit event to know when to confirm the payment through the hyper API.

Call `confirmPayment()`, passing along the `unifiedCheckout` and a `return_url` to indicate where Hyper should redirect the user after they complete the payment. Hyper redirects the customer to an authentication page depending on the payment method. After the customer completes the authentication process, they're redirected to the `return_url`.

```js
async function handleSubmit(e) {
  setMessage("");
  e.preventDefault();

  if (!hyper || !widgets) {
    return;
  }
  setIsLoading(true);

  const { error, status } = await hyper.confirmPayment({
    widgets,
    confirmParams: {
      // Make sure to change this to your payment completion page
      return_url: "https://example.com/complete",
    },
    redirect: "always", // if you wish to redirect always, otherwise it is defaulted to "if_required"
  });

  if (error) {
    if (error.type === "card_error" || error.type === "validation_error") {
      setMessage(error.message);
    } else {
      if (error.message) {
        setMessage(error.message);
      } else {
        setMessage("An unexpected error occurred.");
      }
    }
  }
  if (status) {
    handlePaymentStatus(status); //handle payment status
  }
  setIsLoading(false);
}
```

Also if there are any immediate errors (for example, your customer's card is declined), `HyperLoader` returns an error. Show that error message to your customer so they can try again.

**3.2 Display a payment status message**

When Hyper redirects the customer to the `return_url`, the `payment_intent_client_secret` query parameter is appended by `HyperLoader`. Use this to retrieve the `Payment` to determine what to show to your customer.

```js
// Fetches the payment status after payment submission
async function checkStatus() {
  const clientSecret = new URLSearchParams(window.location.search).get(
    "payment_intent_client_secret"
  );

  if (!clientSecret) {
    return;
  }

  const { payment } = await hyper.retrievePayment(clientSecret);

  switch (payment.status) {
    case "succeeded":
      showMessage("Payment succeeded!");
      break;
    case "processing":
      showMessage("Your payment is processing.");
      break;
    case "requires_payment_method":
      showMessage("Your payment was not successful, please try again.");
      break;
    default:
      showMessage("Something went wrong.");
      break;
  }
}
```

Congratulations! Now that you have integrated the Hyperswitch SDK on your app, you can customize the payment elements to blend with the rest of your app.


# Headless SDK

Juspay Hyperswitch is designed to facilitate the integration and management of payment-related functionalities in a decoupled or headless architecture with flexibility to customize your checkout UI.

Customize the payment experience using Headless functions

**1. Initialize the Hyperswitch SDK**

Initialize Juspay Hyperswitch Headless SDK onto your app with your publishable key. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

<pre class="language-javascript"><code class="lang-javascript"><strong>// Source Hyperloader on your HTML file using the &#x3C;script /> tag
</strong>hyper = Hyper.init("YOUR_PUBLISHABLE_KEY",{
    customBackendUrl: "YOUR_BACKEND_URL",
    //You can configure this as an endpoint for all the api calls such as session, payments, confirm call.
});
</code></pre>

**2. Create a PaymentIntent**

Make a request to the endpoint on your server to create a new Payment. The `clientSecret` returned by your endpoint is used to initialize the payment session.

{% hint style="danger" %}
**Important**: Make sure to never share your API key with your client application as this could potentially compromise your security
{% endhint %}

**3. Initialize your Payment Session**

Initialize a Payment Session by passing the clientSecret to the `initPaymentSession`

```javascript
paymentSession = hyper.initPaymentSession({
  clientSecret: client_secret,
});
```

| options (Required)                   | Description                                                     |
| ------------------------------------ | --------------------------------------------------------------- |
| `paymentIntentClientSecret (string)` | **Required.** Required to use as the identifier of the payment. |

**4. Craft a customized payments experience**

Using the `paymentSession` object, the default customer payment method data can be fetched, using which you can craft your own payments experience. The `paymentSession` object also exposes a `confirmWithCustomerDefaultPaymentMethod` and `confirmWithLastUsedPaymentMethod` function, using which you can confirm and handle the payment session.

**4a. Confirm using Customer Default Payment Method:**

```javascript
paymentMethodSession = await paymentSession.getCustomerSavedPaymentMethods();

if (paymentMethodSession.error) {
    // handle the case where no default customer payment method is not present
} else {
    // use the customer_default_saved_payment_method_data to fulfill your usecases (render UI)
    const customer_default_saved_payment_method_data =
        paymentMethodSession.getCustomerDefaultSavedPaymentMethodData();
}

// handle submit for pay button 
function handleSubmit() { 
    if (paymentMethodSession.error) {
        // handle the case where no default customer payment method is not present
    } else {
        // use the confirmWithCustomerDefaultPaymentMethod function to confirm and handle the payment session response
        const { error, status } = await
        paymentMethodSession.
            confirmWithCustomerDefaultPaymentMethod({
                confirmParams: {
                    // Make sure to change this to your payment completion page
                    return_url: "https://example.com/complete"
                },
                // if you wish to redirect always, otherwise it is defaulted to "if_required"
                redirect: "always",
                // Pass the CardCVCElement id
                id: "card-cvc-element"
            });

        // use error, status to complete the payment journey
        if (error) {
            if (error.message) {
                // handle error messages
                setMessage(error.message);
            } else {
                setMessage("An unexpected error occurred.");
            }
        }
        if (status) {
            // handle payment status
            handlePaymentStatus(status);
        }
    }
}
```

**Payload for** `confirmWithCustomerDefaultPaymentMethod(payload)`

<table><thead><tr><th width="296">options (Required)</th><th>Description</th></tr></thead><tbody><tr><td><code>confirmParams (object)</code></td><td>Parameters that will be passed on to the Hyper API.</td></tr><tr><td><code>redirect (string)</code></td><td><p><strong>Can be either 'always' or 'if_required'</strong></p><p>By default, <code>confirmWithCustomerDefaultPaymentMethod()</code> will always redirect to your <code>return_url</code> after a successful confirmation. If you set redirect: "if_required", then this method will only redirect if your user chooses a redirection-based payment method.</p></td></tr><tr><td><code>id (string)</code><strong><code>(optional)</code></strong></td><td>The id used when creating the CardCVCElement.</td></tr></tbody></table>

**ConfirmParams object**

<table><thead><tr><th width="281">confirmParams</th><th>Description</th></tr></thead><tbody><tr><td><code>return_url(string)</code></td><td>The url your customer will be directed to after they complete payment.</td></tr></tbody></table>

**4b. Confirm using Last Used Payment Method:**

```javascript
paymentMethodSession = await paymentSession.getCustomerSavedPaymentMethods();

if (paymentMethodSession.error) {
    // handle the case where no default customer payment method is not present
} else {
    // use the customer_last_used_payment_method_data to fulfill your usecases (render UI)
    const customer_last_used_payment_method_data =
        paymentMethodSession.getCustomerLastUsedPaymentMethodData();
}

// handle submit for pay button 
function handleSubmit() { 
    if (paymentMethodSession.error) {
        // handle the case where no default customer payment method is not present
    } else {
        // use the confirmWithLastUsedPaymentMethod function to confirm and handle the payment session response
        const { error, status } = await
        paymentMethodSession.
            confirmWithLastUsedPaymentMethod({
                confirmParams: {
                    // Make sure to change this to your payment completion page
                    return_url: "https://example.com/complete"
                },
                // if you wish to redirect always, otherwise it is defaulted to "if_required"
                redirect: "always",
                // Pass the CardCVCElement id
                id: "card-cvc-element"
            });

        // use error, status to complete the payment journey
        if (error) {
            if (error.message) {
                // handle error messages
                setMessage(error.message);
            } else {
                setMessage("An unexpected error occurred.");
            }
        }
        if (status) {
            // handle payment status
            handlePaymentStatus(status);
        }
    }
}
```

**Payload for** `confirmWithLastUsedPaymentMethod(payload)`

<table><thead><tr><th width="296">options (Required)</th><th>Description</th></tr></thead><tbody><tr><td><code>confirmParams (object)</code></td><td>Parameters that will be passed on to the Hyper API.</td></tr><tr><td><code>redirect (string)</code></td><td><p><strong>Can be either 'always' or 'if_required'</strong></p><p>By default, <code>confirmWithLastUsedPaymentMethod()</code> will always redirect to your <code>return_url</code> after a successful confirmation. If you set redirect: "if_required", then this method will only redirect if your user chooses a redirection-based payment method.</p></td></tr><tr><td><code>id (string)</code><strong><code>(optional)</code></strong></td><td>The id used when creating the CardCVCElement.</td></tr></tbody></table>

**ConfirmParams object**

<table><thead><tr><th width="281">confirmParams</th><th>Description</th></tr></thead><tbody><tr><td><code>return_url(string)</code></td><td>The url your customer will be directed to after they complete payment.</td></tr></tbody></table>

**5. Add CVC Collection (Non PCI Approach)**

The `CardCVCElement` renders a secure iframe to collect the customer's CVC without exposing sensitive data to your application. You can follow the [React Integration](https://docs.hyperswitch.io/explore-hyperswitch/payment-experience/payment/web/react-with-rest-api-integration).

```javascript
import React, { useState, useEffect } from "react";
import {
  CardCVCElement,
  useHyper,
} from "@juspay-tech/react-hyper-js";

export default function Checkout() {
  const hyper = useHyper();

 // handle submit for pay button 
 function handleSubmit() {
   // You can follow the same as mentioned in 4. Craft a customized payments experience
 } 

  return (
    <div>
      {/* Render your saved card UI here */}

      {/* CVC Element */}
      <div style={{ marginTop: "16px" }}>
        <CardCVCElement id="card-cvc-element" />
      </div>

      {/* Pay Button */}
      <button onClick={handleSubmit} disabled={isProcessing}>
        {isProcessing ? "Processing..." : "Pay Now"}
      </button>

      {/* Error Message */}
      {message && <div>{message}</div>}
    </div>
  );
}
```


# Customization

Customize your Web unified checkout for Juspay Hyperswitch

#### 1. Layouts

Choose a layout that fits well with your UI pattern. There are two types of layout options as listed below. The layout defaults to accordion if not explicitly specified.

**1.1 Accordion layout**

The accordion layout displays payment methods vertically using an accordion. To use this layout, set the value for layout to accordion. You also have the option to specify other properties, such as those shown in the following example.

```js
var paymentElementOptions = {
  layout: {
    type: 'accordion',
    defaultCollapsed: false,
    radios: true,
    spacedAccordionItems: false
  },
}

--- or ---

var paymentElementOptions = {
  layout: 'accordion'
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

**1.2 Tabs layout**

The tabs layout displays payment methods horizontally using tabs. To use this layout, set the value for layout to tabs. You also have the option to specify other properties, such as tabs or collapsed.

```js
var paymentElementOptions = {
  layout: 'tabs'
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

**1.2.1 Tabs layout - Grid arrangement**

By default, the tabs layout shows excess payment methods inside a dropdown. If you want to display all payment methods at once in a grid view, you can customize the tabs layout using `paymentMethodsArrangementForTabs`.

When `paymentMethodsArrangementForTabs` is set to `grid`, the tabs layout switches to a grid style

`paymentMethodsArrangementForTabs` supports the following values:

* `default` – Shows excess payment methods in a dropdown (default).
* `grid` – Shows all payment methods in a grid without a dropdown.

To enable the grid arrangement in tabs layout, configure the layout object as shown below.

```javascript
var paymentElementOptions = {
  layout: {
    type: 'tabs',
    paymentMethodsArrangementForTabs: 'grid' 
  }
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

**1.3 Saved Methods Customization**

In this layout, by default saved payment methods are shown for a quick checkout. Customers can select an existing method or add a new one using New payment methods, which reveals the payment form inline.

This layout optimizes for faster repeat payments while still supporting new payment method entry in a single, seamless flow.

`hideCardExpiry` - When `hideCardExpiry` is set to true, the expiry date displayed on saved card items is hidden, and the CVC input is rendered inline next to the card details instead of below them. This creates a more compact saved card view.

**One-click wallets** such as Google Pay, Apple Pay, and PayPal are always shown at the top of the checkout to enable faster, low-friction payments. This is available for both Accordion and Tabs layout.

```
var paymentElementOptions = {
   layout: {
    savedMethodCustomization: {
      groupingBehavior: "groupByPaymentMethods",
      hideCardExpiry: true, // default - false
    }
  }
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

**1.4 One Click Payment Methods Customization**

By default, one-click payment methods such as Google Pay and Apple Pay are always displayed at the top of the checkout, regardless of the selected layout (Accordion or Tabs).

If you want to display one-click payment methods alongside other payment methods inside the layout instead of at the top, you can disable this behavior using `displayOneClickPaymentMethodsOnTop`.

When `displayOneClickPaymentMethodsOnTop` is set to `false`:

* Supported one-click methods are moved into the selected layout (Tabs or Accordion).
* Unsupported one-click methods are hidden.

To customize one-click payment method placement, configure the layout object as shown below.

```javascript
var paymentElementOptions = {
   layout: {
    type: 'tabs',
    displayOneClickPaymentMethodsOnTop: false, //Default - true
  }
}

<PaymentElement id="payment-element" options={paymentElementOptions} />
```

{% hint style="info" %}
Note: Currently, only Google Pay, Apple Pay, and PayPal (Redirect) support being moved into the layout. Other one-click methods are hidden when this option is disabled.
{% endhint %}

#### 2. Wallets

The wallet customization feature lets users configure payment options like Apple Pay, Google Pay, PayPal, and Klarna. It includes a `walletReturnUrl` for post-payment redirects and a `style` property to customize the wallet's appearance, offering flexibility for seamless integration.

<pre class="language-javascript"><code class="lang-javascript">var paymentElementOptions = {
    wallets: {
      walletReturnUrl: `${window.location.origin}`,
      applePay: "auto",
      googlePay: "auto",
      payPal: "auto",
      klarna: "never",
      style: {
        theme: "dark",
        type: "default",
        height: 55,
        buttonRadius: 4,
      },
    },
  }
  
<strong>&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</strong></code></pre>

| Variable                                                                                        | Description                                                                                                                                                                                                                                                                                                                    | Values                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ----------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| walletReturnUrl: string                                                                         | Defines the URL to redirect users to after completing a payment.                                                                                                                                                                                                                                                               | This will take a **URL string** as its value                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| <p>applePay: showType<br>googlePay: showType<br>payPal: showType<br>klarna: showType</p>        | Determines the visibility of Apple Pay, Google Pay, PayPal and Klarna.                                                                                                                                                                                                                                                         | <p><code>showType</code> can take two values:</p><ul><li><code>"auto"</code>: Display when supported.</li><li><code>"never"</code>: Always hidden</li></ul>                                                                                                                                                                                                                                                                                                                                                                                                    |
| <p>style: {<br>theme: theme,<br>type: styleType,<br>height: int,<br>buttonRadius: int,<br>}</p> | <p>Configures the wallet's appearance with the following options:</p><ul><li><code>theme</code>: Sets the theme.</li><li><code>type</code>: Defines the style type (e.g. buy).</li><li><code>height</code>: Specifies the height of the wallet.</li><li><code>buttonRadius</code>: Adjusts the button corner radius.</li></ul> | <p><code>theme</code>: It can take values as <code>dark</code>, <code>light</code>, or <code>outline</code>.<br><br><code>type</code>: Specifies the wallet button style with options including <code>checkout</code>, <code>pay</code>, <code>buy</code>, <code>installment</code>, <code>default</code>, <code>book</code>, <code>donate</code>, <code>order</code>, <code>addmoney</code>, <code>topup</code>, <code>rent</code>, <code>subscribe</code>, <code>reload</code>, <code>support</code>, <code>tip</code>, and <code>contribute</code>.<br></p> |

#### 3. Styling variables

The Styling APIs could be used to blend the Unified Checkout with the rest of your app or website.

| Variable              | Description                                                                                                                                                        |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| fontFamily            | The font family is used throughout Widgets. Widget supports css fonts and custom fonts by passing the fonts option; reference to elements consumer                 |
| fontSizeBase          | The font size that's set on the root of the Widget. By default, other font size variables like fontSizeXs or fontSizeSm are scaled from this value using rem units |
| spacingUnit           | The base spacing unit that all other spacing is derived from. Increase or decrease this value to make your layout more or less spacious                            |
| borderRadius          | The border radius used for tabs, inputs, and other components in the Widget                                                                                        |
| colorPrimary          | A primary color used throughout the Widget. Set this to your primary brand color                                                                                   |
| colorBackground       | The color used for the background of inputs, tabs, and other components in the Widget                                                                              |
| colorText             | The default text color used in the Widget                                                                                                                          |
| colorDanger           | A color used to indicate errors or destructive actions in the Widget                                                                                               |
| fontVariantLigatures  | The font-variant-ligatures setting of text in the Widget                                                                                                           |
| fontVariationSettings | The font-variation-settings setting of text in the Widget                                                                                                          |
| fontWeightLight       | The font weight used for light text                                                                                                                                |
| fontWeightNormal      | The font weight used for normal text                                                                                                                               |
| fontWeightMedium      | The font weight used for medium text                                                                                                                               |
| fontWeightBold        | The font weight used for bold text                                                                                                                                 |
| fontLineHeight        | The line-height setting of text in the Widget                                                                                                                      |
| fontSizeXl            | The font size of extra-large text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                                |
| fontSizeLg            | The font size of large text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                                      |
| fontSizeSm            | The font size of small text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                                      |
| fontSizeXs            | The font size of extra-small text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                                |
| fontSize2Xs           | The font size of double-extra small text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                         |
| fontSize3Xs           | The font size of triple-extra small text in the Widget. By default this is scaled from var(--fontSizeBase) using rem units                                         |
| colorSuccess          | A color used to indicate positive actions or successful results in the Element                                                                                     |
| colorWarning          | A color used to indicate potentially destructive actions in the Element                                                                                            |
| colorPrimaryText      | The color of text appearing on top of any a var(--colorPrimary) background                                                                                         |
| colorBackgroundText   | The color of text appearing on top of any a var(--colorBackground) background                                                                                      |
| colorSuccessText      | The color of text appearing on top of any a var(--colorSuccess) background                                                                                         |
| colorDangerText       | The color of text appearing on top of any a var(--colorDanger) background                                                                                          |
| colorWarningText      | The color of text appearing on top of any a var(--colorWarning) background                                                                                         |
| colorTextSecondary    | The color used for text of secondary importance. For example, this color is used for the label of a tab that isn't currently selected                              |
| colorTextPlaceholder  | The color used for input placeholder text in the Widget                                                                                                            |

#### 4. Rules

The rules option is a map of CSS-like selectors to CSS properties, allowing granular customization of individual components. After defining your theme and variables, use rules to seamlessly integrate Elements to match the design of your site. The selector for a rule can target any of the public class names in the Element, as well as the supported states, pseudo-classes, and pseudo-elements for each class. For example, the following are valid selectors:

* .Tab, .Label, .Input, .InputLogo, .SaveWalletDetailsLabel, .OrPayUsingLabel, .TermsTextLabel, .InfoElement, .OrPayUsingLine
* .Tab:focus
* .Input--invalid, .Label--invalid, .InputLogo--invalid
* .Input::placeholder
* .billing-section, .billing-details-text
* .Input--empty, .InputLogo--empty

Each class name used in a selector supports an allowlist of CSS properties that you specify using camel case (for example, boxShadow for the box-shadow property). The following is the complete list of supported class names and corresponding states, pseudo-classes, and pseudo-elements.

**Tabs**

<figure><img src="https://hyperswitch.io/img/site/rulesTabs.png" alt=""><figcaption></figcaption></figure>

| Class Name   | States     | Pseudo-Classes                     | Pseudo-Elements |
| ------------ | ---------- | ---------------------------------- | --------------- |
| .Tabs        | --selected | :hover, :focus, :active, :disabled |                 |
| fontSizeBase | --selected | :hover, :focus, :active, :disabled |                 |
| spacingUnit  | --selected | :hover, :focus, :active, :disabled |                 |

* .Tab, .Label, .Input
* .Tab:focus
* .Input--invalid, .Label--invalid
* .Input::placeholder

Each class name used in a selector supports an allowlist of CSS properties that you specify using camel case (for example, boxShadow for the box-shadow property). The following is the complete list of supported class names and corresponding states, pseudo-classes, and pseudo-elements.

```js
const appearance = {
  variables: {
    buttonBackgroundColor: "#FFFFFF",
    buttonTextColor: "#000000",
    // ... along with other variables
  },
  rules: {
    ".TabLabel": {
      overflowWrap: "break-word",
    },
    ".Tab--selected": {
      display: "flex",
      gap: "8px",
      flexDirection: "row",
      justifyContent: "center",
      alignItems: "center",
      padding: "15px 32px",
      background: "linear-gradient(109deg,#f48836,#f4364c)",
      color: "#ffffff",
      fontWeight: "700",
      borderRadius: "25px",
    },
    ".Tab--selected:hover": {
      display: "flex",
      gap: "8px",
      flexDirection: "row",
      justifyContent: "center",
      alignItems: "center",
      padding: "15px 32px",
      background: "linear-gradient(109deg,#f48836,#f4364c)",
      borderRadius: "25px",
      color: "#ffffff !important",
      fontWeight: "700",
    },
  },
};

const elements = hyper.elements({ clientSecret, appearance });
```

**Form Inputs**

| Class Name | States             | Pseudo-Classes                       | Pseudo-Elements            |
| ---------- | ------------------ | ------------------------------------ | -------------------------- |
| .Label     | --empty, --invalid |                                      |                            |
| .Input     | --empty, --invalid | :hover, :focus, :disabled, :autofill | ::placeholder, ::selection |
| .Error     |                    |                                      |                            |

**Checkbox**

| Class Name     | States    | Pseudo-Classes | Pseudo-Elements |
| -------------- | --------- | -------------- | --------------- |
| .Checkbox      | --checked | :hover         |                 |
| .CheckboxLabel | --checked | :hover         |                 |
| .CheckboxInput | --checked | :hover         |                 |

**InputLogo**

| Class Name | States    | Pseudo-Classes | Pseudo-Elements |
| ---------- | --------- | -------------- | --------------- |
| .InputLogo |           | :hover         |                 |
| .InputLogo | --invalid | :hover,        |                 |
| .InputLogo | --empty   | :hover         |                 |

**SaveWalletDetailsLabel**

| Class Name              | States | Pseudo-Classes | Pseudo-Elements |
| ----------------------- | ------ | -------------- | --------------- |
| .SaveWalletDetailsLabel |        | :hover         |                 |

**OrPayUsingLabel**

| Class Name       | States | Pseudo-Classes | Pseudo-Elements |
| ---------------- | ------ | -------------- | --------------- |
| .OrPayUsingLabel |        | :hover         |                 |

**OrPayUsingLine**

| Class Name      | States | Pseudo-Classes | Pseudo-Elements |
| --------------- | ------ | -------------- | --------------- |
| .OrPayUsingLine |        | :hover         |                 |

**TermsTextLabel**

| Class Name      | States | Pseudo-Classes | Pseudo-Elements |
| --------------- | ------ | -------------- | --------------- |
| .TermsTextLabel |        | :hover         |                 |

**InfoElement**

| Class Name   | States | Pseudo-Classes | Pseudo-Elements |
| ------------ | ------ | -------------- | --------------- |
| .InfoElement |        | :hover         |                 |

#### 5. Languages

Juspay Hyperswitch Unified Checkout supports localization in 6 languages. By default, the Unified Checkout SDK will detect the locale of the customer's browser and display the localized version of the payment sheet if that locale is supported. In case it is not supported, we default to English. To override, you can send locale in hyper.elements (options)

We support the following locales -

* Arabic (ar)
* Catalan (ca)
* Chinese (zh)
* Deutsch (de)
* Dutch (nl)
* English (en)
* EnglishGB (en-GB)
* FrenchBelgium (fr-BE)
* French (fr)
* Hebrew (he)
* Italian (it)
* Japanese (ja)
* Polish (pl)
* Portuguese (pt)
* Russian (ru)
* Spanish (es)
* Swedish (sv)

If you need support for locales other than the ones mentioned above, please contact the Hyperswitch team. Now you can test the payments on your app and go-live!

#### 6. Confirm Button

The Styling APIs could be used to blend the Confirm Payment Button (handled by SDK) with your app.

| Variable              | Description                                                        |
| --------------------- | ------------------------------------------------------------------ |
| buttonBackgroundColor | Sets the background color of the payment button                    |
| buttonHeight          | Define the height of the payment button                            |
| buttonWidth           | Specify the width of the payment button                            |
| buttonBorderRadius    | Adjust the border radius of the payment button for rounded corners |
| buttonBorderColor     | Sets the color of the border surrounding the payment button        |
| buttonTextColor       | Define the color of the text displayed on the payment button       |
| buttonTextFontSize    | Customize the font size of the text on the payment button          |
| buttonTextFontWeight  | Specify the font weight of the text on the payment button          |
| buttonBorderWidth     | Specify the border width of the button                             |

#### 7. More Configurations

**Branding**

You can decide whether to display the Hyperswitch branding using the `branding` prop

<pre class="language-javascript"><code class="lang-javascript"><strong>var paymentElementOptions = {
</strong> ...,
  branding: "never", // choose between "never" and "always"
}

&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</code></pre>

**Payment Methods Header Text**

Customize the header text for the section displaying available payment methods.

<pre class="language-javascript"><code class="lang-javascript"><strong>var paymentElementOptions = {
</strong> ...,
  paymentMethodsHeaderText: "Select Payment Method",
}

&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</code></pre>

**Saved Payment Methods Header Text**

Customize the header text for the section displaying saved payment methods.

<pre class="language-javascript"><code class="lang-javascript"><strong>var paymentElementOptions = {
</strong> ...,
  savedPaymentMethodsHeaderText: "Saved Payment Methods",
}

&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</code></pre>

**Custom Message for Card Terms**

{% hint style="warning" %}
This property will be deprecated, please use the newly added **Payment Methods Configuration (**&#x70;aymentMethodsConfi&#x67;**)** property to pass custom messages
{% endhint %}

We provide a default message for card terms i.e.

```rescript
`By providing your card information, you allow ${company_name} to charge your card for future payments in accordance with their terms.`
```

If you would like to customize this message, you can do so by using the `customMessageForCardTerms` property in the `paymentElementOptions` object.

<pre class="language-javascript"><code class="lang-javascript"><strong>var paymentElementOptions = {
</strong> ...,
  customMessageForCardTerms: "Custom message for Card terms",
}

&#x3C;PaymentElement id="payment-element" options={paymentElementOptions} />
</code></pre>

**Hide Card Nickname Field**

The `hideCardNicknameField` property allows you to hide the card nickname field when saving a card.

```javascript
var paymentElementOptions = {
  ...,
  hideCardNicknameField: true,  // default - false
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Hide Expired Saved Payment Methods**

The `hideExpiredPaymentMethods` property allows you to control whether expired saved payment methods are hidden or not.

```javascript
var paymentElementOptions = {
  ...,
  hideExpiredPaymentMethods: false, // default - false
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Terms**

The `terms` property allows you to configure the display of terms for various payment methods.

```javascript
var paymentElementOptions = {
  ...,
  terms: {
    auBecsDebit: "always",
    bancontact: "auto",
    card: "never",
    ideal: "auto",
    sepaDebit: "always",
    sofort: "never",
    usBankAccount: "auto",
  },
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Display Saved Payment Methods**

The `displaySavedPaymentMethods` property determines whether saved payment methods are displayed.

```javascript
var paymentElementOptions = {
  ...,
  displaySavedPaymentMethods: false,
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Display Saved Payment Methods Checkbox**

The `displaySavedPaymentMethodsCheckbox` property determines whether the "Save payment methods" checkbox is displayed.

```javascript
var paymentElementOptions = {
  ...,
  displaySavedPaymentMethodsCheckbox: false, 
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Saved Payment Methods Checkbox Checked By Default**

The `savedPaymentMethodsCheckboxCheckedByDefault` property determines whether the "Save payment methods" checkbox is checked by default when displayed.

```javascript
var paymentElementOptions = {
  ...,
  savedPaymentMethodsCheckboxCheckedByDefault: false, // default - false
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Payment Method Order**

The `paymentMethodOrder` property allows you to specify the order in which payment methods are displayed.

```javascript
var paymentElementOptions = {
  ...,
  paymentMethodOrder: ["card", "ideal", "sepaDebit", "sofort"],
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Business**

The `business` property allows you to specify a business name to be attached to the terms. By default merchant name will be taken as business name.

```javascript
var paymentElementOptions = {
  ...,
  business: {
    name: "Example Business",
  },
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Read Only**

The `readOnly` property puts the SDK into read-only mode, disabling all interactions.

```javascript
var paymentElementOptions = {
  ...,
  readOnly: true,
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Show Short Surcharge Message**

The `showShortSurchargeMessage` property allows merchants to display a short message when a surcharge is applied, instead of the default message provided by the SDK.

{% hint style="success" %}
The short message format will be: **`Fee: {Currency} {Amount}`**
{% endhint %}

```javascript
var paymentElementOptions = {
  ...,
  showShortSurchargeMessage: true, // default - false
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**Payment Methods Configuration**

The `paymentMethodsConfig` prop allows you to provide payment-method-specific configurations within the Hyperswitch SDK. Currently, it supports displaying custom messages (or hiding default messages) for individual payment method types.

{% hint style="success" %}
This configuration does **not** apply to one-click wallets. It applies to all other payment method types such as cards, bank debits, bank redirects, etc.
{% endhint %}

```javascript
var paymentElementOptions = {
  ...,
  paymentMethodsConfig: [{
    paymentMethod: string,              // e.g. "card", "bank_debit", "bank_redirect"
    paymentMethodTypes: [{
        paymentMethodType: string,      // e.g. "credit", "debit", "sepa", "ach"
        message: {
          value?: string,               // Custom message text
          displayMode: string           // "default_sdk_message" | "custom_message" | "hidden"
        }
      }]
  }]
};

<PaymentElement id="payment-element" options={paymentElementOptions} />;
```

**`displayMode` values**

| Value                   | Description                                                                    |
| ----------------------- | ------------------------------------------------------------------------------ |
| `"default_sdk_message"` | Show the SDK's default message for this payment method type (default behavior) |
| `"custom_message"`      | Show a custom message provided in `message.value`                              |
| `"hidden"`              | Hide the message entirely                                                      |

If `displayMode` is `"custom_message"` but `value` is empty or not provided, the message is hidden.

**How it works**

The `message` configuration controls the text displayed below each payment method type in the checkout. This is used in two places:

1. **Terms/disclaimer text** — The informational text shown below a payment method (e.g., "By providing your card details, you agree to our terms"). Setting `displayMode` to `"custom_message"` with a `value` replaces this text; setting it to `"hidden"` removes it entirely.
2. **Save card checkbox label** — For card payment methods, if a custom message is provided, it also replaces the default label on the "Save card details" checkbox when on the card form screen.

**Default behavior**

If a payment method type is **not** listed in `paymentMethodsConfig`, or if `displayMode` is set to `"default_sdk_message"`, the SDK shows its default terms message as usual.

#### Next step:


# Error Codes

Reference table of client error codes returned by the SDK for graceful error handling in your web application.

The following table lists client error codes that the Juspay Hyperswitch SDK returns to your website for graceful handling.

| Error Type               | Error Message                                   |
| ------------------------ | ----------------------------------------------- |
| invalid\_request\_error  | Invalid api key                                 |
| invalid\_request\_error  | Invalid value for < parameter\_name >           |
| invalid\_request\_error  | Missing required parameter: < parameter\_name > |
| invalid\_request\_error  | Invalid client secret                           |
| invalid\_request\_error  | Invalid promise                                 |
| processing\_error        | Payment failed with the payment processor       |
| internal\_server\_error  | Server is unavailable                           |
| object\_not\_found       | Payment does not exist                          |
| confirm\_payment\_failed | An unknown error occurred                       |


# Mobile

Juspay Hyperswitch SDK offers **powerful and flexible mobile SDKs** to integrate secure, customizable, and high-performance payments into your iOS and Android apps — whether you're building with native frameworks or cross-platform tools like React Native and Flutter.

#### Key Features

* **Native & Cross-Platform Support** – iOS, Android, React Native, and Flutter.
* **Lite SDK Mode** – Minimal bundle size with full payment capabilities via web components.
* **Unified Configuration** – Same `PaymentSheet.Configuration` or `PaymentSession` options across platforms:
  * Appearance & branding
  * Billing & shipping details
  * Payment method preferences
* **Secure by Default** – PCI DSS compliant, tokenized transactions.
* **Customizable UI** – Match your app's look and feel.
* **Global Payment Methods** – Cards, wallets, and more.


# Android

Integrate unified checkout on your Android app

<figure><img src="/files/gwFlkIZzTzHUH5Vc9RAJ" alt="" width="375"><figcaption></figcaption></figure>

**Checkout the working demo of unified checkout by clicking on the link below**

Revolutionize your app's payment capabilities with the Juspay Hyperswitch Android SDK, delivering a seamless and tailored Global Checkout Experience. The Hyperswitch Unified Checkout on Android is meticulously designed to provide an all-encompassing, unified, and optimized payment journey, ensuring exceptional conversion rates.

<table data-header-hidden><thead><tr><th data-type="image"></th><th></th></tr></thead><tbody><tr><td><a href="/files/AXMCQgXc2vMsBEsXcw5L">/files/AXMCQgXc2vMsBEsXcw5L</a></td><td><p><strong>Inclusive</strong></p><p>Global payments, diverse methods - cards, buy now pay later, and digital wallets. Unified Checkout adapts to local preferences, integrates languages for an inclusive solution.</p></td></tr><tr><td><a href="/files/Us9HbXHZjiMUXAizn8OO">/files/Us9HbXHZjiMUXAizn8OO</a></td><td><p><strong>Consistent</strong></p><p>Consistent payment experience on Web, Android, and iOS with smart forms, minimal redirects, and intelligent retries. Unified Checkout ensures reliability and uniformity.</p></td></tr><tr><td><a href="/files/q5U70Wk9354voSk6bWrZ">/files/q5U70Wk9354voSk6bWrZ</a></td><td><p><strong>Blended</strong></p><p>Tailor payment seamlessly with 40+ styling APIs for a native, cohesive, branded checkout in your Android app or website.</p></td></tr></tbody></table>

**Modify and Experiment:** While the Unified Checkout is pre-optimized for maximum conversions, the Hyperswitch Android SDK empowers you to go beyond the standard. Take control with our SDK APIs, allowing you:

* **Include New Fields:** Adapt swiftly to various use cases by adding new fields to the payment form, such as collecting billing addresses or zip codes for additional information.
* **Prioritize Payment Methods:** Impact your payment mix and conversion rates by prioritizing or promoting specific payment methods based on your customer preferences.
* **Switch Themes and Layouts:** Choose from a wide range of pre-designed themes and layouts for the checkout page, aligning the Unified Checkout with your app's aesthetics.

Experience the flexibility to modify and experiment, ensuring your app's payment journey aligns precisely with your business requirements and user expectations. Elevate your Android app's payment experience with the Hyperswitch Android SDK.


# Kotlin with REST API Integration

Integrate hyper SDK to your Kotlin App using hyperswitch-node

<details>

<summary><a href="https://github.com/aashu331998/Hyperswitch-Android-Demo-App/archive/refs/heads/main.zip"><strong>Demo App</strong></a></summary>

You can use this demo app as a reference with your Juspay Hyperswitch credentials to test the setup.

</details>

#### Requirements

* Android 7.0 (API level 24) and above
* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) 8.13+
* [Gradle](https://gradle.org/releases/) 8.13+
* [AndroidX](https://developer.android.com/jetpack/androidx/)

#### 1. Setup the server

Follow the [Server Setup](/integration-guide/payment-experience/pay-then-vault/server-setup) section.&#x20;

#### 2. Build checkout page on your app

**2.1 Add the Buildscript Classpath**

To start integrating the Juspay Hyperswitch SDK, add the following classpath to the `buildscript` block of your project-level `build.gradle` file:

<pre class="language-gradle"><code class="lang-gradle">buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "io.hyperswitch:hyperswitch-gradle-plugin:<a data-footnote-ref href="#user-content-fn-1">$latest_version</a>"
    }
}
</code></pre>

**2.2 Add the Plugin**

Add the following plugin to the `plugins` block of your app-level `build.gradle` file:

```gradle
plugins {
    // Apply Hyperswitch Plugin
    id 'io.hyperswitch.plugin'
}
```

**2.3 Configure the SDK**

Configure the Hyperswitch SDK in your app-level `build.gradle` file. You can specify the main SDK version and enable optional features:

<pre class="language-gradle"><code class="lang-gradle">hyperswitch {
    // Optional: Specify main SDK version (defaults to latest if not specified)
    sdkVersion = "<a data-footnote-ref href="#user-content-fn-2">latest_version</a>"
    
    // Optional features - only add what you need
    features = [HyperFeature.SCANCARD, HyperFeature.NETCETERA]
}
</code></pre>

{% hint style="warning" %}
Note:

* If you don't specify `sdkVersion`, the plugin will automatically use the latest available version
* You only need to enable the features you plan to use
* Individual feature versions are optional - the plugin will use recommended compatible versions
  {% endhint %}

**2.4 Implement the HyperInterface**

Next, implement the `HyperInterface` in your `CheckoutActivity`. This involves extending `FragmentActivity` or a subclass such as `AppCompatActivity`, and implementing the `HyperInterface`:

```kotlin
class CheckoutActivity : AppCompatActivity(), HyperInterface {
    // ...
}
```

{% hint style="warning" %}
**Note**:

`PaymentSession` is designed to work with AndroidX activities. Ensure that your `CheckoutActivity` extends `FragmentActivity` or its subclass from the AndroidX library
{% endhint %}

**2.5 Setup the SDK and fetch a Payment**

Create a HyperswitchInstance using the publishable key and optional profile ID returned by your server:

```kotlin
hyperswitchInstance = Hyperswitch.init(
          activity = this,
          config = HyperswitchConfiguration(
              publishableKey = response.publishableKey,
              profileId = response.profileId,
          ),
      )
```

{% hint style="warning" %}
**Note**:

For an open-source setup, use the following parameters:

```kotlin
val config = HyperswitchConfiguration(
      publishableKey = response.publishableKey,
      profileId = response.profileId,
      customConfig = CustomEndpointConfiguration(
          commonEndpoint = "https://your-hyperswitch-host.example.com",
      ),
  )
```

The SDK derives the backend, logging, and asset paths from commonEndpoint. Provide the base URL without a trailing slash.

Individual endpoints can be overridden when required:

```kotlin
val config = HyperswitchConfiguration(
      publishableKey = response.publishableKey,
      profileId = response.profileId,
      customConfig = CustomEndpointConfiguration(
          overrideEndpoints = OverrideEndpoints(
              customBackendEndpoint =
                  "https://your-hyperswitch-host.example.com/api",
              customLoggingEndpoint =
                  "https://your-hyperswitch-host.example.com/api/logs/sdk",
              customAssetEndpoint =
                  "https://your-hyperswitch-host.example.com/assets/v2",
          ),
      ),
  )
```

{% endhint %}

**Fetch a Payment**

Request your server to fetch a payment as soon as your view is loaded. Store the `sdk_authorization` returned by your server. The `PaymentSession` will use this to complete the payment process.

#### 3. Complete the payment on your app

**Initialize Payment Session**

Initialize the payment session with the `sdk_authorization`:

```kotlin
 private fun initializePaymentSession(sdkAuthorization: String) {
      val instance = hyperswitchInstance ?: return

      lifecycleScope.launch {
          paymentSession = instance.initPaymentSession(
              PaymentSessionConfiguration(
                  sdkAuthorization = sdkAuthorization,
              ),
          )

          // The payment sheet can now be presented.
          enablePayButton()
      }
  }
```

**Handle Payment Result**

Handle the payment result in the completion block. Display appropriate messages to your customer based on the outcome of the payment:

```kotlin
private fun handlePaymentResult(result: PaymentResult) {
      when (result) {
          is PaymentResult.Completed -> {
              showMessage("Payment completed")
          }
          is PaymentResult.Canceled -> {
              showMessage("Payment cancelled")
          }
          is PaymentResult.Failed -> {
              showMessage(
                  result.throwable.message ?: "Payment failed",
              )
          }
      }
  }
```

{% hint style="danger" %}
Please retrieve the payment status from the Hyperswitch backend to get the terminal status of the payment. Do not rely solely on the status returned by the SDK, as it may not always reflect the final state of the transaction.
{% endhint %}

**Present the Payment Page**

Create a configuration object to customize the payment sheet and present the payment page:

```kotlin
private fun buildPaymentSheetConfiguration(): PaymentSheet.Configuration =
      PaymentSheet.Configuration.Builder(
          merchantDisplayName = "Example, Inc.",
      )
          .primaryButtonLabel("Pay Now")
          .allowsDelayedPaymentMethods(false)
          .allowsPaymentMethodsRequiringShippingAddress(false)
          .build()

// Present Payment Page
private fun presentPaymentSheet() {
      val session = paymentSession ?: return

      lifecycleScope.launch {
          val result = session.presentPaymentSheet(
              buildPaymentSheetConfiguration(),
          )

          handlePaymentResult(result)
      }
  }
```

**Final Step**

Congratulations! You have successfully integrated the Hyperswitch Android SDK into your app. You can now customize the payment sheet to match the look and feel of your app.

#### Next Step:

[^1]: [Get Latest Version](https://central.sonatype.com/artifact/io.hyperswitch/hyperswitch-gradle-plugin/versions)

[^2]: <https://central.sonatype.com/artifact/io.hyperswitch/hyperswitch-sdk-android/versions>


# Lite SDK

Integrate Hyperswitch Lite SDK to your Kotlin App

#### Key Features of Lite SDK

**Lightweight Integration**

* **Smaller artifact size**: <300 KB
* **Faster initialization**: Streamlined setup process
* **Web-based UI**: Uses web components for payment forms
* **Reduced dependencies**: Minimal impact on app size
* **Shared Configuration**: The Lite SDK uses the same `PaymentSheet.Configuration` options as the main SDK, including:
  * Appearance customization
  * Billing details
  * Shipping information
  * Payment method preferences
  * Branding options

#### Requirements

* Android 6.0 (API level 23) and above
* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) 8.5+
* [Gradle](https://gradle.org/releases/) 8.8+
* [AndroidX](https://developer.android.com/jetpack/androidx/)

#### 1. Setup the server

Follow the Server Setup section.

#### 2. Build checkout page on your app

**2.1 Add the Dependency**

Add the Juspay Hyperswitch Lite SDK dependency to your app-level `build.gradle` file:

```gradle
dependencies {
    implementation 'io.hyperswitch:hyperswitch-sdk-android-lite:+'
}
```

**2.2 Setup the Lite SDK and fetch a Payment**

Set up the Lite SDK using your publishable key. This is essential for initializing a `PaymentSession`:

```kotlin
import io.hyperswitch.lite.PaymentSession

val paymentSession = PaymentSession(applicationContext, "YOUR_PUBLISHABLE_KEY")
```

{% hint style="warning" %}
**Note**:

PaymentSession needs to be initialized in onCreate method of your `FragmentActivity`
{% endhint %}

{% hint style="warning" %}
**Note**:

For an open-source setup, use the following parameters:

```kotlin
val paymentSession = PaymentSession(applicationContext, "YOUR_PUBLISHABLE_KEY", "YOUR_CUSTOM_BACKEND_URL", "YOUR_CUSTOM_LOG_URL")
```

{% endhint %}

**Fetch a Payment**

Request your server to fetch a payment as soon as your view is loaded. Store the `client_secret` returned by your server. The `PaymentSession` (Lite) will use this secret to complete the payment process.

#### 3. Complete the payment on your app

**Initialize Payment Session**

Initialize the payment session with the `client_secret`:

```kotlin
paymentSession.initPaymentSession(paymentIntentClientSecret)
```

**Handle Payment Result**

Handle the payment result in the completion block. Display appropriate messages to your customer based on the outcome of the payment:

```kotlin
private fun onPaymentSheetResult(paymentResult: PaymentSheetResult) {
    when (paymentResult) {
        is PaymentSheetResult.Completed -> {
            showToast("Payment complete!")
        }
        is PaymentSheetResult.Canceled -> {
            Log.i(TAG, "Payment canceled!")
        }
        is PaymentSheetResult.Failed -> {
            showAlert("Payment failed", paymentResult.error.localizedMessage)
        }
    }
}
```

{% hint style="danger" %}
Please retrieve the payment status from the Hyperswitch backend to get the terminal status of the payment. Do not rely solely on the status returned by the SDK, as it may not always reflect the final state of the transaction.
{% endhint %}

**Present the Payment Page**

Create a configuration object to customize the payment sheet and present the payment page:

```kotlin
val configuration = PaymentSheet.Configuration("Your_app, Inc.")

// Present Payment Page (Lite SDK)
paymentSession.presentPaymentSheet(configuration, ::onPaymentSheetResult)
```

**Final Step**

Congratulations! You have successfully integrated the Hyperswitch Lite SDK into your app. The Lite SDK provides the same powerful payment processing capabilities with a smaller footprint, making it ideal for apps where bundle size is a concern.

#### Next Step:


# Widgets

Integrate Juspay Hyperswitch SDK using individual payment widgets for granular control over your payment flow.

<figure><img src="/files/P9T6hEst7XnsY7EF9VTb" alt="" width="375"><figcaption></figcaption></figure>

#### Requirements

* Android 6.0 (API level 23) and above
* [Android Gradle Plugin](https://developer.android.com/studio/releases/gradle-plugin) 8.5+
* [Gradle](https://gradle.org/releases/) 8.8+
* [AndroidX](https://developer.android.com/jetpack/androidx/)

#### 1. Setup the server

```js
$ npm install @juspay-tech/hyperswitch-node
```

Follow the Server Setup section.

#### 2. Build checkout page on your app

**2.1 Add the Buildscript Classpath**

To start integrating the Juspay Hyperswitch SDK, add the following classpath to the `buildscript` block of your project-level `build.gradle` file:

<pre class="language-gradle"><code class="lang-gradle">buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "io.hyperswitch:hyperswitch-gradle-plugin:<a data-footnote-ref href="#user-content-fn-1">$latest_version</a>"
    }
}
</code></pre>

**2.2 Apply the Plugin**

Add the following plugin to the `plugins` block of your app-level `build.gradle` file:

```gradle
plugins {
    // Apply Hyperswitch Plugin
    id 'io.hyperswitch.plugin'
}
```

**2.3 Implement the HyperInterface**

Next, implement the `HyperInterface` in your Activity. This involves extending `FragmentActivity` and implementing the `HyperInterface`:

```kotlin
class WidgetActivity : AppCompatActivity(), HyperInterface {
    // ...
}
```

**2.4 Initialize Payment Configuration**

Set up the SDK using your publishable key:

```kotlin
private fun initialiseSDK() {
    // Initialize Payment Configuration
    PaymentConfiguration.init(applicationContext, publishKey)
}
```

#### 3. Implementation

Choose from list of available widgets to integrate:

1. Card Element
2. Google Pay
3. PayPal
4. Express Checkout

**Final Step**

Congratulations! You have successfully integrated Juspay Hyperswitch widgets into your app. This approach gives you granular control over each payment method and allows for custom UI/UX design while leveraging Juspay Hyperswitch's payment processing capabilities.

#### Next step:

[^1]: [Get Latest Version](https://central.sonatype.com/artifact/io.hyperswitch/hyperswitch-gradle-plugin/versions)


# Card Element

Learn how to integrate the Card Element widget for accepting card payments in your Android app using Juspay Hyperswitch SDK.

**Purpose:** Card payments with Juspay Hyperswitch

**Add Card Widget to Layout**

```xml
<io.hyperswitch.view.BasePaymentWidget
    android:id="@+id/cardElement"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:paymentMethod="card" />

<Button
    android:id="@+id/confirmButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Pay with Card" />
```

**Initialize Card Launcher**

```kotlin
private lateinit var cardPaymentLauncher: UnifiedPaymentLauncher

private fun setupCardPayment() {
    cardPaymentLauncher = UnifiedPaymentLauncher.createCardLauncher(
        activity = this,
        resultCallback = ::onPaymentResult
    )
}
```

**Handle Card Payment**

```kotlin
private fun processCardPayment() {
    val cardInputWidget: BasePaymentWidget = findViewById(R.id.cardElement)
    val params: PaymentMethodCreateParams = cardInputWidget.paymentMethodCreateParams
    val confirmParams = ConfirmPaymentIntentParams.createWithPaymentMethodCreateParams(
        params,
        paymentIntentClientSecret
    )

    if (::cardPaymentLauncher.isInitialized) {
        cardPaymentLauncher.confirmCardPayment(confirmParams)
    } else {
        Toast.makeText(this, "SDK is not initialized", Toast.LENGTH_SHORT).show()
    }
}

// Handle card payment results
private fun onPaymentResult(paymentResult: PaymentResult) {
    when (paymentResult) {
        is PaymentResult.Completed -> {
            Toast.makeText(this, "Payment completed: ${paymentResult.data}", Toast.LENGTH_SHORT).show()
        }
        is PaymentResult.Canceled -> {
            Toast.makeText(this, "Payment canceled: ${paymentResult.data}", Toast.LENGTH_SHORT).show()
        }
        is PaymentResult.Failed -> {
            Toast.makeText(this, "Payment failed: ${paymentResult.throwable.message}", Toast.LENGTH_SHORT).show()
        }
    }
}
```

#### Best Practices

**Error Handling**

Always check if launchers are initialized before using them:

```kotlin
if (::cardPaymentLauncher.isInitialized) {
    cardPaymentLauncher.confirmCardPayment(confirmParams)
} else {
    Toast.makeText(this, "SDK is not initialized", Toast.LENGTH_SHORT).show()
}
```


# Google Pay

Learn how to integrate the Google Pay widget for accepting Google Pay payments in your Android app using Juspay Hyperswitch SDK.

**Purpose:** Google Pay payments with Juspay Hyperswitch

**Add Google Pay Widget to Layout**

```xml
<io.hyperswitch.view.BasePaymentWidget
    android:id="@+id/googlePayButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:paymentMethod="google_pay" />
```

**Initialize Google Pay Launcher**

```kotlin
private lateinit var googlePayButton: BasePaymentWidget
private lateinit var googlePayLauncherInstance: UnifiedPaymentLauncher

private fun setupGooglePayLauncher() {
    googlePayButton = findViewById(R.id.googlePayButton)
    googlePayButton.isEnabled = false
    
    googlePayLauncherInstance = UnifiedPaymentLauncher.createGooglePayLauncher(
        activity = this,
        clientSecret = paymentIntentClientSecret,
        config = GooglePayConfig(
            environment = GooglePayEnvironment.Test, // Use GooglePayEnvironment.Production for live
            merchantCountryCode = "US",
            merchantName = "Your Store Name"
        ),
        readyCallback = ::onGooglePayReady,
        resultCallback = ::onGooglePayResult
    )

    googlePayButton.setOnClickListener {
        if (::googlePayLauncherInstance.isInitialized) {
            googlePayLauncherInstance.presentForPayment(paymentIntentClientSecret)
        } else {
            Toast.makeText(this, "Google Pay Launcher not initialized", Toast.LENGTH_SHORT).show()
        }
    }
}
```

**Handle Google Pay Callbacks**

```kotlin
private fun onGooglePayReady(isReady: Boolean) {
    googlePayButton.isEnabled = isReady
}

private fun onGooglePayResult(result: GooglePayPaymentMethodLauncher.Result) {
    when (result) {
        is GooglePayPaymentMethodLauncher.Result.Completed -> {
            val paymentMethodId = result.paymentMethod.id
            Toast.makeText(this, "Payment successful: $paymentMethodId", Toast.LENGTH_LONG).show()
        }
        is GooglePayPaymentMethodLauncher.Result.Canceled -> {
            Toast.makeText(this, "Payment canceled: ${result.data}", Toast.LENGTH_LONG).show()
        }
        is GooglePayPaymentMethodLauncher.Result.Failed -> {
            Toast.makeText(this, "Payment failed: ${result.error.message}", Toast.LENGTH_LONG).show()
        }
    }
}
```

#### Best Practices

**UI State Management**

Disable payment buttons until launchers are ready:

```kotlin
private fun onGooglePayReady(isReady: Boolean) {
    googlePayButton.isEnabled = isReady
}
```


# PayPal

Learn how to integrate the PayPal widget for accepting PayPal payments in your Android app using Juspay Hyperswitch SDK.

PayPal payments with Juspay Hyperswitch.

#### Add PayPal Widget to Layout

```xml
<io.hyperswitch.view.BasePaymentWidget
    android:id="@+id/payPalButton"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:paymentMethod="paypal" />
```

#### Initialize PayPal Launcher

```kotlin
private lateinit var payPalButton: BasePaymentWidget
private lateinit var payPalLauncherInstance: UnifiedPaymentLauncher

private fun setupPayPalLauncher() {
    payPalButton = findViewById(R.id.payPalButton)
    payPalButton.isEnabled = false
    
    payPalLauncherInstance = UnifiedPaymentLauncher.createPayPalLauncher(
        activity = this,
        clientSecret = paymentIntentClientSecret,
        readyCallback = ::onPayPalReady,
        resultCallback = ::onPayPalResult
    )

    payPalButton.setOnClickListener {
        if (::payPalLauncherInstance.isInitialized) {
            payPalLauncherInstance.presentForPayment(paymentIntentClientSecret)
        } else {
            Toast.makeText(this, "PayPal Launcher not initialized", Toast.LENGTH_SHORT).show()
        }
    }
}
```

#### Handle PayPal Callbacks

```kotlin
private fun onPayPalReady(isReady: Boolean) {
    payPalButton.isEnabled = isReady
}

private fun onPayPalResult(result: PayPalPaymentMethodLauncher.Result) {
    when (result) {
        is PayPalPaymentMethodLauncher.Result.Completed -> {
            val paymentMethodId = result.paymentMethod.id
            Toast.makeText(this, "PayPal payment successful: $paymentMethodId", Toast.LENGTH_LONG).show()
        }
        is PayPalPaymentMethodLauncher.Result.Canceled -> {
            Toast.makeText(this, "PayPal payment canceled: ${result.data}", Toast.LENGTH_LONG).show()
        }
        is PayPalPaymentMethodLauncher.Result.Failed -> {
            Toast.makeText(this, "PayPal payment failed: ${result.error.message}", Toast.LENGTH_LONG).show()
        }
    }
}
```


# Express Checkout

Learn how to integrate the Express Checkout widget for one-click payments using saved payment methods with Juspay Hyperswitch SDK.

One-click solution for last used saved payment method with Juspay Hyperswitch.

#### Add Express Checkout Widget to Layout

```xml
<io.hyperswitch.view.BasePaymentWidget
    android:id="@+id/expressCheckoutWidget"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:paymentMethod="expressCheckout" />

<Button
    android:id="@+id/confirmEC"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="Confirm EC" />
```

#### Initialize Express Checkout Launcher

```kotlin
private lateinit var ecLauncherInstance: UnifiedPaymentLauncher

private fun setupECLauncher() {
    ecLauncherInstance = UnifiedPaymentLauncher.createExpressCheckoutLauncher(
        activity = this,
        clientSecret = paymentIntentClientSecret,
        readyCallback = ::onExpressCheckoutReady,
        resultCallback = ::onExpressCheckoutResult
    )

    findViewById<View>(R.id.confirmEC).setOnClickListener {
        if (::ecLauncherInstance.isInitialized) {
            ecLauncherInstance.presentForPayment(paymentIntentClientSecret)
        } else {
            Toast.makeText(this, "Express Checkout Launcher not initialized", Toast.LENGTH_SHORT).show()
        }
    }
}
```

#### Handle Express Checkout Callbacks

```kotlin
private fun onExpressCheckoutReady(isReady: Boolean) {
    findViewById<View>(R.id.confirmEC).isEnabled = isReady
}

private fun onExpressCheckoutResult(result: ExpressCheckoutPaymentMethodLauncher.Result) {
    when (result) {
        is ExpressCheckoutPaymentMethodLauncher.Result.Completed -> {
            Toast.makeText(this, "Express checkout successful: ${result.paymentMethod}", Toast.LENGTH_LONG).show()
        }
        is ExpressCheckoutPaymentMethodLauncher.Result.Canceled -> {
            Toast.makeText(this, "Express checkout canceled: ${result.data}", Toast.LENGTH_LONG).show()
        }
        is ExpressCheckoutPaymentMethodLauncher.Result.Failed -> {
            Toast.makeText(this, "Express checkout failed: ${result.error.message}", Toast.LENGTH_LONG).show()
        }
    }
}
```


# Headless SDK

Hyperswitch is designed to facilitate the integration and management of payment-related functionalities in a decoupled or headless architecture with flexibility to customize your checkout UI.

#### Customize the payment experience using Headless functions

**1. Initialize the Juspay Hyperswitch SDK**

Initialize Juspay Hyperswitch Headless SDK onto your app with your publishable key. To get a Publishable Key please find it [here](https://app.hyperswitch.io/developers).

```kotlin
// dependencies: implementation 'io.hyperswitch:hyperswitch-sdk-android:+' val 
hyperswitchInstance = Hyperswitch.init(
          activity = this,
          config = HyperswitchConfiguration(
              publishableKey = publishableKey,
              profileId = profileId,
          ),
      )
```

**2. Create a Payment Intent**

Make a request to the endpoint on your server to create a new Payment. The `sdk_authorization` returned by your endpoint is used to initialize the payment session.

{% hint style="danger" %}
**Important**: Make sure to never share your API key with your client application as this could potentially compromise your security
{% endhint %}

**3. Initialize your Payment Session**

Initialize a Payment Session by passing the sdk\_authorization to the `initPaymentSession`

```kotlin
lifecycleScope.launch {
          paymentSession = instance.initPaymentSession(
              PaymentSessionConfiguration(
                  sdkAuthorization = sdkAuthorization,
              ),
          )
      }
```

**4. Craft a customized payments experience**

Using the `paymentSession` object, the default customer payment method data can be fetched, using which you can craft your own payments experience. The `paymentSession` object also exposes a `confirmWithCustomerDefaultPaymentMethod` function, using which you can confirm and handle the payment session.

<pre class="language-kotlin"><code class="lang-kotlin"><strong>var handler: PaymentSessionHandler? = null
</strong>
paymentSession.getCustomerSavedPaymentMethods { paymentSessionHandler ->
    handler = paymentSessionHandler
}

val savedPaymentMethod = handler!!.getCustomerLastUsedSavedPaymentMethodData()

button.setOnClickListener { 
    handler!!.confirmWithCustomerLastUsedPaymentMethod { paymentResult -> 
        println(paymentResult)
    }
}
</code></pre>

**Payload for** `confirmWithCustomerLastUsedPaymentMethod(callback)`

<table><thead><tr><th width="296">options (Required)</th><th>Description</th></tr></thead><tbody><tr><td><code>callback (method)</code></td><td>Callback to get confirm response.</td></tr></tbody></table>


# Customization

Customize your Android Unified checkout with fonts, colors, shapes and layouts to match your brand guidelines.

{% hint style="info" %}
You can customize the Android Unified Checkout to support your checkout context and brand guidelines by changing fonts, colors, shapes and layouts.
{% endhint %}

Juspay Hyperswitch allows you to create a `PaymentSheet.Configuration` object with an `appearance` object to match the design of your app.

#### Fonts

Set `typography.fontResId` to your custom font's resource ID to customize your font. Set a `typography.sizeScaleFactor` multiplier to increase or decrease the font size.

```kotlin
val appearance = PaymentSheet.Appearance(
  typography = PaymentSheet.Typography(10.0f, R.font.MY_FONT)
)
```

#### Colors

Modify the color categories in `PaymentSheet.Colors` to customize the colors on the mobile payment sheet as follows:

| Color Category   | Usage                                                                          |
| ---------------- | ------------------------------------------------------------------------------ |
| appBarIcon       | Color used for icons in the payment page ex: close (x) button                  |
| component        | Background color of inputs, tabs and other components                          |
| componentBorder  | Border color for inputs, tabs and other components                             |
| componentDivider | Color for divider lines used inside inputs, tabs and other components          |
| error            | Color for error messages to the user on the payment page                       |
| onComponent      | Color of text and other elements inside components                             |
| onSurface        | Color for items appearing on the surface of the payment page, Ex: text prompts |
| placeholderText  | Color for input fields placeholder text                                        |
| primary          | The primary color to be used across the payment page                           |
| subtitle         | Color of secondary text like prompts for input fields                          |
| surface          | Color of the payment page                                                      |

#### Shapes

Modify the corner radius and border width used across the payment page using `appearance.shapes`.

| Shape Category      | Usage                                                                                          |
| ------------------- | ---------------------------------------------------------------------------------------------- |
| borderStrokeWidthDp | Width of the border used to across input fields, tabs and other components of the payment page |
| cornerRadiusDp      | Corner radius of the input fields, tabs and other components                                   |

Now you can test the payments on your app and go-live!

#### Next Steps


# iOS

Integrate unified checkout with your iOS app

<figure><img src="/files/pPAbhh9qZN53ahHMzXAi" alt="" width="375"><figcaption></figcaption></figure>

**Checkout the working demo of unified checkout by clicking on the link below**

Revolutionize your app's payment capabilities with the Juspay Hyperswitch iOS SDK, delivering a seamless and tailored Global Checkout Experience. The Hyperswitch Unified Checkout on iOS is meticulously designed to provide an all-encompassing, unified, and optimized payment journey, ensuring exceptional conversion rates.

<table data-header-hidden><thead><tr><th data-type="image"></th><th></th></tr></thead><tbody><tr><td><a href="/files/AXMCQgXc2vMsBEsXcw5L">/files/AXMCQgXc2vMsBEsXcw5L</a></td><td><strong>Inclusive:</strong> Supporting a diverse array of global payment methods, including cards, buy now pay later, and digital wallets, the Unified Checkout adapts to local preferences. Customize the experience further with the ability to integrate local languages, creating a truly inclusive payment solution.</td></tr><tr><td><a href="/files/Us9HbXHZjiMUXAizn8OO">/files/Us9HbXHZjiMUXAizn8OO</a></td><td><strong>Consistent:</strong> Enjoy a singular and consistent payment experience across platforms, whether on the web, Android, or iOS. Driven by smart payment forms, minimal redirections, and intelligent retries, the Unified Checkout ensures a reliable and uniform payment process.</td></tr><tr><td><a href="/files/gLu96LykMhTz9C74k3B9">/files/gLu96LykMhTz9C74k3B9</a></td><td><strong>Blended:</strong> Tailor the payment experience to seamlessly integrate with your product using 40+ styling APIs. Achieve a fully native and embedded payment experience within your iOS app or website, creating a cohesive and branded checkout environment.</td></tr></tbody></table>

**Modify and Experiment:** While the Unified Checkout is pre-optimized for maximum conversions, the Hyperswitch iOS SDK empowers you to go beyond the standard. Take control with our SDK APIs, allowing you to:

* **Include New Fields:** Adapt swiftly to various use cases by adding new fields to the payment form, such as collecting billing addresses or zip codes for additional information.
* **Prioritize Payment Methods:** Impact your payment mix and conversion rates by prioritizing or promoting specific payment methods based on your customer preferences.
* **Switch Themes and Layouts:** Choose from a wide range of pre-designed themes and layouts for the checkout page, aligning the Unified Checkout with your app's aesthetics.

Experience the flexibility to modify and experiment, ensuring your app's payment journey aligns precisely with your business requirements and user expectations. Elevate your iOS app's payment experience with the Hyperswitch iOS SDK.




---

[Next Page](/llms-full.txt/1)

