Giter VIP home page Giter VIP logo

juspay / hyperswitch Goto Github PK

View Code? Open in Web Editor NEW
10.4K 61.0 1.2K 39.83 MB

An open source payments switch written in Rust to make payments fast, reliable and affordable

Home Page: https://hyperswitch.io/

License: Apache License 2.0

Makefile 0.01% Rust 72.63% Shell 0.18% PLpgSQL 0.37% Dockerfile 0.02% JavaScript 23.87% Nix 2.51% CSS 0.11% HTML 0.30%
payments rust orchestration hacktoberfest beginner-friendly featured high-performance open-source restful-api sdk

hyperswitch's Introduction

Hyperswitch-Logo Hyperswitch-Logo

The open-source payments switch

The single API to access payment ecosystems across 130+ countries

Quick Start GuideLocal Setup GuideFast Integration for Stripe Users API Docs Supported Features
What's IncludedJoin us in building HyperSwitchCommunityBugs and feature requestsFAQsVersioningCopyright and License


Hyperswitch is a community-led, open payments switch to enable access to the best payments infrastructure for every digital business.

Using Hyperswitch, you can:

  • ⬇️ Reduce dependency on a single processor like Stripe or Braintree
  • 🧑‍💻 Reduce Dev effort by 90% to add & maintain integrations
  • 🚀 Improve success rates with seamless failover and auto-retries
  • 💸 Reduce processing fees with smart routing
  • 🎨 Customize payment flows with full visibility and control
  • 🌐 Increase business reach with local/alternate payment methods

Hyperswitch-Product

One-click deployment on AWS cloud

The fastest and easiest way to try Hyperswitch is via our CDK scripts

  1. Click on the following button for a quick standalone deployment on AWS, suitable for prototyping. No code or setup is required in your system and the deployment is covered within the AWS free-tier setup.

  2. Sign-in to your AWS console.

  3. Follow the instructions provided on the console to successfully deploy Hyperswitch

Run it on your system

You can run Hyperswitch on your system using Docker Compose after cloning this repository:

docker compose up -d

This will start the payments router, the primary component within Hyperswitch.

Check out the local setup guide for a more comprehensive setup, which includes the scheduler and monitoring services.

If you are already using Stripe, integrating with Hyperswitch is fun, fast & easy. Try the steps below to get a feel for how quick the setup is:

  1. Get API keys from our dashboard.
  2. Follow the instructions detailed on our documentation page.

🌟 Supported Payment Processors and Methods

As of Sept 2023, we support 50+ payment processors and multiple global payment methods. In addition, we are continuously integrating new processors based on their reach and community requests. Our target is to support 100+ processors by H2 2023. You can find the latest list of payment processors, supported methods, and features here.

🌟 Hosted Version

In addition to all the features of the open-source product, our hosted version provides features and support to manage your payment infrastructure, compliance, analytics, and operations end-to-end:

  • System Performance & Reliability

    • Scalable to support 50000 tps
    • System uptime of up to 99.99%
    • Deployment with very low latency
    • Hosting option with AWS or GCP
  • Value Added Services

    • Compliance Support, incl. PCI, GDPR, Card Vault etc
    • Customise the integration or payment experience
    • Control Center with elaborate analytics and reporting
    • Integration with Risk Management Solutions
    • Integration with other platforms like Subscription, E-commerce, Accounting, etc.
  • Enterprise Support

    • 24x7 Email / On-call Support
    • Dedicated Relationship Manager
    • Custom dashboards with deep analytics, alerts, and reporting
    • Expert team to consult and improve business metrics

You can try the hosted version in our sandbox.

Got more questions? Please refer to our FAQs page.

Within the repositories, you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations.

Repositories

The current setup contains a single repo, which contains the core payment router and the various connector integrations under the src/connector sub-directory.

🌳 Files Tree Layout

.
├── config                             : Initial startup config files for the router
├── connector-template                 : boilerplate code for connectors
├── crates                             : sub-crates
│   ├── api_models                     : Request/response models for the `router` crate
│   ├── cards                          : Types to handle card masking and validation
│   ├── common_enums                   : Enums shared across the request/response types and database types
│   ├── common_utils                   : Utilities shared across `router` and other crates
│   ├── data_models                    : Represents the data/domain models used by the business/domain layer
│   ├── diesel_models                  : Database models shared across `router` and other crates
│   ├── drainer                        : Application that reads Redis streams and executes queries in database
│   ├── external_services              : Interactions with external systems like emails, AWS KMS, etc.
│   ├── masking                        : Personal Identifiable Information protection
│   ├── redis_interface                : A user-friendly interface to Redis
│   ├── router                         : Main crate of the project
│   ├── router_derive                  : Utility macros for the `router` crate
│   ├── router_env                     : Environment of payment router: logger, basic config, its environment awareness
│   ├── scheduler                      : Scheduling and executing deferred tasks like mail scheduling
│   ├── storage_impl                   : Storage backend implementations for data structures & objects
│   └── test_utils                     : Utilities to run Postman and connector UI tests
├── docs                               : hand-written documentation
├── loadtest                           : performance benchmarking setup
├── migrations                         : diesel DB setup
├── monitoring                         : Grafana & Loki monitoring related configuration files
├── openapi                            : automatically generated OpenAPI spec
├── postman                            : postman scenarios API
└── scripts                            : automation, testing, and other utility scripts

🤝 Our Belief

Payments should be open, fast, reliable and affordable to serve the billions of people at scale.

Globally payment diversity has been growing at a rapid pace. There are hundreds of payment processors and new payment methods like BNPL, RTP etc. Businesses need to embrace this diversity to increase conversion, reduce cost and improve control. But integrating and maintaining multiple processors needs a lot of dev effort. Why should devs across companies repeat the same work? Why can't it be unified and reused? Hence, Hyperswitch was born to create that reusable core and let companies build and customise it as per their specific requirements.

✨ Our Values

  1. Embrace Payments Diversity: It will drive innovation in the ecosystem in multiple ways.
  2. Make it Open Source: Increases trust; Improves the quality and reusability of software.
  3. Be community driven: It enables participatory design and development.
  4. Build it like Systems Software: This sets a high bar for Reliability, Security and Performance SLAs.
  5. Maximise Value Creation: For developers, customers & partners.

🤍 Contributing

This project is being created and maintained by Juspay, South Asia's largest payments orchestrator/switch, processing more than 50 Million transactions per day. The solution has 1Mn+ lines of Haskell code built over ten years. Hyperswitch leverages our experience in building large-scale, enterprise-grade & frictionless payment solutions. It is built afresh for the global markets as an open-source product in Rust. We are long-term committed to building and making it useful for the community.

The product roadmap is open for the community's feedback. We shall evolve a prioritisation process that is open and community-driven. We welcome contributions from the community. Please read through our contributing guidelines. Included are directions for opening issues, coding standards, and notes on development.

  • We appreciate all types of contributions: code, documentation, demo creation, or some new way you want to contribute to us. We will reward every contribution with a Hyperswitch branded t-shirt.
  • 🦀 Important note for Rust developers: We aim for contributions from the community across a broad range of tracks. Hence, we have prioritised simplicity and code readability over purely idiomatic code. For example, some of the code in core functions (e.g., payments_core) is written to be more readable than pure-idiomatic.

Get updates on Hyperswitch development and chat with the community:

  • Discord server for questions related to contributing to hyperswitch, questions about the architecture, components, etc.
  • Slack workspace for questions related to integrating hyperswitch, integrating a connector in hyperswitch, etc.
  • GitHub Discussions to drop feature requests or suggest anything payments-related you need for your stack.

Please read the issue guidelines and search for existing and closed issues. If your problem or idea is not addressed yet, please open a new issue.

Check the CHANGELOG.md file for details.

This product is licensed under the Apache 2.0 License.

Thank you for your support in hyperswitch's growth. Keep up the great work! 🥂

Contributors

hyperswitch's People

Contributors

abhicodes-crypto avatar akshayafoiger avatar apoorvdixit88 avatar aprabhat19 avatar arjunkarthik avatar chethan-rao avatar deepanshu-iiitu avatar dracarys18 avatar github-actions[bot] avatar hrithikesh026 avatar jagan-jaya avatar kashif-m avatar lsampras avatar manoj-juspay avatar narayanbhat166 avatar nishantjoshi00 avatar pixincreate avatar prajjwalkumar17 avatar prasunna09 avatar sahkal avatar sai-harsha-vardhan avatar sakilmostak avatar samraatbansal avatar sanchithhegde avatar sangamesh26 avatar shankarsinghc avatar srujanchikke avatar swangi-kumari avatar thisismani avatar vspecky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hyperswitch's Issues

[FEATURE] Schedule webhook for retry

Description

Refactor webhooks core to add retry logic in webhooks core.

Currently, we store information about whether we have sent a webhook or not, improving on this we can implement retry logic to make this more reliable

Cybersource Connector Checklist

Payment Flows

  • Authorize
    • Automatic #154
    • Manual
  • Payment Sync
  • Void
  • Refund
  • Refund Sync
  • Redirect Flow
  • Webhooks

Payment Methods

  • Card

Authentication

  • Add support for a way to get 3 values from keys.conf for http-signature support #69

Miscellaneous

  • Tests
  • Error Handling with error codes

Make KV storage flow more generic

Model the KV storage flow as a series of common operations (For example, set in redis -> get sql query -> push query to redis stream) and define generic utilities that perform these operations for all KV-enabled storage interfaces (as opposed to rewriting code).

Use `masking` for sensitive data

Architecture: use newtype pattern

https://github.com/juspay/orca/blob/01cafe753bc4ea0cf33ec604dcbe0017abfebcad/crates/common_utils/src/pii.rs#L68

We should assume constructed value object is already validated. Email validation is quite a heavy operation. Doing it on each formatting is quite a subtle performance penalty, while being... unnecessary?
Another problem, that validation here is violation of the "Separation of concerns" design principle. Formatting is not a validation in any way. https://en.wikipedia.org/wiki/Separation_of_concerns Consider to provide a newtype for email strings. https://rust-unofficial.github.io/patterns/patterns/behavioural/newtype.html

This way you do the validation only once, when creating a value of the type, and then you may fearlessly reuse it as the type system protects you. https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate
Thus, as the result, you will be able to remove any validation code from the formatting, as the compiler will guarantee that you would have valid values here. The same is true for other formatting strategies in this module too, as they're effectively validators too.

https://github.com/juspay/orca/blob/56d153d8f7c2c75391799cf14280c448df97842f/crates/router/src/connector/adyen/transformers.rs#L309

CVC shouldn't be saved in our db Will need to implement tokenization that allows us to make payments without cvv
And this could be easily prevented if it was represented as a newtype for value object which doesn't implement ToSql.

Consistency Flaws: Races and Outages should be considered

possible race condition here. what if a concurrent user updates parent merchant between this operation and the following?
https://github.com/juspay/orca/blob/56d153d8f7c2c75391799cf14280c448df97842f/crates/router/src/core/admin.rs#L74-L79

possible race condition here. what if a concurrent user updates merchant account between this read and the last write?
https://github.com/juspay/orca/blob/56d153d8f7c2c75391799cf14280c448df97842f/crates/router/src/core/admin.rs#L148-L153

possible race condition here. what if a concurrent user updates parent merchant between this operation and the following?
https://github.com/juspay/orca/blob/56d153d8f7c2c75391799cf14280c448df97842f/crates/router/src/core/admin.rs#L205-L212

What if the application process would be killed after successful execution of delete_payment_method_by_merchant_id_payment_method_id(), but before executing delete_card()? Would be the card ever deleted? Seems like the system has weak consistency guarantees.

https://docs.diesel.rs/diesel/connection/trait.Connection.html#method.transaction

https://github.com/juspay/orca/blob/56d153d8f7c2c75391799cf14280c448df97842f/crates/router/src/core/payment_methods/cards.rs#L430-L434

Sync Open API specifications with latest additions

The Open API specification needs to be updated to sync with:

  • newly implemented APIs such as /session and /verify
  • the addition/ changes in parameters of existing APIs shall also be modified in the specifications
  • payment status fields, description and significance
  • documentation of all possible API errors, explanation and significance
  • documentation of all webhook events with explanation
  • include the health check endpoint (/health) in the spec

feat(db): Implement interfaces for `MockDb`

Description

This issue's primary focus lies in implementing the pending interface functionality for MockDb. The purpose of this change is to have a simple and effective mechanism for testing without connecting to any outside entity for the storage need. The MockDb will come in play for unit tests, integration tests, etc.

Interfaces to implement

If you're interested in picking up any item from the list, please let us know. We'll spin out an issue and assign it to you.

Braintree Connector Checklist

Payment Flows

  • Authorize
    • Automatic #30
    • Manual
  • Payment Sync #30 #73
  • Void #73
  • Refund #73
    • Partial Refund
  • Refund Sync
  • Redirect Flow
  • Webhooks

Payment Methods

  • Card #30
  • Wallet

Miscellaneous

  • Tests
  • Error Handling with error codes
    • Reverse engineer response and find Error Code
    • Map Braintree error codes and send appropriate messages

feat: Implement all of stripe error codes & internal mapping between `ApiErrorResponse`

Description

Currently in the stripe compatibility layer all the error codes defined are limited and are the one's that we directly need to map with stripe. Though moving forward as the compatibility layer continues to develop we might need to keep adding new error codes from the stripe documentation.

Use `frunk` deriving mechanisms to reduce boilerplate

https://github.com/juspay/orca/blob/dddc9eaf1430adcd1293933e726c2f4f296c805b/crates/router/src/types/transformers.rs#L5-L14

Why not just use frunk?

Here's an example:

use frunk::LabelledGeneric;

#[derive(LabelledGeneric)]
enum ApiRoutingAlgorithm {
    RoundRobin,
    MaxConversion,
    MinCost,
    Custom,
}

#[derive(LabelledGeneric, PartialEq, Debug)]
enum RoutingAlgorithm {
    RoundRobin,
    MaxConversion,
    MinCost,
    Custom,
}

fn main() {
    let api_algorithm = ApiRoutingAlgorithm::MinCost;
    let algorithm: RoutingAlgorithm = frunk::labelled_convert_from(api_algorithm);

    assert_eq!(algorithm, RoutingAlgorithm::MinCost);
}

Nix Support

Nix support for orca:

  • Dev shell to include all the required tools, setup
  • Build with nix flakes
  • CI/CD with nix flakes

Feat: Ability to accept 3 values in ConnectorAuthType

Currently we support max 2 values from keys.conf / db

pub enum ConnectorAuthType {
    HeaderKey { api_key: String },
    BodyKey { api_key: String, key1: String },
}

I'm trying to integrate Cybersource, it requires http signatures.

I will need 3 values

  • Merchant Id
  • Api Key
  • Api Secret

With these I'm able to generate the http signature headers, like

digest: "SHA-256=cwjLNSMNo0IFp7hbUtTNu+7KxaF9O67ydqKWMnQ7J5g="
signature: 'keyid="5476633e-eff2-4e65-9834-58081207dd61", algorithm="HmacSHA256", headers="host (request-target) digest v-c-merchant-id", signature="djnWLdaLRh8xtWLCXxGIlavyRG4jBvB7gIzUWTKzPoQ="'

So I'm proposing

pub enum ConnectorAuthType {
    HeaderKey { api_key: String },
    BodyKey { api_key: String, key1: String },
    SignatureKey { api_key: String, key1: String, api_secret: String },
}

@SanchithHegde @Narayanbhat166 @jarnura

I can add the PR for it.

referring #58

docs(CONTRIBUTING): add information about tests and community links

This issue serves an extension of #9; the following pieces of information are yet to be added to the contributing guidelines:

  • Tests
  • Versioning policy
  • Release process
  • Links to Discord/Slack communities #310
  • Process to bump MSRV (Optional)

I'll briefly jot down what I feel are necessary with respect to each of the items.

Tests

  • Specify what type of changes require tests. Example: new features, bug fixes, connector integrations, etc.
  • Specify where to place unit/integration/documentation/API tests. (Of course documentation tests would be alongside documentation.)
  • Specify how to run tests, especially when external tools are involved (anything other than cargo).

Versioning Policy

  • It would be better if we can provide certain guarantees to the users of our APIs, that our APIs won't change behavior between certain types of releases.
  • Specify what changes can be expected between major, minor and patch releases.
  • If possible, try to follow SemVer strictly.

Release Process

  • This is targeted primarily at maintainers, but aims to serve as a checklist to refer to before publishing releases.
  • List out each of the steps in detail. These could include:
    • Bumping up versions
    • Updating Cargo metadata
    • Updating links on documentation pages
    • Updating changelog files
    • Review changes
    • Open PR
    • Release

Now that I think of the release process, I'm wondering if we should also document the steps to take when bumping up MSRV.

Links to Discord/Slack communities

  • As of now, users can use the GitHub Discussions space on our repository to interact with the project maintainers. But a more organized space is necessary; two of the potential candidates are a Discord server and a Slack workspace.
  • Both of these spaces exist as of creating this issue, but require a bit of "initial setup" before people can be invited in there.

primary key violates unique constraint upon sending lots of create payment requests with the same customer id

Discovered while running payment-confirm loadtesting script.

Log:

{
  ...
  "flow":"PaymentsCreate",
  "extra":{
    "api_authentication":"ApiKey",
    "error":"{\"error\":{\"type\":\"server_not_available\",\"code\":\"RE_00\",\"message\":\"Something went wrong.\"}}\n├╴crates/router/src/core/payments.rs:96:10\n│\n├─▶ DatabaseError: A unique constraint violation occurred\n│   ├╴crates/router/src/types/storage/query/generics.rs:168:22\n│   ╰╴Error while inserting CustomerNew { customer_id: \"StripeCustomer\", merchant_id: \"merchant_1669119076606\", name: Some(\"John Doe\"), email: Some(*****@example.com), phone: Some(*** alloc::string::String ***), description: None, phone_country_code: Some(\"+65\"), address: None, metadata: None }\n│\n╰─▶ Failed to issue a query: duplicate key value violates unique constraint \"customers_pkey\"\n    ╰╴crates/router/src/types/storage/query/generics.rs:167:27",
    "http.client_ip":"192.168.48.10",
    "http.flavor":"1.1",
    "http.host":"router-server:8080",
    "http.method":"POST",
    "http.route":"/payments"
    ...
  }
}

Steps to reproduce:
check out rnd-loadtest-failing-requests branch
I made a minor change which gives us access to logs of the router container.
once you checked out the branch:

cd loadtest
docker compose build # will take some time
bash loadtest.sh -s payment-confirm

the last command will give you something like http_req_failed................: 0.18% ✓ 7 ✗ 3718 in the end. The numbers could be different. Those 7 requests are failed.

You can access the logs stored at loadtest/logs.tmp/logs. Search for "server_not_available" string in it.

Notes:

  1. Those customer queries need to be in a single transaction but currently we are not using pgdb as a relational storage so that would not be a good solution.

Possible solutions:

  1. We implement api level locking in future, that will handle parallel request errors. (cc @jarnura)

Fix `RouterData`'s `response` construction before calling the connector

Visible issue:

  • There are a few cases on response construction and using fields from router_data.response while building request, which is logically invalid.

Changes required:

  • Check inconsistencies and make the connector request construction purely dependent on the router_data and router_data.request
  • Constructing the router_data.response only after calling the connector

Consider adding `#![forbid(unsafe_code)]`

Here and in any other crate roots it's better to declare #![forbid(unsafe_code)] as we do in masking crate. This will ease a life of readers and auditors a lot, and will require quite a reasoning for those who will intend to contribute any unsafe code.

perf(logger): Remove unnecessary heap allocations

Use here, below, and in similar places, theformat_args!() macro instead, to omit redundant allocations produced by the format!() macro (as it returns a new String).

https://github.com/juspay/orca/blob/01cafe753bc4ea0cf33ec604dcbe0017abfebcad/crates/router_env/src/logger/formatter.rs#L207
https://github.com/juspay/orca/blob/01cafe753bc4ea0cf33ec604dcbe0017abfebcad/crates/router_env/src/logger/formatter.rs#L213

Redundant allocation on heap. This code produces the redundant String allocation as the result of format!() macro call. Omit it by writing into the formatter directly with write!() macro:

::core::write!(f, "{:?}", self)

https://github.com/juspay/orca/blob/01cafe753bc4ea0cf33ec604dcbe0017abfebcad/crates/router_derive/src/macros.rs#L23

This code contains redundant heap allocation .to_string() allocations, because we can write directly into the formatter:

write!(f, "{}", serde_json::json!({"error": &self.err }))

https://github.com/juspay/orca/blob/01cafe753bc4ea0cf33ec604dcbe0017abfebcad/crates/router/src/utils.rs#L37-L42

Checklist

Generic Response for RouterData

Since we will be integrating different payment methods, they might have varying requirements with respect to the api calls, request and response structs. For calling connectors to support these, the response struct must also need to be generic and dependent on the flow. Currently RouterData supports only PaymentsResponseData.

@jarnura @NishantJoshi00

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.