From 7d8d68faba55dfcb2886c63ae7969ebd4b9ec98c Mon Sep 17 00:00:00 2001 From: Narayan Bhat <48803246+Narayanbhat166@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:20:43 +0530 Subject: [PATCH] refactor(openapi): move openapi to separate crate to decrease compile times (#3110) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Sai Harsha Vardhan <56996463+sai-harsha-vardhan@users.noreply.github.com> Co-authored-by: Sahkal Poddar Co-authored-by: Amisha Prabhat <55580080+Aprabhat19@users.noreply.github.com> Co-authored-by: Sarthak Soni <76486416+Sarthak1799@users.noreply.github.com> Co-authored-by: shashank_attarde Co-authored-by: Aprabhat19 Co-authored-by: sai-harsha-vardhan Co-authored-by: Sahkal Poddar Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com> --- .github/workflows/validate-openapi-spec.yml | 2 +- Cargo.lock | 84 +- crates/api_models/Cargo.toml | 3 +- crates/api_models/src/admin.rs | 258 +- crates/api_models/src/enums.rs | 3 +- crates/api_models/src/gsm.rs | 47 + crates/api_models/src/payment_methods.rs | 6 +- crates/api_models/src/payments.rs | 163 +- crates/api_models/src/refunds.rs | 31 +- crates/api_models/src/routing.rs | 43 +- crates/api_models/src/webhooks.rs | 8 +- crates/common_enums/Cargo.toml | 1 + crates/common_enums/src/enums.rs | 11 +- crates/common_utils/src/macros.rs | 12 + crates/euclid/Cargo.toml | 1 + crates/euclid/src/frontend/ast.rs | 53 +- crates/openapi/Cargo.toml | 14 + crates/openapi/src/lib.rs | 2 + crates/openapi/src/main.rs | 15 + crates/{router => openapi}/src/openapi.rs | 369 +- crates/openapi/src/routes.rs | 26 + crates/openapi/src/routes/api_keys.rs | 80 + crates/openapi/src/routes/blocklist.rs | 43 + crates/openapi/src/routes/business_profile.rs | 124 + crates/openapi/src/routes/customers.rs | 102 + crates/openapi/src/routes/disputes.rs | 44 + crates/openapi/src/routes/gsm.rs | 75 + crates/openapi/src/routes/mandates.rs | 61 + crates/openapi/src/routes/merchant_account.rs | 125 + .../src/routes/merchant_connector_account.rs | 170 + crates/openapi/src/routes/payment_link.rs | 19 + crates/openapi/src/routes/payment_method.rs | 173 + crates/openapi/src/routes/payments.rs | 452 ++ crates/openapi/src/routes/payouts.rs | 85 + crates/openapi/src/routes/refunds.rs | 145 + crates/openapi/src/routes/routing.rs | 202 + crates/router/Cargo.toml | 5 +- crates/router/src/bin/router.rs | 18 - crates/router/src/lib.rs | 11 +- crates/router/src/routes/app.rs | 2 +- crates/router/src/routes/customers.rs | 77 +- crates/router/src/routes/mandates.rs | 6 +- crates/router/src/routes/payment_methods.rs | 95 +- crates/router/src/routes/payments.rs | 8 +- crates/router/src/routes/routing.rs | 2 +- crates/router_derive/src/lib.rs | 5 +- .../src/macros/generate_schema.rs | 180 +- openapi/openapi_spec.json | 4356 +++++++++++++++-- 48 files changed, 6620 insertions(+), 1197 deletions(-) create mode 100644 crates/openapi/Cargo.toml create mode 100644 crates/openapi/src/lib.rs create mode 100644 crates/openapi/src/main.rs rename crates/{router => openapi}/src/openapi.rs (65%) create mode 100644 crates/openapi/src/routes.rs create mode 100644 crates/openapi/src/routes/api_keys.rs create mode 100644 crates/openapi/src/routes/blocklist.rs create mode 100644 crates/openapi/src/routes/business_profile.rs create mode 100644 crates/openapi/src/routes/customers.rs create mode 100644 crates/openapi/src/routes/disputes.rs create mode 100644 crates/openapi/src/routes/gsm.rs create mode 100644 crates/openapi/src/routes/mandates.rs create mode 100644 crates/openapi/src/routes/merchant_account.rs create mode 100644 crates/openapi/src/routes/merchant_connector_account.rs create mode 100644 crates/openapi/src/routes/payment_link.rs create mode 100644 crates/openapi/src/routes/payment_method.rs create mode 100644 crates/openapi/src/routes/payments.rs create mode 100644 crates/openapi/src/routes/payouts.rs create mode 100644 crates/openapi/src/routes/refunds.rs create mode 100644 crates/openapi/src/routes/routing.rs diff --git a/.github/workflows/validate-openapi-spec.yml b/.github/workflows/validate-openapi-spec.yml index bdb987d625..210f820648 100644 --- a/.github/workflows/validate-openapi-spec.yml +++ b/.github/workflows/validate-openapi-spec.yml @@ -52,7 +52,7 @@ jobs: - name: Generate the OpenAPI spec file shell: bash - run: cargo run --features openapi -- generate-openapi-spec + run: cargo run -p openapi - name: Install `swagger-cli` shell: bash diff --git a/Cargo.lock b/Cargo.lock index 5623fd9f72..f920b1ea9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2435,6 +2435,7 @@ dependencies = [ "serde_json", "strum 0.25.0", "thiserror", + "utoipa", ] [[package]] @@ -4043,6 +4044,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openapi" +version = "0.1.0" +dependencies = [ + "api_models", + "serde_json", + "utoipa", +] + [[package]] name = "openssl" version = "0.10.60" @@ -5185,6 +5195,7 @@ dependencies = [ "nanoid", "num_cpus", "once_cell", + "openapi", "openssl", "pm_auth", "qrcode", @@ -5222,7 +5233,6 @@ dependencies = [ "unicode-segmentation", "url", "utoipa", - "utoipa-swagger-ui", "uuid", "validator", "wiremock", @@ -5279,41 +5289,6 @@ dependencies = [ "xmlparser", ] -[[package]] -name = "rust-embed" -version = "6.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" -dependencies = [ - "rust-embed-impl", - "rust-embed-utils", - "walkdir", -] - -[[package]] -name = "rust-embed-impl" -version = "6.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" -dependencies = [ - "proc-macro2", - "quote", - "rust-embed-utils", - "shellexpand", - "syn 2.0.48", - "walkdir", -] - -[[package]] -name = "rust-embed-utils" -version = "7.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" -dependencies = [ - "sha2", - "walkdir", -] - [[package]] name = "rust-ini" version = "0.18.0" @@ -5866,15 +5841,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shellexpand" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" -dependencies = [ - "dirs", -] - [[package]] name = "signal-hook" version = "0.3.17" @@ -7237,22 +7203,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "utoipa-swagger-ui" -version = "3.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84614caa239fb25b2bb373a52859ffd94605ceb256eeb1d63436325cf81e3653" -dependencies = [ - "actix-web", - "mime_guess", - "regex", - "rust-embed", - "serde", - "serde_json", - "utoipa", - "zip", -] - [[package]] name = "uuid" version = "1.4.1" @@ -7820,18 +7770,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" -[[package]] -name = "zip" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" -dependencies = [ - "byteorder", - "crc32fast", - "crossbeam-utils 0.8.16", - "flate2", -] - [[package]] name = "zstd" version = "0.12.4" diff --git a/crates/api_models/Cargo.toml b/crates/api_models/Cargo.toml index d1f603f188..8cd3ee53f2 100644 --- a/crates/api_models/Cargo.toml +++ b/crates/api_models/Cargo.toml @@ -18,6 +18,7 @@ dummy_connector = ["euclid/dummy_connector", "common_enums/dummy_connector"] detailed_errors = [] payouts = [] frm = [] +openapi = ["common_enums/openapi"] recon = [] [dependencies] @@ -39,5 +40,5 @@ cards = { version = "0.1.0", path = "../cards" } common_enums = { path = "../common_enums" } common_utils = { version = "0.1.0", path = "../common_utils" } euclid = { version = "0.1.0", path = "../euclid" } -masking = { version = "0.1.0", path = "../masking" } +masking = { version = "0.1.0", path = "../masking", default-features = false, features = ["alloc", "serde"] } router_derive = { version = "0.1.0", path = "../router_derive" } diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 134beacd22..68ee6cb48b 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -32,7 +32,7 @@ pub struct MerchantAccountCreate { #[schema(value_type= Option,example = "NewAge Retailer")] pub merchant_name: Option>, - /// Merchant related details + /// Details about the merchant pub merchant_details: Option, /// The URL to redirect after the completion of the operation @@ -43,7 +43,8 @@ pub struct MerchantAccountCreate { pub webhook_details: Option, /// The routing algorithm to be used for routing payments to desired connectors - #[schema(value_type = Option,example = json!({"type": "single", "data": "stripe"}))] + #[serde(skip)] + #[schema(deprecated)] pub routing_algorithm: Option, /// The routing algorithm to be used for routing payouts to desired connectors @@ -67,8 +68,7 @@ pub struct MerchantAccountCreate { #[schema(default = false, example = true)] pub enable_payment_response_hash: Option, - /// Refers to the hash key used for calculating the signature for webhooks and redirect response - /// If the value is not provided, a default value is used + /// Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used. pub payment_response_hash_key: Option, /// A boolean value to indicate if redirect to merchant with http post needs to be enabled @@ -87,7 +87,7 @@ pub struct MerchantAccountCreate { #[schema(example = "locker_abc123")] pub locker_id: Option, - ///Default business details for connector routing + /// Details about the primary business unit of the merchant account #[schema(value_type = Option)] pub primary_business_details: Option>, @@ -117,7 +117,7 @@ pub struct MerchantAccountUpdate { #[schema(example = "NewAge Retailer")] pub merchant_name: Option, - /// Merchant related details + /// Details about the merchant pub merchant_details: Option, /// The URL to redirect after the completion of the operation @@ -128,10 +128,11 @@ pub struct MerchantAccountUpdate { pub webhook_details: Option, /// The routing algorithm to be used for routing payments to desired connectors - #[schema(value_type = Option,example = json!({"type": "single", "data": "stripe"}))] + #[serde(skip)] + #[schema(deprecated)] pub routing_algorithm: Option, - /// The routing algorithm to be used for routing payouts to desired connectors + /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' #[cfg(feature = "payouts")] #[schema(value_type = Option,example = json!({"type": "single", "data": "wise"}))] #[serde( @@ -152,7 +153,7 @@ pub struct MerchantAccountUpdate { #[schema(default = false, example = true)] pub enable_payment_response_hash: Option, - /// Refers to the hash key used for payment response + /// Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used. pub payment_response_hash_key: Option, /// A boolean value to indicate if redirect to merchant with http post needs to be enabled @@ -171,7 +172,7 @@ pub struct MerchantAccountUpdate { #[schema(example = "locker_abc123")] pub locker_id: Option, - ///Default business details for connector routing + /// Details about the primary business unit of the merchant account pub primary_business_details: Option>, /// The frm routing algorithm to be used for routing payments to desired FRM's @@ -202,7 +203,7 @@ pub struct MerchantAccountResponse { #[schema(default = false, example = true)] pub enable_payment_response_hash: bool, - /// Refers to the Parent Merchant ID if the merchant being created is a sub-merchant + /// Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used. #[schema(max_length = 255, example = "xkkdf909012sdjki2dkh5sdf")] pub payment_response_hash_key: Option, @@ -210,7 +211,7 @@ pub struct MerchantAccountResponse { #[schema(default = false, example = true)] pub redirect_to_merchant_with_http_post: bool, - /// Merchant related details + /// Details about the merchant #[schema(value_type = Option)] pub merchant_details: Option>, @@ -219,10 +220,11 @@ pub struct MerchantAccountResponse { pub webhook_details: Option, /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' - #[schema(value_type = Option, max_length = 255, example = "custom")] + #[serde(skip)] + #[schema(deprecated)] pub routing_algorithm: Option, - /// The routing algorithm to be used for routing payouts to desired connectors + /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' #[cfg(feature = "payouts")] #[schema(value_type = Option,example = json!({"type": "single", "data": "wise"}))] #[serde( @@ -250,7 +252,8 @@ pub struct MerchantAccountResponse { /// An identifier for the vault used to store payment method information. #[schema(example = "locker_abc123")] pub locker_id: Option, - ///Default business details for connector routing + + /// Details about the primary business unit of the merchant account #[schema(value_type = Vec)] pub primary_business_details: Vec, @@ -272,7 +275,7 @@ pub struct MerchantAccountResponse { #[schema(max_length = 64)] pub default_profile: Option, - /// A enum value to indicate the status of recon service. By default it is not_requested. + /// Used to indicate the status of the recon module for a merchant account #[schema(value_type = ReconStatus, example = "not_requested")] pub recon_status: enums::ReconStatus, } @@ -508,23 +511,18 @@ pub struct MerchantConnectorCreate { /// Name of the Connector #[schema(value_type = Connector, example = "stripe")] pub connector_name: api_enums::Connector, - /// Connector label for a connector, this can serve as a field to identify the connector as per business details + /// This is an unique label you can generate and pass in order to identify this connector account on your Hyperswitch dashboard and reports. Eg: if your profile label is `default`, connector label can be `stripe_default` #[schema(example = "stripe_US_travel")] pub connector_label: Option, - /// Unique ID of the connector - #[schema(example = "mca_5apGeP94tMts6rg3U3kR")] - pub merchant_connector_id: Option, - /// Account details of the Connector. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Useful for storing additional, structured information on an object. - #[schema(value_type = Option,example = json!({ "auth_type": "HeaderKey","api_key": "Basic MyVerySecretApiKey" }))] + /// Identifier for the business profile, if not provided default will be chosen from merchant account + pub profile_id: Option, + + /// An object containing the required details/credentials for a Connector account. + #[schema(value_type = Option,example = json!({ "auth_type": "HeaderKey","api_key": "Basic MyVerySecretApiKey" }))] pub connector_account_details: Option, - /// A boolean value to indicate if the connector is in Test mode. By default, its value is false. - #[schema(default = false, example = false)] - pub test_mode: Option, - /// A boolean value to indicate if the connector is disabled. By default, its value is false. - #[schema(default = false, example = false)] - pub disabled: Option, - /// Refers to the Parent Merchant ID if the merchant being created is a sub-merchant + + /// An object containing the details about the payment methods that need to be enabled under this merchant connector account #[schema(example = json!([ { "payment_method": "wallet", @@ -555,21 +553,6 @@ pub struct MerchantConnectorCreate { } ]))] pub payment_methods_enabled: Option>, - /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. - #[schema(value_type = Option,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))] - pub metadata: Option, - /// contains the frm configs for the merchant connector - #[schema(example = json!(common_utils::consts::FRM_CONFIGS_EG))] - pub frm_configs: Option>, - - #[schema(value_type = Option, example = "US")] - pub business_country: Option, - - pub business_label: Option, - - /// Business Sub label of the merchant - #[schema(example = "chase")] - pub business_sub_label: Option, /// Webhook details of this merchant connector #[schema(example = json!({ @@ -578,12 +561,41 @@ pub struct MerchantConnectorCreate { } }))] pub connector_webhook_details: Option, - /// Identifier for the business profile, if not provided default will be chosen from merchant account - pub profile_id: Option, + + /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. + #[schema(value_type = Option,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))] + pub metadata: Option, + + /// A boolean value to indicate if the connector is in Test mode. By default, its value is false. + #[schema(default = false, example = false)] + pub test_mode: Option, + + /// A boolean value to indicate if the connector is disabled. By default, its value is false. + #[schema(default = false, example = false)] + pub disabled: Option, + + /// Contains the frm configs for the merchant connector + #[schema(example = json!(common_utils::consts::FRM_CONFIGS_EG))] + pub frm_configs: Option>, + + /// The business country to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead + #[schema(value_type = Option, example = "US")] + pub business_country: Option, + + /// The business label to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead + pub business_label: Option, + + /// The business sublabel to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead + #[schema(example = "chase")] + pub business_sub_label: Option, + + /// Unique ID of the connector + #[schema(example = "mca_5apGeP94tMts6rg3U3kR")] + pub merchant_connector_id: Option, pub pm_auth_config: Option, - #[schema(value_type = ConnectorStatus, example = "inactive")] + #[schema(value_type = Option, example = "inactive")] pub status: Option, } @@ -634,26 +646,26 @@ pub struct MerchantConnectorResponse { #[schema(value_type = ConnectorType, example = "payment_processor")] pub connector_type: api_enums::ConnectorType, /// Name of the Connector - #[schema(example = "stripe")] + #[schema(value_type = Connector, example = "stripe")] pub connector_name: String, - /// Connector label for a connector, this can serve as a field to identify the connector as per business details + /// A unique label to identify the connector account created under a business profile #[schema(example = "stripe_US_travel")] pub connector_label: Option, - /// Unique ID of the connector + /// Unique ID of the merchant connector account #[schema(example = "mca_5apGeP94tMts6rg3U3kR")] pub merchant_connector_id: String, - /// Account details of the Connector. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Useful for storing additional, structured information on an object. - #[schema(value_type = Option,example = json!({ "auth_type": "HeaderKey","api_key": "Basic MyVerySecretApiKey" }))] + + /// Identifier for the business profile, if not provided default will be chosen from merchant account + #[schema(max_length = 64)] + pub profile_id: Option, + + /// An object containing the required details/credentials for a Connector account. + #[schema(value_type = Option,example = json!({ "auth_type": "HeaderKey","api_key": "Basic MyVerySecretApiKey" }))] pub connector_account_details: pii::SecretSerdeValue, - /// A boolean value to indicate if the connector is in Test mode. By default, its value is false. - #[schema(default = false, example = false)] - pub test_mode: Option, - /// A boolean value to indicate if the connector is disabled. By default, its value is false. - #[schema(default = false, example = false)] - pub disabled: Option, - /// Refers to the Parent Merchant ID if the merchant being created is a sub-merchant + + /// An object containing the details about the payment methods that need to be enabled under this merchant connector account #[schema(example = json!([ { "payment_method": "wallet", @@ -684,25 +696,6 @@ pub struct MerchantConnectorResponse { } ]))] pub payment_methods_enabled: Option>, - /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. - #[schema(value_type = Option,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))] - pub metadata: Option, - - /// Business Country of the connector - #[schema(value_type = Option, example = "US")] - pub business_country: Option, - - ///Business Type of the merchant - #[schema(example = "travel")] - pub business_label: Option, - - /// Business Sub label of the merchant - #[schema(example = "chase")] - pub business_sub_label: Option, - - /// contains the frm configs for the merchant connector - #[schema(example = json!(common_utils::consts::FRM_CONFIGS_EG))] - pub frm_configs: Option>, /// Webhook details of this merchant connector #[schema(example = json!({ @@ -712,10 +705,34 @@ pub struct MerchantConnectorResponse { }))] pub connector_webhook_details: Option, - /// The business profile this connector must be created in - /// default value from merchant account is taken if not passed - #[schema(max_length = 64)] - pub profile_id: Option, + /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. + #[schema(value_type = Option,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))] + pub metadata: Option, + + /// A boolean value to indicate if the connector is in Test mode. By default, its value is false. + #[schema(default = false, example = false)] + pub test_mode: Option, + + /// A boolean value to indicate if the connector is disabled. By default, its value is false. + #[schema(default = false, example = false)] + pub disabled: Option, + + /// Contains the frm configs for the merchant connector + #[schema(example = json!(common_utils::consts::FRM_CONFIGS_EG))] + pub frm_configs: Option>, + + /// The business country to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead + #[schema(value_type = Option, example = "US")] + pub business_country: Option, + + ///The business label to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead + #[schema(example = "travel")] + pub business_label: Option, + + /// The business sublabel to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead + #[schema(example = "chase")] + pub business_sub_label: Option, + /// identifier for the verified domains of a particular connector account pub applepay_verified_domains: Option>, @@ -733,22 +750,15 @@ pub struct MerchantConnectorUpdate { #[schema(value_type = ConnectorType, example = "payment_processor")] pub connector_type: api_enums::ConnectorType, - /// Connector label for a connector, this can serve as a field to identify the connector as per business details + /// This is an unique label you can generate and pass in order to identify this connector account on your Hyperswitch dashboard and reports. Eg: if your profile label is `default`, connector label can be `stripe_default` + #[schema(example = "stripe_US_travel")] pub connector_label: Option, - /// Account details of the Connector. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Useful for storing additional, structured information on an object. - #[schema(value_type = Option,example = json!({ "auth_type": "HeaderKey","api_key": "Basic MyVerySecretApiKey" }))] + /// An object containing the required details/credentials for a Connector account. + #[schema(value_type = Option,example = json!({ "auth_type": "HeaderKey","api_key": "Basic MyVerySecretApiKey" }))] pub connector_account_details: Option, - /// A boolean value to indicate if the connector is in Test mode. By default, its value is false. - #[schema(default = false, example = false)] - pub test_mode: Option, - - /// A boolean value to indicate if the connector is disabled. By default, its value is false. - #[schema(default = false, example = false)] - pub disabled: Option, - - /// Refers to the Parent Merchant ID if the merchant being created is a sub-merchant + /// An object containing the details about the payment methods that need to be enabled under this merchant connector account #[schema(example = json!([ { "payment_method": "wallet", @@ -780,14 +790,6 @@ pub struct MerchantConnectorUpdate { ]))] pub payment_methods_enabled: Option>, - /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. - #[schema(value_type = Option,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))] - pub metadata: Option, - - /// contains the frm configs for the merchant connector - #[schema(example = json!(common_utils::consts::FRM_CONFIGS_EG))] - pub frm_configs: Option>, - /// Webhook details of this merchant connector #[schema(example = json!({ "connector_webhook_details": { @@ -796,6 +798,22 @@ pub struct MerchantConnectorUpdate { }))] pub connector_webhook_details: Option, + /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. + #[schema(value_type = Option,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))] + pub metadata: Option, + + /// A boolean value to indicate if the connector is in Test mode. By default, its value is false. + #[schema(default = false, example = false)] + pub test_mode: Option, + + /// A boolean value to indicate if the connector is disabled. By default, its value is false. + #[schema(default = false, example = false)] + pub disabled: Option, + + /// Contains the frm configs for the merchant connector + #[schema(example = json!(common_utils::consts::FRM_CONFIGS_EG))] + pub frm_configs: Option>, + pub pm_auth_config: Option, #[schema(value_type = ConnectorStatus, example = "inactive")] @@ -876,6 +894,7 @@ pub enum AcceptedCurrencies { content = "list", rename_all = "snake_case" )] +/// Object to filter the customer countries for which the payment method is displayed pub enum AcceptedCountries { #[schema(value_type = Vec)] EnableOnly(Vec), @@ -961,12 +980,11 @@ pub enum PayoutStraightThroughAlgorithm { #[derive(Clone, Debug, Deserialize, ToSchema, Default, Serialize)] #[serde(deny_unknown_fields)] pub struct BusinessProfileCreate { - /// A short name to identify the business profile + /// The name of business profile #[schema(max_length = 64)] pub profile_name: Option, - /// The URL to redirect after the completion of the operation, This will be applied to all the - /// connector accounts under this profile + /// The URL to redirect after the completion of the operation #[schema(value_type = Option, max_length = 255, example = "https://www.example.com/success")] pub return_url: Option, @@ -974,8 +992,7 @@ pub struct BusinessProfileCreate { #[schema(default = true, example = true)] pub enable_payment_response_hash: Option, - /// Refers to the hash key used for calculating the signature for webhooks and redirect response - /// If the value is not provided, a default value is used + /// Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used. pub payment_response_hash_key: Option, /// A boolean value to indicate if redirect to merchant with http post needs to be enabled @@ -1002,7 +1019,7 @@ pub struct BusinessProfileCreate { #[schema(value_type = Option,example = json!({"type": "single", "data": "signifyd"}))] pub frm_routing_algorithm: Option, - /// The routing algorithm to be used for routing payouts to desired connectors + /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' #[cfg(feature = "payouts")] #[schema(value_type = Option,example = json!({"type": "single", "data": "wise"}))] #[serde( @@ -1028,16 +1045,15 @@ pub struct BusinessProfileResponse { #[schema(max_length = 64, example = "y3oqhf46pyzuxjbcn2giaqnb44")] pub merchant_id: String, - /// The unique identifier for Business Profile + /// The default business profile that must be used for creating merchant accounts and payments #[schema(max_length = 64, example = "pro_abcdefghijklmnopqrstuvwxyz")] pub profile_id: String, - /// A short name to identify the business profile + /// Name of the business profile #[schema(max_length = 64)] pub profile_name: String, - /// The URL to redirect after the completion of the operation, This will be applied to all the - /// connector accounts under this profile + /// The URL to redirect after the completion of the operation #[schema(value_type = Option, max_length = 255, example = "https://www.example.com/success")] pub return_url: Option, @@ -1045,8 +1061,7 @@ pub struct BusinessProfileResponse { #[schema(default = true, example = true)] pub enable_payment_response_hash: bool, - /// Refers to the hash key used for calculating the signature for webhooks and redirect response - /// If the value is not provided, a default value is used + /// Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used. pub payment_response_hash_key: Option, /// A boolean value to indicate if redirect to merchant with http post needs to be enabled @@ -1054,6 +1069,7 @@ pub struct BusinessProfileResponse { pub redirect_to_merchant_with_http_post: bool, /// Webhook related details + #[schema(value_type = Option)] pub webhook_details: Option, /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object. @@ -1069,11 +1085,11 @@ pub struct BusinessProfileResponse { #[schema(example = 900)] pub intent_fulfillment_time: Option, - /// The frm routing algorithm to be used for routing payments to desired FRM's + /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' #[schema(value_type = Option,example = json!({"type": "single", "data": "signifyd"}))] pub frm_routing_algorithm: Option, - /// The routing algorithm to be used for routing payouts to desired connectors + /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' #[cfg(feature = "payouts")] #[schema(value_type = Option,example = json!({"type": "single", "data": "wise"}))] #[serde( @@ -1096,12 +1112,11 @@ pub struct BusinessProfileResponse { #[derive(Clone, Debug, Deserialize, ToSchema, Serialize)] #[serde(deny_unknown_fields)] pub struct BusinessProfileUpdate { - /// A short name to identify the business profile + /// The name of business profile #[schema(max_length = 64)] pub profile_name: Option, - /// The URL to redirect after the completion of the operation, This will be applied to all the - /// connector accounts under this profile + /// The URL to redirect after the completion of the operation #[schema(value_type = Option, max_length = 255, example = "https://www.example.com/success")] pub return_url: Option, @@ -1109,8 +1124,7 @@ pub struct BusinessProfileUpdate { #[schema(default = true, example = true)] pub enable_payment_response_hash: Option, - /// Refers to the hash key used for calculating the signature for webhooks and redirect response - /// If the value is not provided, a default value is used + /// Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used. pub payment_response_hash_key: Option, /// A boolean value to indicate if redirect to merchant with http post needs to be enabled @@ -1137,7 +1151,7 @@ pub struct BusinessProfileUpdate { #[schema(value_type = Option,example = json!({"type": "single", "data": "signifyd"}))] pub frm_routing_algorithm: Option, - /// The routing algorithm to be used for routing payouts to desired connectors + /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' #[cfg(feature = "payouts")] #[schema(value_type = Option,example = json!({"type": "single", "data": "wise"}))] #[serde( diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index 558223a68e..cc2052d18a 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -13,11 +13,9 @@ use utoipa::ToSchema; serde::Serialize, strum::Display, strum::EnumString, - ToSchema, )] /// The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom' -#[schema(example = "custom")] #[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] pub enum RoutingAlgorithm { @@ -27,6 +25,7 @@ pub enum RoutingAlgorithm { Custom, } +/// A connector is an integration to fulfill payments #[derive( Clone, Copy, diff --git a/crates/api_models/src/gsm.rs b/crates/api_models/src/gsm.rs index 81798d0517..30e4906243 100644 --- a/crates/api_models/src/gsm.rs +++ b/crates/api_models/src/gsm.rs @@ -4,25 +4,41 @@ use crate::enums::Connector; #[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)] pub struct GsmCreateRequest { + /// The connector through which payment has gone through pub connector: Connector, + /// The flow in which the code and message occurred for a connector pub flow: String, + /// The sub_flow in which the code and message occurred for a connector pub sub_flow: String, + /// code received from the connector pub code: String, + /// message received from the connector pub message: String, + /// status provided by the router pub status: String, + /// optional error provided by the router pub router_error: Option, + /// decision to be taken for auto retries flow pub decision: GsmDecision, + /// indicates if step_up retry is possible pub step_up_possible: bool, + /// error code unified across the connectors pub unified_code: Option, + /// error message unified across the connectors pub unified_message: Option, } #[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)] pub struct GsmRetrieveRequest { + /// The connector through which payment has gone through pub connector: Connector, + /// The flow in which the code and message occurred for a connector pub flow: String, + /// The sub_flow in which the code and message occurred for a connector pub sub_flow: String, + /// code received from the connector pub code: String, + /// message received from the connector pub message: String, } @@ -50,48 +66,79 @@ pub enum GsmDecision { #[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)] pub struct GsmUpdateRequest { + /// The connector through which payment has gone through pub connector: String, + /// The flow in which the code and message occurred for a connector pub flow: String, + /// The sub_flow in which the code and message occurred for a connector pub sub_flow: String, + /// code received from the connector pub code: String, + /// message received from the connector pub message: String, + /// status provided by the router pub status: Option, + /// optional error provided by the router pub router_error: Option, + /// decision to be taken for auto retries flow pub decision: Option, + /// indicates if step_up retry is possible pub step_up_possible: Option, + /// error code unified across the connectors pub unified_code: Option, + /// error message unified across the connectors pub unified_message: Option, } #[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)] pub struct GsmDeleteRequest { + /// The connector through which payment has gone through pub connector: String, + /// The flow in which the code and message occurred for a connector pub flow: String, + /// The sub_flow in which the code and message occurred for a connector pub sub_flow: String, + /// code received from the connector pub code: String, + /// message received from the connector pub message: String, } #[derive(Debug, serde::Serialize, ToSchema)] pub struct GsmDeleteResponse { pub gsm_rule_delete: bool, + /// The connector through which payment has gone through pub connector: String, + /// The flow in which the code and message occurred for a connector pub flow: String, + /// The sub_flow in which the code and message occurred for a connector pub sub_flow: String, + /// code received from the connector pub code: String, } #[derive(serde::Serialize, Debug, ToSchema)] pub struct GsmResponse { + /// The connector through which payment has gone through pub connector: String, + /// The flow in which the code and message occurred for a connector pub flow: String, + /// The sub_flow in which the code and message occurred for a connector pub sub_flow: String, + /// code received from the connector pub code: String, + /// message received from the connector pub message: String, + /// status provided by the router pub status: String, + /// optional error provided by the router pub router_error: Option, + /// decision to be taken for auto retries flow pub decision: String, + /// indicates if step_up retry is possible pub step_up_possible: bool, + /// error code unified across the connectors pub unified_code: Option, + /// error message unified across the connectors pub unified_message: Option, } diff --git a/crates/api_models/src/payment_methods.rs b/crates/api_models/src/payment_methods.rs index 984e6dbfff..173272e25d 100644 --- a/crates/api_models/src/payment_methods.rs +++ b/crates/api_models/src/payment_methods.rs @@ -21,7 +21,7 @@ use crate::{ #[serde(deny_unknown_fields)] pub struct PaymentMethodCreate { /// The type of payment method use for the payment. - #[schema(value_type = PaymentMethodType,example = "card")] + #[schema(value_type = PaymentMethod,example = "card")] pub payment_method: api_enums::PaymentMethod, /// This is a sub-category of payment method. @@ -139,7 +139,7 @@ pub struct PaymentMethodResponse { pub payment_method_id: String, /// The type of payment method use for the payment. - #[schema(value_type = PaymentMethodType, example = "card")] + #[schema(value_type = PaymentMethod, example = "card")] pub payment_method: api_enums::PaymentMethod, /// This is a sub-category of payment method. @@ -727,7 +727,7 @@ pub struct CustomerPaymentMethod { pub customer_id: String, /// The type of payment method use for the payment. - #[schema(value_type = PaymentMethodType,example = "card")] + #[schema(value_type = PaymentMethod,example = "card")] pub payment_method: api_enums::PaymentMethod, /// This is a sub-category of payment method. diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 24ac72175d..57c66dc5a7 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -82,9 +82,25 @@ pub struct CustomerDetails { ToSchema, router_derive::PolymorphicSchema, )] -#[generate_schemas(PaymentsCreateRequest)] +#[generate_schemas(PaymentsCreateRequest, PaymentsUpdateRequest, PaymentsConfirmRequest)] #[serde(deny_unknown_fields)] pub struct PaymentsRequest { + /// The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and ¥100 since ¥ is a zero-decimal currency + #[schema(value_type = Option, example = 6540)] + #[serde(default, deserialize_with = "amount::deserialize_option")] + #[mandatory_in(PaymentsCreateRequest = u64)] + // Makes the field mandatory in PaymentsCreateRequest + pub amount: Option, + + /// The three letter ISO currency code in uppercase. Eg: 'USD' to charge US Dollars + #[schema(example = "USD", value_type = Option)] + #[mandatory_in(PaymentsCreateRequest = Currency)] + pub currency: Option, + + /// The Amount to be captured / debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc., If not provided, the default amount_to_capture will be the payment amount. + #[schema(example = 6540)] + pub amount_to_capture: Option, + /// Unique identifier for the payment. This ensures idempotency for multiple payments /// that have been done by a single merchant. This field is auto generated and is returned in the API response. #[schema( @@ -101,36 +117,26 @@ pub struct PaymentsRequest { #[schema(max_length = 255, example = "merchant_1668273825")] pub merchant_id: Option, - /// The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc., - #[schema(value_type = Option, example = 6540)] - #[serde(default, deserialize_with = "amount::deserialize_option")] - #[mandatory_in(PaymentsCreateRequest)] - // Makes the field mandatory in PaymentsCreateRequest - pub amount: Option, - - #[schema(value_type = Option, example = json!({ + #[schema(value_type = Option, example = json!({ "type": "single", - "data": "stripe" + "data": {"connector": "stripe", "merchant_connector_id": "mca_123"} }))] pub routing: Option, - /// This allows the merchant to manually select a connector with which the payment can go through + /// This allows to manually select a connector with which the payment can go through #[schema(value_type = Option>, max_length = 255, example = json!(["stripe", "adyen"]))] pub connector: Option>, - /// The currency of the payment request can be specified here - #[schema(value_type = Option, example = "USD")] - #[mandatory_in(PaymentsCreateRequest)] - pub currency: Option, - - /// This is the instruction for capture/ debit the money from the users' card. On the other hand authorization refers to blocking the amount on the users' payment method. + /// Default value if not passed is set to 'automatic' which results in Auth and Capture in one single API request. Pass 'manual' or 'manual_multiple' in case you want do a separate Auth and Capture by first authorizing and placing a hold on your customer's funds so that you can use the Payments/Capture endpoint later to capture the authorized amount. Pass 'manual' if you want to only capture the amount later once or 'manual_multiple' if you want to capture the funds multiple times later. Both 'manual' and 'manual_multiple' are only supported by a specific list of processors #[schema(value_type = Option, example = "automatic")] pub capture_method: Option, - /// The Amount to be captured/ debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc., - /// If not provided, the default amount_to_capture will be the payment amount. - #[schema(example = 6540)] - pub amount_to_capture: Option, + /// Pass this parameter to force 3DS or non 3DS auth for this payment. Some connectors will still force 3DS auth even in case of passing 'no_three_ds' here and vice versa. Default value is 'no_three_ds' if not set + #[schema(value_type = Option, example = "no_three_ds", default = "three_ds")] + pub authentication_type: Option, + + /// The billing details of the customer + pub billing: Option
, /// A timestamp (ISO 8601 code) that determines when the payment should be captured. /// Providing this field will automatically set `capture` to true @@ -142,23 +148,19 @@ pub struct PaymentsRequest { #[schema(default = false, example = true)] pub confirm: Option, - /// The details of a customer for this payment - /// This will create the customer if `customer.id` does not exist - /// If customer id already exists, it will update the details of the customer + /// Passing this object creates a new customer or attaches an existing customer to the payment pub customer: Option, - /// The identifier for the customer object. - /// This field will be deprecated soon, use the customer object instead + /// The identifier for the customer object. This field will be deprecated soon, use the customer object instead #[schema(max_length = 255, example = "cus_y3oqhf46pyzuxjbcn2giaqnb44")] pub customer_id: Option, - /// The customer's email address - /// This field will be deprecated soon, use the customer object instead + /// The customer's email address This field will be deprecated soon, use the customer object instead #[schema(max_length = 255, value_type = Option, example = "johntest@test.com")] pub email: Option, - /// description: The customer's name - /// This field will be deprecated soon, use the customer object instead + /// The customer's name. + /// This field will be deprecated soon, use the customer object instead. #[schema(value_type = Option, max_length = 255, example = "John Test")] pub name: Option>, @@ -172,11 +174,11 @@ pub struct PaymentsRequest { #[schema(max_length = 255, example = "+1")] pub phone_country_code: Option, - /// Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. This parameter can only be used with `confirm: true`. + /// Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. When making a recurring payment by passing a mandate_id, this parameter is mandatory #[schema(example = true)] pub off_session: Option, - /// A description of the payment + /// A description for the payment #[schema(example = "It's my first payment request")] pub description: Option, @@ -187,10 +189,6 @@ pub struct PaymentsRequest { #[schema(value_type = Option, example = "off_session")] pub setup_future_usage: Option, - /// The transaction authentication can be set to undergo payer authentication. - #[schema(value_type = Option, example = "no_three_ds", default = "three_ds")] - pub authentication_type: Option, - /// The payment method information provided for making a payment #[schema(example = "bank_transfer")] pub payment_method_data: Option, @@ -203,17 +201,13 @@ pub struct PaymentsRequest { #[schema(example = "187282ab-40ef-47a9-9206-5099ba31e432")] pub payment_token: Option, - /// This is used when payment is to be confirmed and the card is not saved. - /// This field will be deprecated soon, use the CardToken object instead + /// This is used along with the payment_token field while collecting during saved card payments. This field will be deprecated soon, use the payment_method_data.card_token object instead #[schema(value_type = Option, deprecated)] pub card_cvc: Option>, /// The shipping address for the payment pub shipping: Option
, - /// The billing address for the payment - pub billing: Option
, - /// For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters. #[schema(max_length = 255, example = "Hyperswitch Router")] pub statement_descriptor_name: Option, @@ -222,28 +216,30 @@ pub struct PaymentsRequest { #[schema(max_length = 255, example = "Payment for shoes purchase")] pub statement_descriptor_suffix: Option, - /// Information about the product , quantity and amount for connectors. (e.g. Klarna) + /// Use this object to capture the details about the different products for which the payment is being made. The sum of amount across different products here should be equal to the overall payment amount #[schema(value_type = Option>, example = r#"[{ - "product_name": "gillete creme", - "quantity": 15, - "amount" : 900 + "product_name": "Apple iPhone 16", + "quantity": 1, + "amount" : 69000 "product_img_link" : "https://dummy-img-link.com" }]"#)] pub order_details: Option>, /// It's a token used for client side verification. #[schema(example = "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo")] + #[remove_in(PaymentsUpdateRequest, PaymentsCreateRequest)] pub client_secret: Option, - /// Provide mandate information for creating a mandate + /// Passing this object during payments creates a mandate. The mandate_type sub object is passed by the server usually and the customer_acceptance sub object is usually passed by the SDK or client pub mandate_data: Option, - /// A unique identifier to link the payment to a mandate, can be use instead of payment_method_data + /// A unique identifier to link the payment to a mandate. To do Recurring payments after a mandate has been created, pass the mandate_id instead of payment_method_data #[schema(max_length = 255, example = "mandate_iwer89rnjef349dni3")] + #[remove_in(PaymentsUpdateRequest)] pub mandate_id: Option, /// Additional details required by 3DS 2.0 - #[schema(value_type = Option, example = r#"{ + #[schema(value_type = Option, example = r#"{ "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", "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "language": "nl-NL", @@ -256,7 +252,7 @@ pub struct PaymentsRequest { }"#)] pub browser_info: Option, - /// Payment Experience for the current payment + /// To indicate the type of payment experience that the payment method would go through #[schema(value_type = Option, example = "redirect_to_url")] pub payment_experience: Option, @@ -264,23 +260,28 @@ pub struct PaymentsRequest { #[schema(value_type = Option, example = "google_pay")] pub payment_method_type: Option, - /// Business country of the merchant for this payment + /// Business country of the merchant for this payment. + /// To be deprecated soon. Pass the profile_id instead #[schema(value_type = Option, example = "US")] + #[remove_in(PaymentsUpdateRequest, PaymentsConfirmRequest)] pub business_country: Option, - /// Business label of the merchant for this payment + /// Business label of the merchant for this payment. + /// To be deprecated soon. Pass the profile_id instead #[schema(example = "food")] + #[remove_in(PaymentsUpdateRequest, PaymentsConfirmRequest)] pub business_label: Option, /// Merchant connector details used to make payments. #[schema(value_type = Option)] pub merchant_connector_details: Option, - /// Allowed Payment Method Types for a given PaymentIntent + /// Use this parameter to restrict the Payment Method Types to show for a given PaymentIntent #[schema(value_type = Option>)] pub allowed_payment_method_types: Option>, /// Business sub label for the payment + #[remove_in(PaymentsUpdateRequest, PaymentsConfirmRequest, PaymentsCreateRequest)] pub business_sub_label: Option, /// Denotes the retry action @@ -307,9 +308,11 @@ pub struct PaymentsRequest { /// The business profile to use for this payment, if not passed the default business profile /// associated with the merchant account will be used. + #[remove_in(PaymentsUpdateRequest, PaymentsConfirmRequest)] pub profile_id: Option, /// surcharge_details for this payment + #[remove_in(PaymentsConfirmRequest)] #[schema(value_type = Option)] pub surcharge_details: Option, @@ -347,6 +350,44 @@ pub struct RequestSurchargeDetails { pub tax_amount: Option, } +/// Browser information to be used for 3DS 2.0 +#[derive(ToSchema)] +pub struct BrowserInformation { + /// Color depth supported by the browser + pub color_depth: Option, + + /// Whether java is enabled in the browser + pub java_enabled: Option, + + /// Whether javascript is enabled in the browser + pub java_script_enabled: Option, + + /// Language supported + pub language: Option, + + /// The screen height in pixels + pub screen_height: Option, + + /// The screen width in pixels + pub screen_width: Option, + + /// Time zone of the client + pub time_zone: Option, + + /// Ip address of the client + #[schema(value_type = Option)] + pub ip_address: Option, + + /// List of headers that are accepted + #[schema( + example = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8" + )] + pub accept_header: Option, + + /// User-agent of the browser + pub user_agent: Option, +} + impl RequestSurchargeDetails { pub fn is_surcharge_zero(&self) -> bool { self.surcharge_amount == 0 && self.tax_amount.unwrap_or(0) == 0 @@ -662,6 +703,7 @@ pub struct CustomerAcceptance { #[derive(Default, Debug, serde::Deserialize, serde::Serialize, PartialEq, Eq, Clone, ToSchema)] #[serde(rename_all = "lowercase")] +/// This is used to indicate if the mandate was accepted online or offline pub enum AcceptanceType { Online, #[default] @@ -876,19 +918,33 @@ pub enum BankDebitData { #[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema, Eq, PartialEq)] #[serde(rename_all = "snake_case")] pub enum PaymentMethodData { + #[schema(title = "Card")] Card(Card), + #[schema(title = "CardRedirect")] CardRedirect(CardRedirectData), + #[schema(title = "Wallet")] Wallet(WalletData), + #[schema(title = "PayLater")] PayLater(PayLaterData), + #[schema(title = "BankRedirect")] BankRedirect(BankRedirectData), + #[schema(title = "BankDebit")] BankDebit(BankDebitData), + #[schema(title = "BankTransfer")] BankTransfer(Box), + #[schema(title = "Crypto")] Crypto(CryptoData), + #[schema(title = "MandatePayment")] MandatePayment, + #[schema(title = "Reward")] Reward, + #[schema(title = "Upi")] Upi(UpiData), + #[schema(title = "Voucher")] Voucher(VoucherData), + #[schema(title = "GiftCard")] GiftCard(Box), + #[schema(title = "CardToken")] CardToken(CardToken), } @@ -1788,6 +1844,7 @@ pub struct Address { } // used by customers also, could be moved outside +/// Address details #[derive(Clone, Default, Debug, Eq, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)] #[serde(deny_unknown_fields)] pub struct AddressDetails { @@ -3132,7 +3189,7 @@ pub struct PaymentsCancelRequest { /// The reason for the payment cancel pub cancellation_reason: Option, /// Merchant connector details used to make payments. - #[schema(value_type = MerchantConnectorDetailsWrap)] + #[schema(value_type = Option)] pub merchant_connector_details: Option, } diff --git a/crates/api_models/src/refunds.rs b/crates/api_models/src/refunds.rs index 1a0668023f..97182df0a5 100644 --- a/crates/api_models/src/refunds.rs +++ b/crates/api_models/src/refunds.rs @@ -9,15 +9,7 @@ use crate::{admin, enums}; #[derive(Default, Debug, ToSchema, Clone, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct RefundRequest { - /// Unique Identifier for the Refund. This is to ensure idempotency for multiple partial refund initiated against the same payment. If the identifiers is not defined by the merchant, this filed shall be auto generated and provide in the API response. It is recommended to generate uuid(v4) as the refund_id. - #[schema( - max_length = 30, - min_length = 30, - example = "ref_mbabizu24mvu3mela5njyhpit4" - )] - pub refund_id: Option, - - /// Total amount for which the refund is to be initiated. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc. If not provided, this will default to the full payment amount + /// The payment id against which refund is to be intiated #[schema( max_length = 30, min_length = 30, @@ -25,6 +17,14 @@ pub struct RefundRequest { )] pub payment_id: String, + /// Unique Identifier for the Refund. This is to ensure idempotency for multiple partial refunds initiated against the same payment. If this is not passed by the merchant, this field shall be auto generated and provided in the API response. It is recommended to generate uuid(v4) as the refund_id. + #[schema( + max_length = 30, + min_length = 30, + example = "ref_mbabizu24mvu3mela5njyhpit4" + )] + pub refund_id: Option, + /// The identifier for the Merchant Account #[schema(max_length = 255, example = "y3oqhf46pyzuxjbcn2giaqnb44")] pub merchant_id: Option, @@ -33,11 +33,11 @@ pub struct RefundRequest { #[schema(minimum = 100, example = 6540)] pub amount: Option, - /// An arbitrary string attached to the object. Often useful for displaying to users and your customer support executive + /// Reason for the refund. Often useful for displaying to users and your customer support executive. In case the payment went through Stripe, this field needs to be passed with one of these enums: `duplicate`, `fraudulent`, or `requested_by_customer` #[schema(max_length = 255, example = "Customer returned the product")] pub reason: Option, - /// The type of refund based on waiting time for processing: Scheduled or Instant Refund + /// To indicate whether to refund needs to be instant or scheduled. Default value is instant #[schema(default = "Instant", example = "Instant")] pub refund_type: Option, @@ -87,6 +87,7 @@ pub struct RefundUpdateRequest { pub metadata: Option, } +/// To indicate whether to refund needs to be instant or scheduled #[derive( Default, Debug, Clone, Copy, ToSchema, Deserialize, Serialize, Eq, PartialEq, strum::Display, )] @@ -99,18 +100,18 @@ pub enum RefundType { #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, ToSchema)] pub struct RefundResponse { - /// The identifier for refund + /// Unique Identifier for the refund pub refund_id: String, - /// The identifier for payment + /// The payment id against which refund is intiated pub payment_id: String, /// The refund amount, which should be less than or equal to the total payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc pub amount: i64, /// The three-letter ISO currency code pub currency: String, - /// An arbitrary string attached to the object. Often useful for displaying to users and your customer support executive - pub reason: Option, /// The status for refund pub status: RefundStatus, + /// An arbitrary string attached to the object. Often useful for displaying to users and your customer support executive + pub reason: Option, /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object #[schema(value_type = Option)] pub metadata: Option, diff --git a/crates/api_models/src/routing.rs b/crates/api_models/src/routing.rs index 2236714da1..2775034c88 100644 --- a/crates/api_models/src/routing.rs +++ b/crates/api_models/src/routing.rs @@ -2,7 +2,7 @@ use std::fmt::Debug; use common_utils::errors::ParsingError; use error_stack::IntoReport; -use euclid::{ +pub use euclid::{ dssa::types::EuclidAnalysable, frontend::{ ast, @@ -10,10 +10,11 @@ use euclid::{ }, }; use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; use crate::enums::{self, RoutableConnectors}; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] #[serde(tag = "type", content = "data", rename_all = "snake_case")] pub enum ConnectorSelection { Priority(Vec), @@ -31,7 +32,7 @@ impl ConnectorSelection { } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] pub struct RoutingConfigRequest { pub name: Option, pub description: Option, @@ -39,7 +40,7 @@ pub struct RoutingConfigRequest { pub profile_id: Option, } -#[derive(Debug, serde::Serialize)] +#[derive(Debug, serde::Serialize, ToSchema)] pub struct ProfileDefaultRoutingConfig { pub profile_id: String, pub connectors: Vec, @@ -60,19 +61,21 @@ pub struct RoutingRetrieveLinkQuery { pub profile_id: Option, } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] +/// Response of the retrieved routing configs for a merchant account pub struct RoutingRetrieveResponse { pub algorithm: Option, } -#[derive(Debug, serde::Serialize)] +#[derive(Debug, serde::Serialize, ToSchema)] #[serde(untagged)] pub enum LinkedRoutingConfigRetrieveResponse { MerchantAccountBased(RoutingRetrieveResponse), ProfileBased(Vec), } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] +/// Routing Algorithm specific to merchants pub struct MerchantRoutingAlgorithm { pub id: String, #[cfg(feature = "business_profile_routing")] @@ -153,14 +156,14 @@ impl EuclidAnalysable for ConnectorSelection { } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] pub struct ConnectorVolumeSplit { pub connector: RoutableConnectorChoice, pub split: u8, } #[cfg(feature = "connector_choice_bcompat")] -#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] +#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)] pub enum RoutableChoiceKind { OnlyConnector, FullStruct, @@ -180,15 +183,18 @@ pub enum RoutableChoiceSerde { }, } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] #[cfg_attr( feature = "connector_choice_bcompat", serde(from = "RoutableChoiceSerde"), serde(into = "RoutableChoiceSerde") )] #[cfg_attr(not(feature = "connector_choice_bcompat"), derive(PartialEq, Eq))] + +/// Routable Connector chosen for a payment pub struct RoutableConnectorChoice { #[cfg(feature = "connector_choice_bcompat")] + #[serde(skip)] pub choice_kind: RoutableChoiceKind, pub connector: RoutableConnectors, #[cfg(feature = "connector_choice_mca_id")] @@ -322,7 +328,7 @@ impl DetailedConnectorChoice { } } -#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize, strum::Display)] +#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize, strum::Display, ToSchema)] #[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] pub enum RoutingAlgorithmKind { @@ -339,17 +345,19 @@ pub struct RoutingPayloadWrapper { pub profile_id: String, } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] #[serde( tag = "type", content = "data", rename_all = "snake_case", try_from = "RoutingAlgorithmSerde" )] +/// Routing Algorithm kind pub enum RoutingAlgorithm { Single(Box), Priority(Vec), VolumeSplit(Vec), + #[schema(value_type=ProgramConnectorSelection)] Advanced(euclid::frontend::ast::Program), } @@ -390,7 +398,7 @@ impl TryFrom for RoutingAlgorithm { } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] #[serde( tag = "type", content = "data", @@ -399,8 +407,11 @@ impl TryFrom for RoutingAlgorithm { into = "StraightThroughAlgorithmSerde" )] pub enum StraightThroughAlgorithm { + #[schema(title = "Single")] Single(Box), + #[schema(title = "Priority")] Priority(Vec), + #[schema(title = "VolumeSplit")] VolumeSplit(Vec), } @@ -516,7 +527,7 @@ impl RoutingAlgorithmRef { } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] pub struct RoutingDictionaryRecord { pub id: String, @@ -529,14 +540,14 @@ pub struct RoutingDictionaryRecord { pub modified_at: i64, } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)] pub struct RoutingDictionary { pub merchant_id: String, pub active_id: Option, pub records: Vec, } -#[derive(serde::Serialize, serde::Deserialize, Debug)] +#[derive(serde::Serialize, serde::Deserialize, Debug, ToSchema)] #[serde(untagged)] pub enum RoutingKind { Config(RoutingDictionary), diff --git a/crates/api_models/src/webhooks.rs b/crates/api_models/src/webhooks.rs index 7b3564732b..37aaac42e0 100644 --- a/crates/api_models/src/webhooks.rs +++ b/crates/api_models/src/webhooks.rs @@ -169,13 +169,13 @@ pub struct OutgoingWebhook { #[derive(Debug, Clone, Serialize, ToSchema)] #[serde(tag = "type", content = "object", rename_all = "snake_case")] pub enum OutgoingWebhookContent { - #[schema(value_type = PaymentsResponse)] + #[schema(value_type = PaymentsResponse, title = "PaymentsResponse")] PaymentDetails(payments::PaymentsResponse), - #[schema(value_type = RefundResponse)] + #[schema(value_type = RefundResponse, title = "RefundResponse")] RefundDetails(refunds::RefundResponse), - #[schema(value_type = DisputeResponse)] + #[schema(value_type = DisputeResponse, title = "DisputeResponse")] DisputeDetails(Box), - #[schema(value_type = MandateResponse)] + #[schema(value_type = MandateResponse, title = "MandateResponse")] MandateDetails(Box), } diff --git a/crates/common_enums/Cargo.toml b/crates/common_enums/Cargo.toml index 3ed01ca2a9..f82d8e7a82 100644 --- a/crates/common_enums/Cargo.toml +++ b/crates/common_enums/Cargo.toml @@ -9,6 +9,7 @@ license.workspace = true [features] dummy_connector = [] +openapi = [] [dependencies] diesel = { version = "2.1.0", features = ["postgres"] } diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 949cc2e003..c0a363042e 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -74,10 +74,12 @@ pub enum AttemptStatus { strum::EnumString, strum::EnumIter, strum::EnumVariantNames, + ToSchema, )] #[router_derive::diesel_enum(storage_type = "db_enum")] #[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] +/// Connectors eligible for payments routing pub enum RoutableConnectors { #[cfg(feature = "dummy_connector")] #[serde(rename = "phonypay")] @@ -328,6 +330,7 @@ pub enum CaptureMethod { Scheduled, } +/// Type of the Connector for the financial use case. Could range from Payments to Accounting to Banking. #[derive( Clone, Copy, @@ -364,6 +367,7 @@ pub enum ConnectorType { PaymentMethodAuth, } +/// The three letter ISO currency code in uppercase. Eg: 'USD' for the United States Dollar. #[allow(clippy::upper_case_acronyms)] #[derive( Clone, @@ -1074,6 +1078,7 @@ pub enum PaymentMethodIssuerCode { JpBacs, } +/// To indicate the type of payment experience that the customer would go through #[derive( Eq, strum::EnumString, @@ -1109,6 +1114,7 @@ pub enum PaymentExperience { DisplayWaitScreen, } +/// Indicates the sub type of payment method. Eg: 'google_pay' & 'apple_pay' for wallets. #[derive( Clone, Copy, @@ -1214,6 +1220,7 @@ pub enum PaymentMethodType { PayEasy, } +/// Indicates the type of payment method. Eg: 'card', 'wallet', etc. #[derive( Clone, Copy, @@ -1249,6 +1256,7 @@ pub enum PaymentMethod { GiftCard, } +/// To be used to specify the type of payment. Use 'setup_mandate' in case of zero auth flow. #[derive( Clone, Copy, @@ -1297,7 +1305,7 @@ pub enum RefundStatus { TransactionFailure, } -/// The status of the mandate, which indicates whether it can be used to initiate a payment +/// The status of the mandate, which indicates whether it can be used to initiate a payment. #[derive( Clone, Copy, @@ -1322,6 +1330,7 @@ pub enum MandateStatus { Revoked, } +/// Indicates the card network. #[derive( Clone, Debug, diff --git a/crates/common_utils/src/macros.rs b/crates/common_utils/src/macros.rs index 9d41569384..c07b2112db 100644 --- a/crates/common_utils/src/macros.rs +++ b/crates/common_utils/src/macros.rs @@ -54,6 +54,18 @@ macro_rules! async_spawn { }; } +/// Use this to ensure that the corresponding +/// openapi route has been implemented in the openapi crate +#[macro_export] +macro_rules! openapi_route { + ($route_name: ident) => {{ + #[cfg(feature = "openapi")] + use openapi::routes::$route_name as _; + + $route_name + }}; +} + #[macro_export] macro_rules! fallback_reverse_lookup_not_found { ($a:expr,$b:expr) => { diff --git a/crates/euclid/Cargo.toml b/crates/euclid/Cargo.toml index 08b9f0af28..415398105a 100644 --- a/crates/euclid/Cargo.toml +++ b/crates/euclid/Cargo.toml @@ -16,6 +16,7 @@ serde = { version = "1.0.193", features = ["derive", "rc"] } serde_json = "1.0.108" strum = { version = "0.25", features = ["derive"] } thiserror = "1.0.43" +utoipa = { version = "3.3.0", features = ["preserve_order"] } # First party dependencies common_enums = { version = "0.1.0", path = "../common_enums" } diff --git a/crates/euclid/src/frontend/ast.rs b/crates/euclid/src/frontend/ast.rs index 0dad9b53c3..905bf04de0 100644 --- a/crates/euclid/src/frontend/ast.rs +++ b/crates/euclid/src/frontend/ast.rs @@ -4,6 +4,7 @@ pub mod parser; use common_enums::RoutableConnectors; use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; use crate::types::{DataType, Metadata}; @@ -14,14 +15,14 @@ pub struct ConnectorChoice { pub sub_label: Option, } -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ToSchema)] pub struct MetadataValue { pub key: String, pub value: String, } /// Represents a value in the DSL -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ToSchema)] #[serde(tag = "type", content = "value", rename_all = "snake_case")] pub enum ValueType { /// Represents a number literal @@ -60,7 +61,7 @@ impl ValueType { } /// Represents a number comparison for "NumberComparisonArrayValue" -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct NumberComparison { pub comparison_type: ComparisonType, @@ -68,7 +69,7 @@ pub struct NumberComparison { } /// Conditional comparison type -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "snake_case")] pub enum ComparisonType { Equal, @@ -80,7 +81,7 @@ pub enum ComparisonType { } /// Represents a single comparison condition. -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct Comparison { /// The left hand side which will always be a domain input identifier like "payment.method.cardtype" @@ -92,6 +93,7 @@ pub struct Comparison { /// Additional metadata that the Static Analyzer and Backend does not touch. /// This can be used to store useful information for the frontend and is required for communication /// between the static analyzer and the frontend. + #[schema(value_type=HashMap)] pub metadata: Metadata, } @@ -112,9 +114,10 @@ pub type IfCondition = Vec; /// } /// } /// ``` -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] pub struct IfStatement { + #[schema(value_type=Vec)] pub condition: IfCondition, pub nested: Option>, } @@ -134,8 +137,9 @@ pub struct IfStatement { /// } /// ``` -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] +#[aliases(RuleConnectorSelection = Rule)] pub struct Rule { pub name: String, #[serde(alias = "routingOutput")] @@ -145,10 +149,43 @@ pub struct Rule { /// The program, having a default connector selection and /// a bunch of rules. Also can hold arbitrary metadata. -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] #[serde(rename_all = "camelCase")] +#[aliases(ProgramConnectorSelection = Program)] pub struct Program { pub default_selection: O, + #[schema(value_type=RuleConnectorSelection)] pub rules: Vec>, + #[schema(value_type=HashMap)] pub metadata: Metadata, } + +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct RoutableConnectorChoice { + #[cfg(feature = "connector_choice_bcompat")] + #[serde(skip)] + pub choice_kind: RoutableChoiceKind, + #[cfg(feature = "connector_choice_mca_id")] + pub merchant_connector_id: Option, + #[cfg(not(feature = "connector_choice_mca_id"))] + pub sub_label: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)] +pub enum RoutableChoiceKind { + OnlyConnector, + FullStruct, +} + +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct ConnectorVolumeSplit { + pub connector: RoutableConnectorChoice, + pub split: u8, +} + +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(tag = "type", content = "data", rename_all = "snake_case")] +pub enum ConnectorSelection { + Priority(Vec), + VolumeSplit(Vec), +} diff --git a/crates/openapi/Cargo.toml b/crates/openapi/Cargo.toml new file mode 100644 index 0000000000..236916862d --- /dev/null +++ b/crates/openapi/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "openapi" +version = "0.1.0" +edition.workspace = true +rust-version.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +utoipa = { version = "3.3.0", features = ["preserve_order", "time"] } +serde_json = "1.0.96" + +api_models = { version = "0.1.0", path = "../api_models", features = ["openapi"] } diff --git a/crates/openapi/src/lib.rs b/crates/openapi/src/lib.rs new file mode 100644 index 0000000000..27d67445bc --- /dev/null +++ b/crates/openapi/src/lib.rs @@ -0,0 +1,2 @@ +mod openapi; +pub mod routes; diff --git a/crates/openapi/src/main.rs b/crates/openapi/src/main.rs new file mode 100644 index 0000000000..88bcb8896b --- /dev/null +++ b/crates/openapi/src/main.rs @@ -0,0 +1,15 @@ +mod openapi; +mod routes; + +fn main() { + let file_path = "openapi/openapi_spec.json"; + #[allow(clippy::expect_used)] + std::fs::write( + file_path, + ::openapi() + .to_pretty_json() + .expect("Failed to serialize OpenAPI specification as JSON"), + ) + .expect("Failed to write OpenAPI specification to file"); + println!("Successfully saved OpenAPI specification file at '{file_path}'"); +} diff --git a/crates/router/src/openapi.rs b/crates/openapi/src/openapi.rs similarity index 65% rename from crates/router/src/openapi.rs rename to crates/openapi/src/openapi.rs index 174926c7d3..3d4a1893ad 100644 --- a/crates/router/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -1,4 +1,5 @@ -#[cfg(feature = "openapi")] +use crate::routes; + #[derive(utoipa::OpenApi)] #[openapi( info( @@ -59,97 +60,138 @@ Never share your secret api keys. Keep them guarded and secure. (name = "Customers", description = "Create and manage customers"), (name = "Payment Methods", description = "Create and manage payment methods of customers"), (name = "Disputes", description = "Manage disputes"), - // (name = "API Key", description = "Create and manage API Keys"), + (name = "API Key", description = "Create and manage API Keys"), (name = "Payouts", description = "Create and manage payouts"), (name = "payment link", description = "Create payment link"), + (name = "Routing", description = "Create and manage routing configurations"), ), + // The paths will be displayed in the same order as they are registered here paths( - crate::routes::refunds::refunds_create, - crate::routes::refunds::refunds_retrieve, - crate::routes::refunds::refunds_update, - crate::routes::refunds::refunds_list, - // Commenting this out as these are admin apis and not to be used by the merchant - // crate::routes::admin::merchant_account_create, - // crate::routes::admin::retrieve_merchant_account, - // crate::routes::admin::update_merchant_account, - // crate::routes::admin::delete_merchant_account, - crate::routes::admin::payment_connector_create, - crate::routes::admin::payment_connector_retrieve, - crate::routes::admin::payment_connector_list, - crate::routes::admin::payment_connector_update, - crate::routes::admin::payment_connector_delete, - crate::routes::mandates::get_mandate, - crate::routes::mandates::revoke_mandate, - crate::routes::payments::payments_create, - // crate::routes::payments::payments_start, - crate::routes::payments::payments_retrieve, - crate::routes::payments::payments_update, - crate::routes::payments::payments_confirm, - crate::routes::payments::payments_capture, - crate::routes::payments::payments_connector_session, - // crate::routes::payments::payments_redirect_response, - crate::routes::payments::payments_cancel, - crate::routes::payments::payments_list, - crate::routes::payment_methods::create_payment_method_api, - crate::routes::payment_methods::list_payment_method_api, - crate::routes::payment_methods::list_customer_payment_method_api, - crate::routes::payment_methods::list_customer_payment_method_api_client, - crate::routes::payment_methods::payment_method_retrieve_api, - crate::routes::payment_methods::payment_method_update_api, - crate::routes::payment_methods::payment_method_delete_api, - crate::routes::customers::customers_create, - crate::routes::customers::customers_retrieve, - crate::routes::customers::customers_update, - crate::routes::customers::customers_delete, - crate::routes::customers::customers_list, - // crate::routes::api_keys::api_key_create, - // crate::routes::api_keys::api_key_retrieve, - // crate::routes::api_keys::api_key_update, - // crate::routes::api_keys::api_key_revoke, - // crate::routes::api_keys::api_key_list, - crate::routes::disputes::retrieve_disputes_list, - crate::routes::disputes::retrieve_dispute, - crate::routes::payouts::payouts_create, - crate::routes::payouts::payouts_cancel, - crate::routes::payouts::payouts_fulfill, - crate::routes::payouts::payouts_retrieve, - crate::routes::payouts::payouts_update, - crate::routes::payment_link::payment_link_retrieve, - crate::routes::gsm::create_gsm_rule, - crate::routes::gsm::get_gsm_rule, - crate::routes::gsm::update_gsm_rule, - crate::routes::gsm::delete_gsm_rule, - crate::routes::blocklist::add_entry_to_blocklist, - crate::routes::blocklist::list_blocked_payment_methods, - crate::routes::blocklist::remove_entry_from_blocklist + // Routes for payments + routes::payments::payments_create, + routes::payments::payments_update, + routes::payments::payments_confirm, + routes::payments::payments_retrieve, + routes::payments::payments_capture, + routes::payments::payments_connector_session, + routes::payments::payments_cancel, + routes::payments::payments_list, + routes::payments::payments_incremental_authorization, + routes::payment_link::payment_link_retrieve, + + // Routes for refunds + routes::refunds::refunds_create, + routes::refunds::refunds_retrieve, + routes::refunds::refunds_update, + routes::refunds::refunds_list, + + // Routes for merchant account + routes::merchant_account::merchant_account_create, + routes::merchant_account::retrieve_merchant_account, + routes::merchant_account::update_merchant_account, + routes::merchant_account::delete_merchant_account, + + // Routes for merchant connector account + routes::merchant_connector_account::payment_connector_create, + routes::merchant_connector_account::payment_connector_retrieve, + routes::merchant_connector_account::payment_connector_list, + routes::merchant_connector_account::payment_connector_update, + routes::merchant_connector_account::payment_connector_delete, + + //Routes for gsm + routes::gsm::create_gsm_rule, + routes::gsm::get_gsm_rule, + routes::gsm::update_gsm_rule, + routes::gsm::delete_gsm_rule, + + // Routes for mandates + routes::mandates::get_mandate, + routes::mandates::revoke_mandate, + + //Routes for customers + routes::customers::customers_create, + routes::customers::customers_retrieve, + routes::customers::customers_list, + routes::customers::customers_update, + routes::customers::customers_delete, + + //Routes for payment methods + routes::payment_method::create_payment_method_api, + routes::payment_method::list_payment_method_api, + routes::payment_method::list_customer_payment_method_api, + routes::payment_method::list_customer_payment_method_api_client, + routes::payment_method::payment_method_retrieve_api, + routes::payment_method::payment_method_update_api, + routes::payment_method::payment_method_delete_api, + + // Routes for Business Profile + routes::business_profile::business_profile_create, + routes::business_profile::business_profiles_list, + routes::business_profile::business_profiles_update, + routes::business_profile::business_profiles_delete, + routes::business_profile::business_profiles_retrieve, + + // Routes for disputes + routes::disputes::retrieve_dispute, + routes::disputes::retrieve_disputes_list, + + // Routes for routing + routes::routing::routing_create_config, + routes::routing::routing_link_config, + routes::routing::routing_retrieve_config, + routes::routing::list_routing_configs, + routes::routing::routing_unlink_config, + routes::routing::routing_update_default_config, + routes::routing::routing_retrieve_default_config, + routes::routing::routing_retrieve_linked_config, + routes::routing::routing_retrieve_default_config_for_profiles, + routes::routing::routing_update_default_config_for_profile, + + // Routes for blocklist + routes::blocklist::remove_entry_from_blocklist, + routes::blocklist::list_blocked_payment_methods, + routes::blocklist::add_entry_to_blocklist, + + // Routes for payouts + routes::payouts::payouts_create, + routes::payouts::payouts_retrieve, + routes::payouts::payouts_update, + routes::payouts::payouts_cancel, + routes::payouts::payouts_fulfill, + + // Routes for api keys + routes::api_keys::api_key_create, + routes::api_keys::api_key_retrieve, + routes::api_keys::api_key_update, + routes::api_keys::api_key_revoke ), components(schemas( - crate::types::api::refunds::RefundRequest, - crate::types::api::refunds::RefundType, - crate::types::api::refunds::RefundResponse, - crate::types::api::refunds::RefundStatus, - crate::types::api::refunds::RefundUpdateRequest, - crate::types::api::admin::MerchantAccountCreate, - crate::types::api::admin::MerchantAccountUpdate, - crate::types::api::admin::MerchantAccountDeleteResponse, - crate::types::api::admin::MerchantConnectorDeleteResponse, - crate::types::api::admin::MerchantConnectorResponse, - crate::types::api::customers::CustomerRequest, - crate::types::api::customers::CustomerDeleteResponse, - crate::types::api::payment_methods::PaymentMethodCreate, - crate::types::api::payment_methods::PaymentMethodResponse, - crate::types::api::payment_methods::PaymentMethodList, - crate::types::api::payment_methods::CustomerPaymentMethod, - crate::types::api::payment_methods::PaymentMethodListResponse, - crate::types::api::payment_methods::CustomerPaymentMethodsListResponse, - crate::types::api::payment_methods::PaymentMethodDeleteResponse, - crate::types::api::payment_methods::PaymentMethodUpdate, - crate::types::api::payment_methods::CardDetailFromLocker, - crate::types::api::payment_methods::CardDetail, + api_models::refunds::RefundRequest, + api_models::refunds::RefundType, + api_models::refunds::RefundResponse, + api_models::refunds::RefundStatus, + api_models::refunds::RefundUpdateRequest, + api_models::admin::MerchantAccountCreate, + api_models::admin::MerchantAccountUpdate, + api_models::admin::MerchantAccountDeleteResponse, + api_models::admin::MerchantConnectorDeleteResponse, + api_models::admin::MerchantConnectorResponse, + api_models::customers::CustomerRequest, + api_models::customers::CustomerDeleteResponse, + api_models::payment_methods::PaymentMethodCreate, + api_models::payment_methods::PaymentMethodResponse, + api_models::payment_methods::PaymentMethodList, + api_models::payment_methods::CustomerPaymentMethod, + api_models::payment_methods::PaymentMethodListResponse, + api_models::payment_methods::CustomerPaymentMethodsListResponse, + api_models::payment_methods::PaymentMethodDeleteResponse, + api_models::payment_methods::PaymentMethodUpdate, + api_models::payment_methods::CardDetailFromLocker, + api_models::payment_methods::CardDetail, + api_models::payment_methods::RequestPaymentMethodTypes, api_models::customers::CustomerResponse, api_models::admin::AcceptedCountries, api_models::admin::AcceptedCurrencies, - api_models::enums::RoutingAlgorithm, api_models::enums::PaymentType, api_models::enums::PaymentMethod, api_models::enums::PaymentMethodType, @@ -189,6 +231,8 @@ Never share your secret api keys. Keep them guarded and secure. api_models::admin::MerchantConnectorDetailsWrap, api_models::admin::MerchantConnectorDetails, api_models::admin::MerchantConnectorWebhookDetails, + api_models::admin::BusinessProfileCreate, + api_models::admin::BusinessProfileResponse, api_models::admin::BusinessPaymentLinkConfig, api_models::admin::PaymentLinkConfigRequest, api_models::admin::PaymentLinkConfig, @@ -257,6 +301,8 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::CustomerAcceptance, api_models::payments::PaymentsRequest, api_models::payments::PaymentsCreateRequest, + api_models::payments::PaymentsUpdateRequest, + api_models::payments::PaymentsConfirmRequest, api_models::payments::PaymentsResponse, api_models::payments::PaymentsStartRequest, api_models::payments::PaymentRetrieveBody, @@ -321,14 +367,15 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::RequestSurchargeDetails, api_models::payments::PaymentAttemptResponse, api_models::payments::CaptureResponse, + api_models::payments::PaymentsIncrementalAuthorizationRequest, api_models::payments::IncrementalAuthorizationResponse, + api_models::payments::BrowserInformation, api_models::payments::PaymentCreatePaymentLinkConfig, api_models::payment_methods::RequiredFieldInfo, api_models::payment_methods::MaskedBankDetails, api_models::payment_methods::SurchargeDetailsResponse, api_models::payment_methods::SurchargeResponse, api_models::payment_methods::SurchargePercentage, - api_models::payment_methods::RequestPaymentMethodTypes, api_models::refunds::RefundListRequest, api_models::refunds::RefundListResponse, api_models::payments::TimeRange, @@ -359,25 +406,50 @@ Never share your secret api keys. Keep them guarded and secure. api_models::webhooks::OutgoingWebhook, api_models::webhooks::OutgoingWebhookContent, api_models::enums::EventType, - crate::types::api::admin::MerchantAccountResponse, - crate::types::api::admin::MerchantConnectorId, - crate::types::api::admin::MerchantDetails, - crate::types::api::admin::WebhookDetails, - crate::types::api::api_keys::ApiKeyExpiration, - crate::types::api::api_keys::CreateApiKeyRequest, - crate::types::api::api_keys::CreateApiKeyResponse, - crate::types::api::api_keys::RetrieveApiKeyResponse, - crate::types::api::api_keys::RevokeApiKeyResponse, - crate::types::api::api_keys::UpdateApiKeyRequest, + api_models::admin::MerchantAccountResponse, + api_models::admin::MerchantConnectorId, + api_models::admin::MerchantDetails, + api_models::admin::WebhookDetails, + api_models::api_keys::ApiKeyExpiration, + api_models::api_keys::CreateApiKeyRequest, + api_models::api_keys::CreateApiKeyResponse, + api_models::api_keys::RetrieveApiKeyResponse, + api_models::api_keys::RevokeApiKeyResponse, + api_models::api_keys::UpdateApiKeyRequest, api_models::payments::RetrievePaymentLinkRequest, api_models::payments::PaymentLinkResponse, api_models::payments::RetrievePaymentLinkResponse, api_models::payments::PaymentLinkInitiateRequest, + api_models::routing::RoutingConfigRequest, + api_models::routing::RoutingDictionaryRecord, + api_models::routing::RoutingKind, + api_models::routing::RoutableConnectorChoice, + api_models::routing::LinkedRoutingConfigRetrieveResponse, + api_models::routing::RoutingRetrieveResponse, + api_models::routing::ProfileDefaultRoutingConfig, + api_models::routing::MerchantRoutingAlgorithm, + api_models::routing::RoutingAlgorithmKind, + api_models::routing::RoutingDictionary, + api_models::routing::RoutingAlgorithm, + api_models::routing::StraightThroughAlgorithm, + api_models::routing::ConnectorVolumeSplit, + api_models::routing::ConnectorSelection, + api_models::routing::ast::RoutableChoiceKind, + api_models::enums::RoutableConnectors, + api_models::routing::ast::ProgramConnectorSelection, + api_models::routing::ast::RuleConnectorSelection, + api_models::routing::ast::IfStatement, + api_models::routing::ast::Comparison, + api_models::routing::ast::ComparisonType, + api_models::routing::ast::ValueType, + api_models::routing::ast::MetadataValue, + api_models::routing::ast::NumberComparison, + api_models::payment_methods::RequestPaymentMethodTypes, api_models::payments::PaymentLinkStatus, api_models::blocklist::BlocklistRequest, api_models::blocklist::BlocklistResponse, api_models::blocklist::ListBlocklistQuery, - common_enums::enums::BlocklistDataKind + api_models::enums::BlocklistDataKind )), modifiers(&SecurityAddon) )] @@ -395,8 +467,7 @@ impl utoipa::Modify for SecurityAddon { "api_key", SecurityScheme::ApiKey(ApiKey::Header(ApiKeyValue::with_description( "api-key", - "API keys are the most common method of authentication and can be obtained \ - from the HyperSwitch dashboard." + "Use the API key created under your merchant account from the HyperSwitch dashboard. API key is used to authenticate API requests from your merchant server only. Don't expose this key on a website or embed it in a mobile application." ))), ), ( @@ -427,107 +498,3 @@ impl utoipa::Modify for SecurityAddon { } } } - -pub mod examples { - /// Creating the payment with minimal fields - pub const PAYMENTS_CREATE_MINIMUM_FIELDS: &str = r#"{ - "amount": 6540, - "currency": "USD", - }"#; - - /// Creating a manual capture payment - pub const PAYMENTS_CREATE_WITH_MANUAL_CAPTURE: &str = r#"{ - "amount": 6540, - "currency": "USD", - "capture_method":"manual" - }"#; - - /// Creating a payment with billing and shipping address - pub const PAYMENTS_CREATE_WITH_ADDRESS: &str = r#"{ - "amount": 6540, - "currency": "USD", - "customer": { - "id" : "cus_abcdefgh" - }, - "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": "8056594427", - "country_code": "+91" - } - } - }"#; - - /// Creating a payment with customer details - pub const PAYMENTS_CREATE_WITH_CUSTOMER_DATA: &str = r#"{ - "amount": 6540, - "currency": "USD", - "customer": { - "id":"cus_abcdefgh", - "name":"John Dough", - "phone":"9999999999", - "email":"john@example.com" - } - }"#; - - /// 3DS force payment - pub const PAYMENTS_CREATE_WITH_FORCED_3DS: &str = r#"{ - "amount": 6540, - "currency": "USD", - "authentication_type" : "three_ds" - }"#; - - /// A payment with other fields - pub const PAYMENTS_CREATE: &str = r#"{ - "amount": 6540, - "currency": "USD", - "payment_id": "abcdefghijklmnopqrstuvwxyz", - "customer": { - "id":"cus_abcdefgh", - "name":"John Dough", - "phone":"9999999999", - "email":"john@example.com" - }, - "description": "Its my first payment request", - "statement_descriptor_name": "joseph", - "statement_descriptor_suffix": "JS", - "metadata": { - "udf1": "some-value", - "udf2": "some-value" - } - }"#; - - /// Creating the payment with order details - pub const PAYMENTS_CREATE_WITH_ORDER_DETAILS: &str = r#"{ - "amount": 6540, - "currency": "USD", - "order_details": [ - { - "product_name": "Apple iPhone 15", - "quantity": 1, - "amount" : 6540 - } - ] - }"#; - - /// Creating the payment with connector metadata for noon - pub const PAYMENTS_CREATE_WITH_NOON_ORDER_CATETORY: &str = r#"{ - "amount": 6540, - "currency": "USD", - "connector_metadata": { - "noon": { - "order_category":"shoes" - } - } - }"#; -} diff --git a/crates/openapi/src/routes.rs b/crates/openapi/src/routes.rs new file mode 100644 index 0000000000..5a18229595 --- /dev/null +++ b/crates/openapi/src/routes.rs @@ -0,0 +1,26 @@ +#![allow(unused)] + +pub mod api_keys; +pub mod blocklist; +pub mod business_profile; +pub mod customers; +pub mod disputes; +pub mod gsm; +pub mod mandates; +pub mod merchant_account; +pub mod merchant_connector_account; +pub mod payment_link; +pub mod payment_method; +pub mod payments; +pub mod payouts; +pub mod refunds; +pub mod routing; + +pub use customers::*; +pub use mandates::*; +pub use merchant_account::*; +pub use merchant_connector_account::*; +pub use payment_method::*; +pub use payments::*; +pub use refunds::*; +pub use routing::*; diff --git a/crates/openapi/src/routes/api_keys.rs b/crates/openapi/src/routes/api_keys.rs new file mode 100644 index 0000000000..2956569bfb --- /dev/null +++ b/crates/openapi/src/routes/api_keys.rs @@ -0,0 +1,80 @@ +/// API Key - Create +/// +/// Create a new API Key for accessing our APIs from your servers. The plaintext API Key will be +/// displayed only once on creation, so ensure you store it securely. +#[utoipa::path( + post, + path = "/api_keys/{merchant_id)", + params(("merchant_id" = String, Path, description = "The unique identifier for the merchant account")), + request_body= CreateApiKeyRequest, + responses( + (status = 200, description = "API Key created", body = CreateApiKeyResponse), + (status = 400, description = "Invalid data") + ), + tag = "API Key", + operation_id = "Create an API Key", + security(("admin_api_key" = [])) +)] +pub async fn api_key_create() {} + +/// API Key - Retrieve +/// +/// Retrieve information about the specified API Key. +#[utoipa::path( + get, + path = "/api_keys/{merchant_id}/{key_id}", + params ( + ("merchant_id" = String, Path, description = "The unique identifier for the merchant account"), + ("key_id" = String, Path, description = "The unique identifier for the API Key") + ), + responses( + (status = 200, description = "API Key retrieved", body = RetrieveApiKeyResponse), + (status = 404, description = "API Key not found") + ), + tag = "API Key", + operation_id = "Retrieve an API Key", + security(("admin_api_key" = [])) +)] +pub async fn api_key_retrieve() {} + +/// API Key - Update +/// +/// Update information for the specified API Key. +#[utoipa::path( + post, + path = "/api_keys/{merchant_id}/{key_id}", + request_body = UpdateApiKeyRequest, + params ( + ("merchant_id" = String, Path, description = "The unique identifier for the merchant account"), + ("key_id" = String, Path, description = "The unique identifier for the API Key") + ), + responses( + (status = 200, description = "API Key updated", body = RetrieveApiKeyResponse), + (status = 404, description = "API Key not found") + ), + tag = "API Key", + operation_id = "Update an API Key", + security(("admin_api_key" = [])) +)] +pub async fn api_key_update() {} + +/// API Key - Revoke +/// +/// Revoke the specified API Key. Once revoked, the API Key can no longer be used for +/// authenticating with our APIs. +#[utoipa::path( + delete, + path = "/api_keys/{merchant_id)/{key_id}", + params ( + ("merchant_id" = String, Path, description = "The unique identifier for the merchant account"), + ("key_id" = String, Path, description = "The unique identifier for the API Key") + ), + responses( + (status = 200, description = "API Key revoked", body = RevokeApiKeyResponse), + (status = 404, description = "API Key not found") + ), + tag = "API Key", + operation_id = "Revoke an API Key", + security(("admin_api_key" = [])) +)] +pub async fn api_key_revoke() {} diff --git a/crates/openapi/src/routes/blocklist.rs b/crates/openapi/src/routes/blocklist.rs new file mode 100644 index 0000000000..bf683259e0 --- /dev/null +++ b/crates/openapi/src/routes/blocklist.rs @@ -0,0 +1,43 @@ +#[utoipa::path( + post, + path = "/blocklist", + request_body = BlocklistRequest, + responses( + (status = 200, description = "Fingerprint Blocked", body = BlocklistResponse), + (status = 400, description = "Invalid Data") + ), + tag = "Blocklist", + operation_id = "Block a Fingerprint", + security(("api_key" = [])) +)] +pub async fn add_entry_to_blocklist() {} + +#[utoipa::path( + delete, + path = "/blocklist", + request_body = BlocklistRequest, + responses( + (status = 200, description = "Fingerprint Unblocked", body = BlocklistResponse), + (status = 400, description = "Invalid Data") + ), + tag = "Blocklist", + operation_id = "Unblock a Fingerprint", + security(("api_key" = [])) +)] +pub async fn remove_entry_from_blocklist() {} + +#[utoipa::path( + get, + path = "/blocklist", + params ( + ("data_kind" = BlocklistDataKind, Query, description = "Kind of the fingerprint list requested"), + ), + responses( + (status = 200, description = "Blocked Fingerprints", body = BlocklistResponse), + (status = 400, description = "Invalid Data") + ), + tag = "Blocklist", + operation_id = "List Blocked fingerprints of a particular kind", + security(("api_key" = [])) +)] +pub async fn list_blocked_payment_methods() {} diff --git a/crates/openapi/src/routes/business_profile.rs b/crates/openapi/src/routes/business_profile.rs new file mode 100644 index 0000000000..57da0e5970 --- /dev/null +++ b/crates/openapi/src/routes/business_profile.rs @@ -0,0 +1,124 @@ +/// Business Profile - Create +/// +/// Creates a new *business profile* for a merchant +#[utoipa::path( + post, + path = "/account/{account_id}/business_profile", + params ( + ("account_id" = String, Path, description = "The unique identifier for the merchant account") + ), + request_body( + content = BusinessProfileCreate, + examples( + ( + "Create a business profile with minimal fields" = ( + value = json!({}) + ) + ), + ( + "Create a business profile with profile name" = ( + value = json!({ + "profile_name": "shoe_business" + }) + ) + ) + ) + ), + responses( + (status = 200, description = "Business Account Created", body = BusinessProfileResponse), + (status = 400, description = "Invalid data") + ), + tag = "Business Profile", + operation_id = "Create A Business Profile", + security(("admin_api_key" = [])) +)] +pub async fn business_profile_create() {} + +/// Business Profile - List +/// +/// Lists all the *business profiles* under a merchant +#[utoipa::path( + get, + path = "/account/{account_id}/business_profile", + params ( + ("account_id" = String, Path, description = "Merchant Identifier"), + ), + responses( + (status = 200, description = "Business profiles Retrieved", body = Vec) + ), + tag = "Business Profile", + operation_id = "List Business Profiles", + security(("api_key" = [])) +)] +pub async fn business_profiles_list() {} + +/// Business Profile - Update +/// +/// Update the *business profile* +#[utoipa::path( + post, + path = "/account/{account_id}/business_profile/{profile_id}", + params( + ("account_id" = String, Path, description = "The unique identifier for the merchant account"), + ("profile_id" = String, Path, description = "The unique identifier for the business profile") + ), + request_body( + content = BusinessProfileCreate, + examples( + ( + "Update business profile with profile name fields" = ( + value = json!({ + "profile_name" : "shoe_business" + }) + ) + ) + )), + responses( + (status = 200, description = "Business Profile Updated", body = BusinessProfileResponse), + (status = 400, description = "Invalid data") + ), + tag = "Business Profile", + operation_id = "Update a Business Profile", + security(("api_key" = [])) +)] +pub async fn business_profiles_update() {} + +/// Business Profile - Delete +/// +/// Delete the *business profile* +#[utoipa::path( + delete, + path = "/account/{account_id}/business_profile/{profile_id}", + params( + ("account_id" = String, Path, description = "The unique identifier for the merchant account"), + ("profile_id" = String, Path, description = "The unique identifier for the business profile") + ), + responses( + (status = 200, description = "Business profiles Deleted", body = bool), + (status = 400, description = "Invalid data") + ), + tag = "Business Profile", + operation_id = "Delete the Business Profile", + security(("api_key" = [])) +)] +pub async fn business_profiles_delete() {} + +/// Business Profile - Retrieve +/// +/// Retrieve existing *business profile* +#[utoipa::path( + get, + path = "/account/{account_id}/business_profile/{profile_id}", + params( + ("account_id" = String, Path, description = "The unique identifier for the merchant account"), + ("profile_id" = String, Path, description = "The unique identifier for the business profile") + ), + responses( + (status = 200, description = "Business Profile Updated", body = BusinessProfileResponse), + (status = 400, description = "Invalid data") + ), + tag = "Business Profile", + operation_id = "Retrieve a Business Profile", + security(("api_key" = [])) +)] +pub async fn business_profiles_retrieve() {} diff --git a/crates/openapi/src/routes/customers.rs b/crates/openapi/src/routes/customers.rs new file mode 100644 index 0000000000..7517cdc61a --- /dev/null +++ b/crates/openapi/src/routes/customers.rs @@ -0,0 +1,102 @@ +/// Customers - Create +/// +/// Creates a customer object and stores the customer details to be reused for future payments. +/// Incase the customer already exists in the system, this API will respond with the customer details. +#[utoipa::path( + post, + path = "/customers", + request_body ( + content = CustomerRequest, + examples (( "Update name and email of a customer" =( + value =json!( { + "email": "guest@example.com", + "name": "John Doe" + }) + ))) + ), + responses( + (status = 200, description = "Customer Created", body = CustomerResponse), + (status = 400, description = "Invalid data") + + ), + tag = "Customers", + operation_id = "Create a Customer", + security(("api_key" = [])) +)] +pub async fn customers_create() {} + +/// Customers - Retrieve +/// +/// Retrieves a customer's details. +#[utoipa::path( + get, + path = "/customers/{customer_id}", + params (("customer_id" = String, Path, description = "The unique identifier for the Customer")), + responses( + (status = 200, description = "Customer Retrieved", body = CustomerResponse), + (status = 404, description = "Customer was not found") + ), + tag = "Customers", + operation_id = "Retrieve a Customer", + security(("api_key" = []), ("ephemeral_key" = [])) +)] +pub async fn customers_retrieve() {} + +/// Customers - Update +/// +/// Updates the customer's details in a customer object. +#[utoipa::path( + post, + path = "/customers/{customer_id}", + request_body ( + content = CustomerRequest, + examples (( "Update name and email of a customer" =( + value =json!( { + "email": "guest@example.com", + "name": "John Doe" + }) + ))) + ), + params (("customer_id" = String, Path, description = "The unique identifier for the Customer")), + responses( + (status = 200, description = "Customer was Updated", body = CustomerResponse), + (status = 404, description = "Customer was not found") + ), + tag = "Customers", + operation_id = "Update a Customer", + security(("api_key" = [])) +)] +pub async fn customers_update() {} + +/// Customers - Delete +/// +/// Delete a customer record. +#[utoipa::path( + delete, + path = "/customers/{customer_id}", + params (("customer_id" = String, Path, description = "The unique identifier for the Customer")), + responses( + (status = 200, description = "Customer was Deleted", body = CustomerDeleteResponse), + (status = 404, description = "Customer was not found") + ), + tag = "Customers", + operation_id = "Delete a Customer", + security(("api_key" = [])) +)] +pub async fn customers_delete() {} + +/// Customers - List +/// +/// Lists all the customers for a particular merchant id. +#[utoipa::path( + post, + path = "/customers/list", + responses( + (status = 200, description = "Customers retrieved", body = Vec), + (status = 400, description = "Invalid Data"), + ), + tag = "Customers List", + operation_id = "List all Customers for a Merchant", + security(("api_key" = [])) +)] +pub async fn customers_list() {} diff --git a/crates/openapi/src/routes/disputes.rs b/crates/openapi/src/routes/disputes.rs new file mode 100644 index 0000000000..491edae410 --- /dev/null +++ b/crates/openapi/src/routes/disputes.rs @@ -0,0 +1,44 @@ +/// Disputes - Retrieve Dispute +/// Retrieves a dispute +#[utoipa::path( + get, + path = "/disputes/{dispute_id}", + params( + ("dispute_id" = String, Path, description = "The identifier for dispute") + ), + responses( + (status = 200, description = "The dispute was retrieved successfully", body = DisputeResponse), + (status = 404, description = "Dispute does not exist in our records") + ), + tag = "Disputes", + operation_id = "Retrieve a Dispute", + security(("api_key" = [])) +)] +pub async fn retrieve_dispute() {} + +/// Disputes - List Disputes +/// Lists all the Disputes for a merchant +#[utoipa::path( + get, + path = "/disputes/list", + params( + ("limit" = Option, Query, description = "The maximum number of Dispute Objects to include in the response"), + ("dispute_status" = Option, Query, description = "The status of dispute"), + ("dispute_stage" = Option, Query, description = "The stage of dispute"), + ("reason" = Option, Query, description = "The reason for dispute"), + ("connector" = Option, Query, description = "The connector linked to dispute"), + ("received_time" = Option, Query, description = "The time at which dispute is received"), + ("received_time.lt" = Option, Query, description = "Time less than the dispute received time"), + ("received_time.gt" = Option, Query, description = "Time greater than the dispute received time"), + ("received_time.lte" = Option, Query, description = "Time less than or equals to the dispute received time"), + ("received_time.gte" = Option, Query, description = "Time greater than or equals to the dispute received time"), + ), + responses( + (status = 200, description = "The dispute list was retrieved successfully", body = Vec), + (status = 401, description = "Unauthorized request") + ), + tag = "Disputes", + operation_id = "List Disputes", + security(("api_key" = [])) +)] +pub async fn retrieve_disputes_list() {} diff --git a/crates/openapi/src/routes/gsm.rs b/crates/openapi/src/routes/gsm.rs new file mode 100644 index 0000000000..f20cc1f261 --- /dev/null +++ b/crates/openapi/src/routes/gsm.rs @@ -0,0 +1,75 @@ +/// Gsm - Create +/// +/// Creates a GSM (Global Status Mapping) Rule. A GSM rule is used to map a connector's error message/error code combination during a particular payments flow/sub-flow to Hyperswitch's unified status/error code/error message combination. It is also used to decide the next action in the flow - retry/requeue/do_default +#[utoipa::path( + post, + path = "/gsm", + request_body( + content = GsmCreateRequest, + ), + responses( + (status = 200, description = "Gsm created", body = GsmResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Gsm", + operation_id = "Create Gsm Rule", + security(("admin_api_key" = [])), +)] +pub async fn create_gsm_rule() {} + +/// Gsm - Get +/// +/// Retrieves a Gsm Rule +#[utoipa::path( + post, + path = "/gsm/get", + request_body( + content = GsmRetrieveRequest, + ), + responses( + (status = 200, description = "Gsm retrieved", body = GsmResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Gsm", + operation_id = "Retrieve Gsm Rule", + security(("admin_api_key" = [])), +)] +pub async fn get_gsm_rule() {} + +/// Gsm - Update +/// +/// Updates a Gsm Rule +#[utoipa::path( + post, + path = "/gsm/update", + request_body( + content = GsmUpdateRequest, + ), + responses( + (status = 200, description = "Gsm updated", body = GsmResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Gsm", + operation_id = "Update Gsm Rule", + security(("admin_api_key" = [])), +)] +pub async fn update_gsm_rule() {} + +/// Gsm - Delete +/// +/// Deletes a Gsm Rule +#[utoipa::path( + post, + path = "/gsm/delete", + request_body( + content = GsmDeleteRequest, + ), + responses( + (status = 200, description = "Gsm deleted", body = GsmDeleteResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Gsm", + operation_id = "Delete Gsm Rule", + security(("admin_api_key" = [])), +)] +pub async fn delete_gsm_rule() {} diff --git a/crates/openapi/src/routes/mandates.rs b/crates/openapi/src/routes/mandates.rs new file mode 100644 index 0000000000..c61e2eb2f5 --- /dev/null +++ b/crates/openapi/src/routes/mandates.rs @@ -0,0 +1,61 @@ +/// Mandates - Retrieve Mandate +/// +/// Retrieves a mandate created using the Payments/Create API +#[utoipa::path( + get, + path = "/mandates/{mandate_id}", + params( + ("mandate_id" = String, Path, description = "The identifier for mandate") + ), + responses( + (status = 200, description = "The mandate was retrieved successfully", body = MandateResponse), + (status = 404, description = "Mandate does not exist in our records") + ), + tag = "Mandates", + operation_id = "Retrieve a Mandate", + security(("api_key" = [])) +)] +pub async fn get_mandate() {} + +/// Mandates - Revoke Mandate +/// +/// Revokes a mandate created using the Payments/Create API +#[utoipa::path( + post, + path = "/mandates/revoke/{mandate_id}", + params( + ("mandate_id" = String, Path, description = "The identifier for a mandate") + ), + responses( + (status = 200, description = "The mandate was revoked successfully", body = MandateRevokedResponse), + (status = 400, description = "Mandate does not exist in our records") + ), + tag = "Mandates", + operation_id = "Revoke a Mandate", + security(("api_key" = [])) +)] +pub async fn revoke_mandate() {} + +/// Mandates - List Mandates +#[utoipa::path( + get, + path = "/mandates/list", + params( + ("limit" = Option, Query, description = "The maximum number of Mandate Objects to include in the response"), + ("mandate_status" = Option, Query, description = "The status of mandate"), + ("connector" = Option, Query, description = "The connector linked to mandate"), + ("created_time" = Option, Query, description = "The time at which mandate is created"), + ("created_time.lt" = Option, Query, description = "Time less than the mandate created time"), + ("created_time.gt" = Option, Query, description = "Time greater than the mandate created time"), + ("created_time.lte" = Option, Query, description = "Time less than or equals to the mandate created time"), + ("created_time.gte" = Option, Query, description = "Time greater than or equals to the mandate created time"), + ), + responses( + (status = 200, description = "The mandate list was retrieved successfully", body = Vec), + (status = 401, description = "Unauthorized request") + ), + tag = "Mandates", + operation_id = "List Mandates", + security(("api_key" = [])) +)] +pub async fn retrieve_mandates_list() {} diff --git a/crates/openapi/src/routes/merchant_account.rs b/crates/openapi/src/routes/merchant_account.rs new file mode 100644 index 0000000000..967e28225c --- /dev/null +++ b/crates/openapi/src/routes/merchant_account.rs @@ -0,0 +1,125 @@ +/// Merchant Account - Create +/// +/// Create a new account for a *merchant* and the *merchant* could be a seller or retailer or client who likes to receive and send payments. +#[utoipa::path( + post, + path = "/accounts", + request_body( + content = MerchantAccountCreate, + examples( + ( + "Create a merchant account with minimal fields" = ( + value = json!({"merchant_id": "merchant_abc"}) + ) + ), + ( + "Create a merchant account with webhook url" = ( + value = json!({ + "merchant_id": "merchant_abc", + "webhook_details" : { + "webhook_url": "https://webhook.site/a5c54f75-1f7e-4545-b781-af525b7e37a0" + } + }) + ) + ), + ( + "Create a merchant account with return url" = ( + value = json!({"merchant_id": "merchant_abc", + "return_url": "https://example.com"}) + ) + ) + ) + + ), + responses( + (status = 200, description = "Merchant Account Created", body = MerchantAccountResponse), + (status = 400, description = "Invalid data") + ), + tag = "Merchant Account", + operation_id = "Create a Merchant Account", + security(("admin_api_key" = [])) +)] +pub async fn merchant_account_create() {} + +/// Merchant Account - Retrieve +/// +/// Retrieve a *merchant* account details. +#[utoipa::path( + get, + path = "/accounts/{account_id}", + params (("account_id" = String, Path, description = "The unique identifier for the merchant account")), + responses( + (status = 200, description = "Merchant Account Retrieved", body = MerchantAccountResponse), + (status = 404, description = "Merchant account not found") + ), + tag = "Merchant Account", + operation_id = "Retrieve a Merchant Account", + security(("admin_api_key" = [])) +)] +pub async fn retrieve_merchant_account() {} + +/// Merchant Account - Update +/// +/// Updates details of an existing merchant account. Helpful in updating merchant details such as email, contact details, or other configuration details like webhook, routing algorithm etc +#[utoipa::path( + post, + path = "/accounts/{account_id}", + request_body ( + content = MerchantAccountUpdate, + examples( + ( + "Update merchant name" = ( + value = json!({ + "merchant_id": "merchant_abc", + "merchant_name": "merchant_name" + }) + ) + ), + ("Update merchant name" = ( + value = json!({ + "merchant_id": "merchant_abc", + "merchant_name": "merchant_name" + }) + )), + ("Update webhook url" = ( + value = json!({ + "merchant_id": "merchant_abc", + "webhook_details": { + "webhook_url": "https://webhook.site/a5c54f75-1f7e-4545-b781-af525b7e37a0" + } + }) + ) + ), + ("Update return url" = ( + value = json!({ + "merchant_id": "merchant_abc", + "return_url": "https://example.com" + }) + )))), + params (("account_id" = String, Path, description = "The unique identifier for the merchant account")), + responses( + (status = 200, description = "Merchant Account Updated", body = MerchantAccountResponse), + (status = 404, description = "Merchant account not found") + ), + tag = "Merchant Account", + operation_id = "Update a Merchant Account", + security(("admin_api_key" = [])) +)] +pub async fn update_merchant_account() {} + +/// Merchant Account - Delete +/// +/// Delete a *merchant* account +#[utoipa::path( + delete, + path = "/accounts/{account_id}", + params (("account_id" = String, Path, description = "The unique identifier for the merchant account")), + responses( + (status = 200, description = "Merchant Account Deleted", body = MerchantAccountDeleteResponse), + (status = 404, description = "Merchant account not found") + ), + tag = "Merchant Account", + operation_id = "Delete a Merchant Account", + security(("admin_api_key" = [])) +)] +pub async fn delete_merchant_account() {} diff --git a/crates/openapi/src/routes/merchant_connector_account.rs b/crates/openapi/src/routes/merchant_connector_account.rs new file mode 100644 index 0000000000..6f7746ccd4 --- /dev/null +++ b/crates/openapi/src/routes/merchant_connector_account.rs @@ -0,0 +1,170 @@ +/// Merchant Connector - Create +/// +/// Creates a new Merchant Connector for the merchant account. The connector could be a payment processor/facilitator/acquirer or a provider of specialized services like Fraud/Accounting etc. +#[utoipa::path( + post, + path = "/accounts/{account_id}/connectors", + request_body( + content = MerchantConnectorCreate, + examples( + ( + "Create a merchant connector account with minimal fields" = ( + value = json!({ + "connector_type": "fiz_operations", + "connector_name": "adyen", + "connector_account_details": { + "auth_type": "BodyKey", + "api_key": "{{adyen-api-key}}", + "key1": "{{adyen_merchant_account}}" + } + }) + ) + ), + ( + "Create a merchant connector account under a specific business profile" = ( + value = json!({ + "connector_type": "fiz_operations", + "connector_name": "adyen", + "connector_account_details": { + "auth_type": "BodyKey", + "api_key": "{{adyen-api-key}}", + "key1": "{{adyen_merchant_account}}" + }, + "profile_id": "{{profile_id}}" + }) + ) + ), + ( + "Create a merchant account with custom connector label" = ( + value = json!({ + "connector_type": "fiz_operations", + "connector_name": "adyen", + "connector_label": "EU_adyen", + "connector_account_details": { + "auth_type": "BodyKey", + "api_key": "{{adyen-api-key}}", + "key1": "{{adyen_merchant_account}}" + } + }) + ) + ), + ) + ), + responses( + (status = 200, description = "Merchant Connector Created", body = MerchantConnectorResponse), + (status = 400, description = "Missing Mandatory fields"), + ), + tag = "Merchant Connector Account", + operation_id = "Create a Merchant Connector", + security(("admin_api_key" = [])) +)] +pub async fn payment_connector_create() {} + +/// Merchant Connector - Retrieve +/// +/// Retrieves details of a Connector account +#[utoipa::path( + get, + path = "/accounts/{account_id}/connectors/{connector_id}", + params( + ("account_id" = String, Path, description = "The unique identifier for the merchant account"), + ("connector_id" = i32, Path, description = "The unique identifier for the Merchant Connector") + ), + responses( + (status = 200, description = "Merchant Connector retrieved successfully", body = MerchantConnectorResponse), + (status = 404, description = "Merchant Connector does not exist in records"), + (status = 401, description = "Unauthorized request") + ), + tag = "Merchant Connector Account", + operation_id = "Retrieve a Merchant Connector", + security(("admin_api_key" = [])) +)] +pub async fn payment_connector_retrieve() {} + +/// Merchant Connector - List +/// +/// List Merchant Connector Details for the merchant +#[utoipa::path( + get, + path = "/accounts/{account_id}/connectors", + params( + ("account_id" = String, Path, description = "The unique identifier for the merchant account"), + ), + responses( + (status = 200, description = "Merchant Connector list retrieved successfully", body = Vec), + (status = 404, description = "Merchant Connector does not exist in records"), + (status = 401, description = "Unauthorized request") + ), + tag = "Merchant Connector Account", + operation_id = "List all Merchant Connectors", + security(("admin_api_key" = [])) +)] +pub async fn payment_connector_list() {} + +/// Merchant Connector - Update +/// +/// To update an existing Merchant Connector account. Helpful in enabling/disabling different payment methods and other settings for the connector +#[utoipa::path( + post, + path = "/accounts/{account_id}/connectors/{connector_id}", + request_body( + content = MerchantConnectorUpdate, + examples( + ( + "Enable card payment method" = ( + value = json! ({ + "connector_type": "fiz_operations", + "payment_methods_enabled": [ + { + "payment_method": "card" + } + ] + }) + ) + ), + ( + "Update webhook secret" = ( + value = json! ({ + "connector_webhook_details": { + "merchant_secret": "{{webhook_secret}}" + } + }) + ) + ) + ), + ), + params( + ("account_id" = String, Path, description = "The unique identifier for the merchant account"), + ("connector_id" = i32, Path, description = "The unique identifier for the Merchant Connector") + ), + responses( + (status = 200, description = "Merchant Connector Updated", body = MerchantConnectorResponse), + (status = 404, description = "Merchant Connector does not exist in records"), + (status = 401, description = "Unauthorized request") + ), + tag = "Merchant Connector Account", + operation_id = "Update a Merchant Connector", + security(("admin_api_key" = [])) +)] +pub async fn payment_connector_update() {} + +/// Merchant Connector - Delete +/// +/// Delete or Detach a Merchant Connector from Merchant Account +#[utoipa::path( + delete, + path = "/accounts/{account_id}/connectors/{connector_id}", + params( + ("account_id" = String, Path, description = "The unique identifier for the merchant account"), + ("connector_id" = i32, Path, description = "The unique identifier for the Merchant Connector") + ), + responses( + (status = 200, description = "Merchant Connector Deleted", body = MerchantConnectorDeleteResponse), + (status = 404, description = "Merchant Connector does not exist in records"), + (status = 401, description = "Unauthorized request") + ), + tag = "Merchant Connector Account", + operation_id = "Delete a Merchant Connector", + security(("admin_api_key" = [])) +)] +pub async fn payment_connector_delete() {} diff --git a/crates/openapi/src/routes/payment_link.rs b/crates/openapi/src/routes/payment_link.rs new file mode 100644 index 0000000000..9b9cb3a4d5 --- /dev/null +++ b/crates/openapi/src/routes/payment_link.rs @@ -0,0 +1,19 @@ +/// Payments Link - Retrieve +/// +/// To retrieve the properties of a Payment Link. This may be used to get the status of a previously initiated payment or next action for an ongoing payment +#[utoipa::path( + get, + path = "/payment_link/{payment_link_id}", + params( + ("payment_link_id" = String, Path, description = "The identifier for payment link") + ), + request_body=RetrievePaymentLinkRequest, + responses( + (status = 200, description = "Gets details regarding payment link", body = RetrievePaymentLinkResponse), + (status = 404, description = "No payment link found") + ), + tag = "Payments", + operation_id = "Retrieve a Payment Link", + security(("api_key" = []), ("publishable_key" = [])) +)] +pub async fn payment_link_retrieve() {} diff --git a/crates/openapi/src/routes/payment_method.rs b/crates/openapi/src/routes/payment_method.rs new file mode 100644 index 0000000000..ffb9d8c5f7 --- /dev/null +++ b/crates/openapi/src/routes/payment_method.rs @@ -0,0 +1,173 @@ +/// PaymentMethods - Create +/// +/// Creates and stores a payment method against a customer. +/// In case of cards, this API should be used only by PCI compliant merchants. +#[utoipa::path( + post, + path = "/payment_methods", + request_body ( + content = PaymentMethodCreate, + examples (( "Save a card" =( + value =json!( { + "payment_method": "card", + "payment_method_type": "credit", + "payment_method_issuer": "Visa", + "card": { + "card_number": "4242424242424242", + "card_exp_month": "11", + "card_exp_year": "25", + "card_holder_name": "John Doe" + }, + "customer_id": "{{customer_id}}" + }) + ))) + ), + responses( + (status = 200, description = "Payment Method Created", body = PaymentMethodResponse), + (status = 400, description = "Invalid Data") + + ), + tag = "Payment Methods", + operation_id = "Create a Payment Method", + security(("api_key" = [])) +)] +pub async fn create_payment_method_api() {} + +/// List payment methods for a Merchant +/// +/// Lists the applicable payment methods for a particular Merchant ID. +/// Use the client secret and publishable key authorization to list all relevant payment methods of the merchant for the payment corresponding to the client secret. +#[utoipa::path( + get, + path = "/account/payment_methods", + params ( + ("account_id" = String, Path, description = "The unique identifier for the merchant account"), + ("accepted_country" = Vec, Query, description = "The two-letter ISO currency code"), + ("accepted_currency" = Vec, Path, description = "The three-letter ISO currency code"), + ("minimum_amount" = i64, Query, description = "The minimum amount accepted for processing by the particular payment method."), + ("maximum_amount" = i64, Query, description = "The maximum amount accepted for processing by the particular payment method."), + ("recurring_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for recurring payments"), + ("installment_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for installment payments"), + ), + responses( + (status = 200, description = "Payment Methods retrieved", body = PaymentMethodListResponse), + (status = 400, description = "Invalid Data"), + (status = 404, description = "Payment Methods does not exist in records") + ), + tag = "Payment Methods", + operation_id = "List all Payment Methods for a Merchant", + security(("api_key" = []), ("publishable_key" = [])) +)] +pub async fn list_payment_method_api() {} + +/// List payment methods for a Customer +/// +/// Lists all the applicable payment methods for a particular Customer ID. +#[utoipa::path( + get, + path = "/customers/{customer_id}/payment_methods", + params ( + ("customer_id" = String, Path, description = "The unique identifier for the customer account"), + ("accepted_country" = Vec, Query, description = "The two-letter ISO currency code"), + ("accepted_currency" = Vec, Path, description = "The three-letter ISO currency code"), + ("minimum_amount" = i64, Query, description = "The minimum amount accepted for processing by the particular payment method."), + ("maximum_amount" = i64, Query, description = "The maximum amount accepted for processing by the particular payment method."), + ("recurring_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for recurring payments"), + ("installment_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for installment payments"), + ), + responses( + (status = 200, description = "Payment Methods retrieved", body = CustomerPaymentMethodsListResponse), + (status = 400, description = "Invalid Data"), + (status = 404, description = "Payment Methods does not exist in records") + ), + tag = "Payment Methods", + operation_id = "List all Payment Methods for a Customer", + security(("api_key" = [])) +)] +pub async fn list_customer_payment_method_api() {} + +/// List payment methods for a Payment +/// +/// Lists all the applicable payment methods for a particular payment tied to the `client_secret`. +#[utoipa::path( + get, + path = "/customers/payment_methods", + params ( + ("client-secret" = String, Path, description = "A secret known only to your client and the authorization server. Used for client side authentication"), + ("customer_id" = String, Path, description = "The unique identifier for the customer account"), + ("accepted_country" = Vec, Query, description = "The two-letter ISO currency code"), + ("accepted_currency" = Vec, Path, description = "The three-letter ISO currency code"), + ("minimum_amount" = i64, Query, description = "The minimum amount accepted for processing by the particular payment method."), + ("maximum_amount" = i64, Query, description = "The maximum amount accepted for processing by the particular payment method."), + ("recurring_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for recurring payments"), + ("installment_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for installment payments"), + ), + responses( + (status = 200, description = "Payment Methods retrieved for customer tied to its respective client-secret passed in the param", body = CustomerPaymentMethodsListResponse), + (status = 400, description = "Invalid Data"), + (status = 404, description = "Payment Methods does not exist in records") + ), + tag = "Payment Methods", + operation_id = "List all Payment Methods for a Customer", + security(("publishable_key" = [])) +)] +pub async fn list_customer_payment_method_api_client() {} + +/// Payment Method - Retrieve +/// +/// Retrieves a payment method of a customer. +#[utoipa::path( + get, + path = "/payment_methods/{method_id}", + params ( + ("method_id" = String, Path, description = "The unique identifier for the Payment Method"), + ), + responses( + (status = 200, description = "Payment Method retrieved", body = PaymentMethodResponse), + (status = 404, description = "Payment Method does not exist in records") + ), + tag = "Payment Methods", + operation_id = "Retrieve a Payment method", + security(("api_key" = [])) +)] +pub async fn payment_method_retrieve_api() {} + +/// Payment Method - Update +/// +/// Update an existing payment method of a customer. +/// This API is useful for use cases such as updating the card number for expired cards to prevent discontinuity in recurring payments. +#[utoipa::path( + post, + path = "/payment_methods/{method_id}", + params ( + ("method_id" = String, Path, description = "The unique identifier for the Payment Method"), + ), + request_body = PaymentMethodUpdate, + responses( + (status = 200, description = "Payment Method updated", body = PaymentMethodResponse), + (status = 404, description = "Payment Method does not exist in records") + ), + tag = "Payment Methods", + operation_id = "Update a Payment method", + security(("api_key" = [])) +)] +pub async fn payment_method_update_api() {} + +/// Payment Method - Delete +/// +/// Deletes a payment method of a customer. +#[utoipa::path( + delete, + path = "/payment_methods/{method_id}", + params ( + ("method_id" = String, Path, description = "The unique identifier for the Payment Method"), + ), + responses( + (status = 200, description = "Payment Method deleted", body = PaymentMethodDeleteResponse), + (status = 404, description = "Payment Method does not exist in records") + ), + tag = "Payment Methods", + operation_id = "Delete a Payment method", + security(("api_key" = [])) +)] +pub async fn payment_method_delete_api() {} diff --git a/crates/openapi/src/routes/payments.rs b/crates/openapi/src/routes/payments.rs new file mode 100644 index 0000000000..b6c83d5aae --- /dev/null +++ b/crates/openapi/src/routes/payments.rs @@ -0,0 +1,452 @@ +/// Payments - Create +/// +/// **Creates a payment object when amount and currency are passed.** This API is also used to create a mandate by passing the `mandate_object`. +/// +/// To completely process a payment you will have to create a payment, attach a payment method, confirm and capture funds. +/// +/// Depending on the user journey you wish to achieve, you may opt to complete all the steps in a single request by attaching a payment method, setting `confirm=true` and `capture_method = automatic` in the *Payments/Create API* request or you could use the following sequence of API requests to achieve the same: +/// +/// 1. Payments - Create +/// +/// 2. Payments - Update +/// +/// 3. Payments - Confirm +/// +/// 4. Payments - Capture. +/// +/// Use the client secret returned in this API along with your publishable key to make subsequent API calls from your client +#[utoipa::path( + post, + path = "/payments", + request_body( + content = PaymentsCreateRequest, + examples( + ( + "Create a payment with minimal fields" = ( + value = json!({"amount": 6540,"currency": "USD"}) + ) + ), + ( + "Create a payment with customer details and metadata" = ( + value = json!({ + "amount": 6540, + "currency": "USD", + "payment_id": "abcdefghijklmnopqrstuvwxyz", + "customer": { + "id": "cus_abcdefgh", + "name": "John Dough", + "phone": "9999999999", + "email": "john@example.com" + }, + "description": "Its my first payment request", + "statement_descriptor_name": "joseph", + "statement_descriptor_suffix": "JS", + "metadata": { + "udf1": "some-value", + "udf2": "some-value" + } + }) + ) + ), + ( + "Create a 3DS payment" = ( + value = json!({ + "amount": 6540, + "currency": "USD", + "authentication_type": "three_ds" + }) + ) + ), + ( + "Create a manual capture payment" = ( + value = json!({ + "amount": 6540, + "currency": "USD", + "capture_method": "manual" + }) + ) + ), + ( + "Create a setup mandate payment" = ( + value = json!({ + "amount": 6540, + "currency": "USD", + "confirm": true, + "customer_id": "StripeCustomer123", + "authentication_type": "no_three_ds", + "payment_method": "card", + "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", + "mandate_data": { + "customer_acceptance": { + "acceptance_type": "offline", + "accepted_at": "1963-05-03T04:07:52.723Z", + "online": { + "ip_address": "127.0.0.1", + "user_agent": "amet irure esse" + } + }, + "mandate_type": { + "single_use": { + "amount": 6540, + "currency": "USD" + } + } + } + }) + ) + ), + ( + "Create a recurring payment with mandate_id" = ( + value = json!({ + "amount": 6540, + "currency": "USD", + "confirm": true, + "customer_id": "StripeCustomer", + "authentication_type": "no_three_ds", + "mandate_id": "{{mandate_id}}", + "off_session": true + }) + ) + ), + ( + "Create a payment and save the card" = ( + value = json!({ + "amount": 6540, + "currency": "USD", + "confirm": true, + "customer_id": "StripeCustomer123", + "authentication_type": "no_three_ds", + "payment_method": "card", + "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" + }) + ) + ), + ( + "Create a payment using an already saved card's token" = ( + value = json!({ + "amount": 6540, + "currency": "USD", + "confirm": true, + "client_secret": "{{client_secret}}", + "payment_method": "card", + "payment_token": "{{payment_token}}", + "card_cvc": "123" + }) + ) + ), + ( + "Create a manual capture payment" = ( + value = json!({ + "amount": 6540, + "currency": "USD", + "customer": { + "id": "cus_abcdefgh" + }, + "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": "8056594427", + "country_code": "+91" + } + } + }) + ) + ) + ), + ), + responses( + (status = 200, description = "Payment created", body = PaymentsResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Payments", + operation_id = "Create a Payment", + security(("api_key" = [])), +)] +pub fn payments_create() {} + +/// Payments - Retrieve +/// +/// Retrieves a Payment. This API can also be used to get the status of a previously initiated payment or next action for an ongoing payment +#[utoipa::path( + get, + path = "/payments/{payment_id}", + params( + ("payment_id" = String, Path, description = "The identifier for payment") + ), + request_body=PaymentRetrieveBody, + responses( + (status = 200, description = "Gets the payment with final status", body = PaymentsResponse), + (status = 404, description = "No payment found") + ), + tag = "Payments", + operation_id = "Retrieve a Payment", + security(("api_key" = []), ("publishable_key" = [])) +)] +pub fn payments_retrieve() {} + +/// Payments - Update +/// +/// To update the properties of a *PaymentIntent* object. This may include attaching a payment method, or attaching customer object or metadata fields after the Payment is created +#[utoipa::path( + post, + path = "/payments/{payment_id}", + params( + ("payment_id" = String, Path, description = "The identifier for payment") + ), + request_body( + content = PaymentsUpdateRequest, + examples( + ( + "Update the payment amount" = ( + value = json!({ + "amount": 7654, + } + ) + ) + ), + ( + "Update the shipping address" = ( + value = json!( + { + "shipping": { + "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" + } + }, + } + ) + ) + ) + ) + ), + responses( + (status = 200, description = "Payment updated", body = PaymentsResponse), + (status = 400, description = "Missing mandatory fields") + ), + tag = "Payments", + operation_id = "Update a Payment", + security(("api_key" = []), ("publishable_key" = [])) +)] +pub fn payments_update() {} + +/// Payments - Confirm +/// +/// **Use this API to confirm the payment and forward the payment to the payment processor.** +/// +/// Alternatively you can confirm the payment within the *Payments/Create* API by setting `confirm=true`. After confirmation, the payment could either: +/// +/// 1. fail with `failed` status or +/// +/// 2. transition to a `requires_customer_action` status with a `next_action` block or +/// +/// 3. succeed with either `succeeded` in case of automatic capture or `requires_capture` in case of manual capture +#[utoipa::path( + post, + path = "/payments/{payment_id}/confirm", + params( + ("payment_id" = String, Path, description = "The identifier for payment") + ), + request_body( + content = PaymentsConfirmRequest, + examples( + ( + "Confirm a payment with payment method data" = ( + value = json!({ + "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" + } + } + } + ) + ) + ) + ) + ), + responses( + (status = 200, description = "Payment confirmed", body = PaymentsResponse), + (status = 400, description = "Missing mandatory fields") + ), + tag = "Payments", + operation_id = "Confirm a Payment", + security(("api_key" = []), ("publishable_key" = [])) +)] +pub fn payments_confirm() {} + +/// Payments - Capture +/// +/// To capture the funds for an uncaptured payment +#[utoipa::path( + post, + path = "/payments/{payment_id}/capture", + params( + ("payment_id" = String, Path, description = "The identifier for payment") + ), + request_body ( + content = PaymentsCaptureRequest, + examples( + ( + "Capture the full amount" = ( + value = json!({}) + ) + ), + ( + "Capture partial amount" = ( + value = json!({"amount_to_capture": 654}) + ) + ), + ) + ), + responses( + (status = 200, description = "Payment captured", body = PaymentsResponse), + (status = 400, description = "Missing mandatory fields") + ), + tag = "Payments", + operation_id = "Capture a Payment", + security(("api_key" = [])) +)] +pub fn payments_capture() {} + +/// Payments - Session token +/// +/// Creates a session object or a session token for wallets like Apple Pay, Google Pay, etc. These tokens are used by Hyperswitch's SDK to initiate these wallets' SDK. +#[utoipa::path( + post, + path = "/payments/session_tokens", + request_body=PaymentsSessionRequest, + responses( + (status = 200, description = "Payment session object created or session token was retrieved from wallets", body = PaymentsSessionResponse), + (status = 400, description = "Missing mandatory fields") + ), + tag = "Payments", + operation_id = "Create Session tokens for a Payment", + security(("publishable_key" = [])) +)] +pub fn payments_connector_session() {} + +/// Payments - Cancel +/// +/// A Payment could can be cancelled when it is in one of these statuses: `requires_payment_method`, `requires_capture`, `requires_confirmation`, `requires_customer_action`. +#[utoipa::path( + post, + path = "/payments/{payment_id}/cancel", + request_body ( + content = PaymentsCancelRequest, + examples( + ( + "Cancel the payment with minimal fields" = ( + value = json!({}) + ) + ), + ( + "Cancel the payment with cancellation reason" = ( + value = json!({"cancellation_reason": "requested_by_customer"}) + ) + ), + ) + ), + params( + ("payment_id" = String, Path, description = "The identifier for payment") + ), + responses( + (status = 200, description = "Payment canceled"), + (status = 400, description = "Missing mandatory fields") + ), + tag = "Payments", + operation_id = "Cancel a Payment", + security(("api_key" = [])) +)] +pub fn payments_cancel() {} + +/// Payments - List +/// +/// To list the *payments* +#[utoipa::path( + get, + path = "/payments/list", + params( + ("customer_id" = String, Query, description = "The identifier for the customer"), + ("starting_after" = String, Query, description = "A cursor for use in pagination, fetch the next list after some object"), + ("ending_before" = String, Query, description = "A cursor for use in pagination, fetch the previous list before some object"), + ("limit" = i64, Query, description = "Limit on the number of objects to return"), + ("created" = PrimitiveDateTime, Query, description = "The time at which payment is created"), + ("created_lt" = PrimitiveDateTime, Query, description = "Time less than the payment created time"), + ("created_gt" = PrimitiveDateTime, Query, description = "Time greater than the payment created time"), + ("created_lte" = PrimitiveDateTime, Query, description = "Time less than or equals to the payment created time"), + ("created_gte" = PrimitiveDateTime, Query, description = "Time greater than or equals to the payment created time") + ), + responses( + (status = 200, description = "Successfully retrieved a payment list", body = Vec), + (status = 404, description = "No payments found") + ), + tag = "Payments", + operation_id = "List all Payments", + security(("api_key" = [])) +)] +pub fn payments_list() {} + +/// Payments - Incremental Authorization +/// +/// Authorized amount for a payment can be incremented if it is in status: requires_capture +#[utoipa::path( + post, + path = "/payments/{payment_id}/incremental_authorization", + request_body=PaymentsIncrementalAuthorizationRequest, + params( + ("payment_id" = String, Path, description = "The identifier for payment") + ), + responses( + (status = 200, description = "Payment authorized amount incremented", body = PaymentsResponse), + (status = 400, description = "Missing mandatory fields") + ), + tag = "Payments", + operation_id = "Increment authorized amount for a Payment", + security(("api_key" = [])) +)] +pub fn payments_incremental_authorization() {} diff --git a/crates/openapi/src/routes/payouts.rs b/crates/openapi/src/routes/payouts.rs new file mode 100644 index 0000000000..3cc01de982 --- /dev/null +++ b/crates/openapi/src/routes/payouts.rs @@ -0,0 +1,85 @@ +/// Payouts - Create +#[utoipa::path( + post, + path = "/payouts/create", + request_body=PayoutCreateRequest, + responses( + (status = 200, description = "Payout created", body = PayoutCreateResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Payouts", + operation_id = "Create a Payout", + security(("api_key" = [])) +)] +pub async fn payouts_create() {} + +/// Payouts - Retrieve +#[utoipa::path( + get, + path = "/payouts/{payout_id}", + params( + ("payout_id" = String, Path, description = "The identifier for payout]") + ), + responses( + (status = 200, description = "Payout retrieved", body = PayoutCreateResponse), + (status = 404, description = "Payout does not exist in our records") + ), + tag = "Payouts", + operation_id = "Retrieve a Payout", + security(("api_key" = [])) +)] +pub async fn payouts_retrieve() {} + +/// Payouts - Update +#[utoipa::path( + post, + path = "/payouts/{payout_id}", + params( + ("payout_id" = String, Path, description = "The identifier for payout]") + ), + request_body=PayoutCreateRequest, + responses( + (status = 200, description = "Payout updated", body = PayoutCreateResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Payouts", + operation_id = "Update a Payout", + security(("api_key" = [])) +)] +pub async fn payouts_update() {} + +/// Payouts - Cancel +#[utoipa::path( + post, + path = "/payouts/{payout_id}/cancel", + params( + ("payout_id" = String, Path, description = "The identifier for payout") + ), + request_body=PayoutActionRequest, + responses( + (status = 200, description = "Payout cancelled", body = PayoutCreateResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Payouts", + operation_id = "Cancel a Payout", + security(("api_key" = [])) +)] +pub async fn payouts_cancel() {} + +/// Payouts - Fulfill +#[utoipa::path( + post, + path = "/payouts/{payout_id}/fulfill", + params( + ("payout_id" = String, Path, description = "The identifier for payout") + ), + request_body=PayoutActionRequest, + responses( + (status = 200, description = "Payout fulfilled", body = PayoutCreateResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Payouts", + operation_id = "Fulfill a Payout", + security(("api_key" = [])) +)] +pub async fn payouts_fulfill() {} diff --git a/crates/openapi/src/routes/refunds.rs b/crates/openapi/src/routes/refunds.rs new file mode 100644 index 0000000000..aa4728869b --- /dev/null +++ b/crates/openapi/src/routes/refunds.rs @@ -0,0 +1,145 @@ +/// Refunds - Create +/// +/// Creates a refund against an already processed payment. In case of some processors, you can even opt to refund only a partial amount multiple times until the original charge amount has been refunded +#[utoipa::path( + post, + path = "/refunds", + request_body( + content = RefundRequest, + examples( + ( + "Create an instant refund to refund the whole amount" = ( + value = json!({ + "payment_id": "{{payment_id}}", + "refund_type": "instant" + }) + ) + ), + ( + "Create an instant refund to refund partial amount" = ( + value = json!({ + "payment_id": "{{payment_id}}", + "refund_type": "instant", + "amount": 654 + }) + ) + ), + ( + "Create an instant refund with reason" = ( + value = json!({ + "payment_id": "{{payment_id}}", + "refund_type": "instant", + "amount": 6540, + "reason": "Customer returned product" + }) + ) + ), + ) + ), + responses( + (status = 200, description = "Refund created", body = RefundResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Refunds", + operation_id = "Create a Refund", + security(("api_key" = [])) +)] +pub async fn refunds_create() {} + +/// Refunds - Retrieve +/// +/// Retrieves a Refund. This may be used to get the status of a previously initiated refund +#[utoipa::path( + get, + path = "/refunds/{refund_id}", + params( + ("refund_id" = String, Path, description = "The identifier for refund") + ), + responses( + (status = 200, description = "Refund retrieved", body = RefundResponse), + (status = 404, description = "Refund does not exist in our records") + ), + tag = "Refunds", + operation_id = "Retrieve a Refund", + security(("api_key" = [])) +)] +pub async fn refunds_retrieve() {} + +/// Refunds - Retrieve (POST) +/// +/// To retrieve the properties of a Refund. This may be used to get the status of a previously initiated payment or next action for an ongoing payment +#[utoipa::path( + get, + path = "/refunds/sync", + responses( + (status = 200, description = "Refund retrieved", body = RefundResponse), + (status = 404, description = "Refund does not exist in our records") + ), + tag = "Refunds", + operation_id = "Retrieve a Refund", + security(("api_key" = [])) +)] +pub async fn refunds_retrieve_with_body() {} + +/// Refunds - Update +/// +/// Updates the properties of a Refund object. This API can be used to attach a reason for the refund or metadata fields +#[utoipa::path( + post, + path = "/refunds/{refund_id}", + params( + ("refund_id" = String, Path, description = "The identifier for refund") + ), + request_body( + content = RefundUpdateRequest, + examples( + ( + "Update refund reason" = ( + value = json!({ + "reason": "Paid by mistake" + }) + ) + ), + ) + ), + responses( + (status = 200, description = "Refund updated", body = RefundResponse), + (status = 400, description = "Missing Mandatory fields") + ), + tag = "Refunds", + operation_id = "Update a Refund", + security(("api_key" = [])) +)] +pub async fn refunds_update() {} + +/// Refunds - List +/// +/// Lists all the refunds associated with the merchant or a payment_id if payment_id is not provided +#[utoipa::path( + post, + path = "/refunds/list", + request_body=RefundListRequest, + responses( + (status = 200, description = "List of refunds", body = RefundListResponse), + ), + tag = "Refunds", + operation_id = "List all Refunds", + security(("api_key" = [])) +)] +pub fn refunds_list() {} + +/// Refunds - Filter +/// +/// To list the refunds filters associated with list of connectors, currencies and payment statuses +#[utoipa::path( + post, + path = "/refunds/filter", + request_body=TimeRange, + responses( + (status = 200, description = "List of filters", body = RefundListMetaData), + ), + tag = "Refunds", + operation_id = "List all filters for Refunds", + security(("api_key" = [])) +)] +pub async fn refunds_filter_list() {} diff --git a/crates/openapi/src/routes/routing.rs b/crates/openapi/src/routes/routing.rs new file mode 100644 index 0000000000..ecfac39f9e --- /dev/null +++ b/crates/openapi/src/routes/routing.rs @@ -0,0 +1,202 @@ +/// Routing - Create +/// +/// Create a routing config +#[utoipa::path( + post, + path = "/routing", + request_body = RoutingConfigRequest, + responses( + (status = 200, description = "Routing config created", body = RoutingDictionaryRecord), + (status = 400, description = "Request body is malformed"), + (status = 500, description = "Internal server error"), + (status = 404, description = "Resource missing"), + (status = 422, description = "Unprocessable request"), + (status = 403, description = "Forbidden"), + ), + tag = "Routing", + operation_id = "Create a routing config", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_create_config() {} + +/// Routing - Activate config +/// +/// Activate a routing config +#[utoipa::path( + post, + path = "/routing/{algorithm_id}/activate", + params( + ("algorithm_id" = String, Path, description = "The unique identifier for a config"), + ), + responses( + (status = 200, description = "Routing config activated", body = RoutingDictionaryRecord), + (status = 500, description = "Internal server error"), + (status = 404, description = "Resource missing"), + (status = 400, description = "Bad request") + ), + tag = "Routing", + operation_id = "Activate a routing config", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_link_config() {} + +/// Routing - Retrieve +/// +/// Retrieve a routing algorithm + +#[utoipa::path( + get, + path = "/routing/{algorithm_id}", + params( + ("algorithm_id" = String, Path, description = "The unique identifier for a config"), + ), + responses( + (status = 200, description = "Successfully fetched routing config", body = MerchantRoutingAlgorithm), + (status = 500, description = "Internal server error"), + (status = 404, description = "Resource missing"), + (status = 403, description = "Forbidden") + ), + tag = "Routing", + operation_id = "Retrieve a routing config", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_retrieve_config() {} + +/// Routing - List +/// +/// List all routing configs +#[utoipa::path( + get, + path = "/routing", + params( + ("limit" = Option, Query, description = "The number of records to be returned"), + ("offset" = Option, Query, description = "The record offset from which to start gathering of results"), + ("profile_id" = Option, Query, description = "The unique identifier for a merchant profile"), + ), + responses( + (status = 200, description = "Successfully fetched routing configs", body = RoutingKind), + (status = 500, description = "Internal server error"), + (status = 404, description = "Resource missing") + ), + tag = "Routing", + operation_id = "List routing configs", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn list_routing_configs() {} + +/// Routing - Deactivate +/// +/// Deactivates a routing config +#[utoipa::path( + post, + path = "/routing/deactivate", + request_body = RoutingConfigRequest, + responses( + (status = 200, description = "Successfully deactivated routing config", body = RoutingDictionaryRecord), + (status = 500, description = "Internal server error"), + (status = 400, description = "Malformed request"), + (status = 403, description = "Malformed request"), + (status = 422, description = "Unprocessable request") + ), + tag = "Routing", + operation_id = "Deactivate a routing config", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_unlink_config() {} + +/// Routing - Update Default Config +/// +/// Update default fallback config +#[utoipa::path( + post, + path = "/routing/default", + request_body = Vec, + responses( + (status = 200, description = "Successfully updated default config", body = Vec), + (status = 500, description = "Internal server error"), + (status = 400, description = "Malformed request"), + (status = 422, description = "Unprocessable request") + ), + tag = "Routing", + operation_id = "Update default fallback config", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_update_default_config() {} + +/// Routing - Retrieve Default Config +/// +/// Retrieve default fallback config +#[utoipa::path( + get, + path = "/routing/default", + responses( + (status = 200, description = "Successfully retrieved default config", body = Vec), + (status = 500, description = "Internal server error") + ), + tag = "Routing", + operation_id = "Retrieve default fallback config", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_retrieve_default_config() {} + +/// Routing - Retrieve Config +/// +/// Retrieve active config +#[utoipa::path( + get, + path = "/routing/active", + params( + ("profile_id" = Option, Query, description = "The unique identifier for a merchant profile"), + ), + responses( + (status = 200, description = "Successfully retrieved active config", body = LinkedRoutingConfigRetrieveResponse), + (status = 500, description = "Internal server error"), + (status = 404, description = "Resource missing"), + (status = 403, description = "Forbidden") + ), + tag = "Routing", + operation_id = "Retrieve active config", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_retrieve_linked_config() {} + +/// Routing - Retrieve Default For Profile +/// +/// Retrieve default config for profiles +#[utoipa::path( + get, + path = "/routing/default/profile", + responses( + (status = 200, description = "Successfully retrieved default config", body = ProfileDefaultRoutingConfig), + (status = 500, description = "Internal server error"), + (status = 404, description = "Resource missing") + ), + tag = "Routing", + operation_id = "Retrieve default configs for all profiles", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_retrieve_default_config_for_profiles() {} + +/// Routing - Update Default For Profile +/// +/// Update default config for profiles +#[utoipa::path( + post, + path = "/routing/default/profile/{profile_id}", + request_body = Vec, + params( + ("profile_id" = String, Path, description = "The unique identifier for a profile"), + ), + responses( + (status = 200, description = "Successfully updated default config for profile", body = ProfileDefaultRoutingConfig), + (status = 500, description = "Internal server error"), + (status = 404, description = "Resource missing"), + (status = 400, description = "Malformed request"), + (status = 422, description = "Unprocessable request"), + (status = 403, description = "Forbidden"), + ), + tag = "Routing", + operation_id = "Update default configs for all profiles", + security(("api_key" = []), ("jwt_key" = [])) +)] +pub async fn routing_update_default_config_for_profile() {} diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml index 2c3ef2911c..e575daf7e7 100644 --- a/crates/router/Cargo.toml +++ b/crates/router/Cargo.toml @@ -21,7 +21,7 @@ olap = ["data_models/olap", "storage_impl/olap", "scheduler/olap", "dep:analytic oltp = ["storage_impl/oltp"] kv_store = ["scheduler/kv_store"] accounts_cache = [] -openapi = ["olap", "oltp", "payouts"] +openapi = ["olap", "oltp", "payouts", "dep:openapi"] vergen = ["router_env/vergen"] backwards_compatibility = ["api_models/backwards_compatibility"] business_profile_routing = ["api_models/business_profile_routing"] @@ -96,7 +96,6 @@ tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] } unicode-segmentation = "1.10.1" url = { version = "2.4.0", features = ["serde"] } utoipa = { version = "3.3.0", features = ["preserve_order", "time"] } -utoipa-swagger-ui = { version = "3.1.3", features = ["actix-web"] } uuid = { version = "1.3.3", features = ["serde", "v4"] } validator = "0.16.0" x509-parser = "0.15.0" @@ -121,6 +120,7 @@ router_derive = { version = "0.1.0", path = "../router_derive" } router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] } scheduler = { version = "0.1.0", path = "../scheduler", default-features = false } storage_impl = { version = "0.1.0", path = "../storage_impl", default-features = false } +openapi = { version = "0.1.0", path = "../openapi", optional = true } erased-serde = "0.3.31" quick-xml = { version = "0.31.0", features = ["serialize"] } rdkafka = "0.36.0" @@ -139,6 +139,7 @@ time = { version = "0.3.21", features = ["macros"] } tokio = "1.35.1" wiremock = "0.5.18" + # First party dev-dependencies test_utils = { version = "0.1.0", path = "../test_utils" } diff --git a/crates/router/src/bin/router.rs b/crates/router/src/bin/router.rs index a02758d8ed..094f799cb2 100644 --- a/crates/router/src/bin/router.rs +++ b/crates/router/src/bin/router.rs @@ -9,24 +9,6 @@ async fn main() -> ApplicationResult<()> { // get commandline config before initializing config let cmd_line = ::parse(); - #[cfg(feature = "openapi")] - { - use router::configs::settings::Subcommand; - if let Some(Subcommand::GenerateOpenapiSpec) = cmd_line.subcommand { - let file_path = "openapi/openapi_spec.json"; - #[allow(clippy::expect_used)] - std::fs::write( - file_path, - ::openapi() - .to_pretty_json() - .expect("Failed to serialize OpenAPI specification as JSON"), - ) - .expect("Failed to write OpenAPI specification to file"); - println!("Successfully saved OpenAPI specification file at '{file_path}'"); - return Ok(()); - } - } - #[allow(clippy::expect_used)] let conf = Settings::with_config_path(cmd_line.config_path) .expect("Unable to construct application configuration"); diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs index ee22e40190..bb56a173da 100644 --- a/crates/router/src/lib.rs +++ b/crates/router/src/lib.rs @@ -12,6 +12,7 @@ pub mod cors; pub mod db; pub mod env; pub(crate) mod macros; + pub mod routes; pub mod workflows; @@ -19,7 +20,6 @@ pub mod workflows; pub mod analytics; pub mod events; pub mod middleware; -pub mod openapi; pub mod services; pub mod types; pub mod utils; @@ -93,15 +93,6 @@ pub fn mk_app( > { let mut server_app = get_application_builder(request_body_limit); - #[cfg(feature = "openapi")] - { - use utoipa::OpenApi; - server_app = server_app.service( - utoipa_swagger_ui::SwaggerUi::new("/docs/{_:.*}") - .url("/docs/openapi.json", openapi::ApiDoc::openapi()), - ); - } - #[cfg(feature = "dummy_connector")] { use routes::DummyConnector; diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index 44822efddc..f490cee8da 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -458,7 +458,7 @@ impl Routing { ) .service( web::resource("") - .route(web::get().to(cloud_routing::routing_retrieve_dictionary)) + .route(web::get().to(cloud_routing::list_routing_configs)) .route(web::post().to(cloud_routing::routing_create_config)), ) .service( diff --git a/crates/router/src/routes/customers.rs b/crates/router/src/routes/customers.rs index e7a0804500..012030df6b 100644 --- a/crates/router/src/routes/customers.rs +++ b/crates/router/src/routes/customers.rs @@ -8,21 +8,6 @@ use crate::{ types::api::customers, }; -/// Create Customer -/// -/// Create a customer object and store the customer details to be reused for future payments. Incase the customer already exists in the system, this API will respond with the customer details. -#[utoipa::path( - post, - path = "/customers", - request_body = CustomerRequest, - responses( - (status = 200, description = "Customer Created", body = CustomerResponse), - (status = 400, description = "Invalid data") - ), - tag = "Customers", - operation_id = "Create a Customer", - security(("api_key" = [])) -)] #[instrument(skip_all, fields(flow = ?Flow::CustomersCreate))] pub async fn customers_create( state: web::Data, @@ -45,21 +30,7 @@ pub async fn customers_create( )) .await } -/// Retrieve Customer -/// -/// Retrieve a customer's details. -#[utoipa::path( - get, - path = "/customers/{customer_id}", - params (("customer_id" = String, Path, description = "The unique identifier for the Customer")), - responses( - (status = 200, description = "Customer Retrieved", body = CustomerResponse), - (status = 404, description = "Customer was not found") - ), - tag = "Customers", - operation_id = "Retrieve a Customer", - security(("api_key" = []), ("ephemeral_key" = [])) -)] + #[instrument(skip_all, fields(flow = ?Flow::CustomersRetrieve))] pub async fn customers_retrieve( state: web::Data, @@ -93,20 +64,6 @@ pub async fn customers_retrieve( .await } -/// List customers for a merchant -/// -/// To filter and list the customers for a particular merchant id -#[utoipa::path( - post, - path = "/customers/list", - responses( - (status = 200, description = "Customers retrieved", body = Vec), - (status = 400, description = "Invalid Data"), - ), - tag = "Customers List", - operation_id = "List all Customers for a Merchant", - security(("api_key" = [])) -)] #[instrument(skip_all, fields(flow = ?Flow::CustomersList))] pub async fn customers_list(state: web::Data, req: HttpRequest) -> HttpResponse { let flow = Flow::CustomersList; @@ -127,22 +84,6 @@ pub async fn customers_list(state: web::Data, req: HttpRequest) -> Htt .await } -/// Update Customer -/// -/// Updates the customer's details in a customer object. -#[utoipa::path( - post, - path = "/customers/{customer_id}", - request_body = CustomerRequest, - params (("customer_id" = String, Path, description = "The unique identifier for the Customer")), - responses( - (status = 200, description = "Customer was Updated", body = CustomerResponse), - (status = 404, description = "Customer was not found") - ), - tag = "Customers", - operation_id = "Update a Customer", - security(("api_key" = [])) -)] #[instrument(skip_all, fields(flow = ?Flow::CustomersUpdate))] pub async fn customers_update( state: web::Data, @@ -168,21 +109,7 @@ pub async fn customers_update( )) .await } -/// Delete Customer -/// -/// Delete a customer record. -#[utoipa::path( - delete, - path = "/customers/{customer_id}", - params (("customer_id" = String, Path, description = "The unique identifier for the Customer")), - responses( - (status = 200, description = "Customer was Deleted", body = CustomerDeleteResponse), - (status = 404, description = "Customer was not found") - ), - tag = "Customers", - operation_id = "Delete a Customer", - security(("api_key" = [])) -)] + #[instrument(skip_all, fields(flow = ?Flow::CustomersDelete))] pub async fn customers_delete( state: web::Data, diff --git a/crates/router/src/routes/mandates.rs b/crates/router/src/routes/mandates.rs index 342fe23c38..eafd61dcde 100644 --- a/crates/router/src/routes/mandates.rs +++ b/crates/router/src/routes/mandates.rs @@ -10,7 +10,7 @@ use crate::{ /// Mandates - Retrieve Mandate /// -/// Retrieve a mandate +/// Retrieves a mandate created using the Payments/Create API #[utoipa::path( get, path = "/mandates/{mandate_id}", @@ -49,12 +49,12 @@ pub async fn get_mandate( } /// Mandates - Revoke Mandate /// -/// Revoke a mandate +/// Revokes a mandate created using the Payments/Create API #[utoipa::path( post, path = "/mandates/revoke/{mandate_id}", params( - ("mandate_id" = String, Path, description = "The identifier for mandate") + ("mandate_id" = String, Path, description = "The identifier for a mandate") ), responses( (status = 200, description = "The mandate was revoked successfully", body = MandateRevokedResponse), diff --git a/crates/router/src/routes/payment_methods.rs b/crates/router/src/routes/payment_methods.rs index 55564a6386..ef7047bffa 100644 --- a/crates/router/src/routes/payment_methods.rs +++ b/crates/router/src/routes/payment_methods.rs @@ -16,21 +16,6 @@ use crate::{ utils::Encode, }; -/// PaymentMethods - Create -/// -/// To create a payment method against a customer object. In case of cards, this API could be used only by PCI compliant merchants -#[utoipa::path( - post, - path = "/payment_methods", - request_body = PaymentMethodCreate, - responses( - (status = 200, description = "Payment Method Created", body = PaymentMethodResponse), - (status = 400, description = "Invalid Data") - ), - tag = "Payment Methods", - operation_id = "Create a Payment Method", - security(("api_key" = [])) -)] #[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsCreate))] pub async fn create_payment_method_api( state: web::Data, @@ -57,30 +42,7 @@ pub async fn create_payment_method_api( )) .await } -/// List payment methods for a Merchant -/// -/// To filter and list the applicable payment methods for a particular Merchant ID -#[utoipa::path( - get, - path = "/account/payment_methods", - params ( - ("account_id" = String, Path, description = "The unique identifier for the merchant account"), - ("accepted_country" = Vec, Query, description = "The two-letter ISO currency code"), - ("accepted_currency" = Vec, Path, description = "The three-letter ISO currency code"), - ("minimum_amount" = i64, Query, description = "The minimum amount accepted for processing by the particular payment method."), - ("maximum_amount" = i64, Query, description = "The maximum amount amount accepted for processing by the particular payment method."), - ("recurring_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for recurring payments"), - ("installment_payment_enabled" = bool, Query, description = "Indicates whether the payment method is eligible for installment payments"), - ), - responses( - (status = 200, description = "Payment Methods retrieved", body = PaymentMethodListResponse), - (status = 400, description = "Invalid Data"), - (status = 404, description = "Payment Methods does not exist in records") - ), - tag = "Payment Methods", - operation_id = "List all Payment Methods for a Merchant", - security(("api_key" = []), ("publishable_key" = [])) -)] + #[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsList))] pub async fn list_payment_method_api( state: web::Data, @@ -214,23 +176,7 @@ pub async fn list_customer_payment_method_api_client( )) .await } -/// Payment Method - Retrieve -/// -/// To retrieve a payment method -#[utoipa::path( - get, - path = "/payment_methods/{method_id}", - params ( - ("method_id" = String, Path, description = "The unique identifier for the Payment Method"), - ), - responses( - (status = 200, description = "Payment Method retrieved", body = PaymentMethodResponse), - (status = 404, description = "Payment Method does not exist in records") - ), - tag = "Payment Methods", - operation_id = "Retrieve a Payment method", - security(("api_key" = [])) -)] + #[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsRetrieve))] pub async fn payment_method_retrieve_api( state: web::Data, @@ -254,24 +200,7 @@ pub async fn payment_method_retrieve_api( )) .await } -/// Payment Method - Update -/// -/// To update an existing payment method attached to a customer object. This API is useful for use cases such as updating the card number for expired cards to prevent discontinuity in recurring payments -#[utoipa::path( - post, - path = "/payment_methods/{method_id}", - params ( - ("method_id" = String, Path, description = "The unique identifier for the Payment Method"), - ), - request_body = PaymentMethodUpdate, - responses( - (status = 200, description = "Payment Method updated", body = PaymentMethodResponse), - (status = 404, description = "Payment Method does not exist in records") - ), - tag = "Payment Methods", - operation_id = "Update a Payment method", - security(("api_key" = [])) -)] + #[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsUpdate))] pub async fn payment_method_update_api( state: web::Data, @@ -301,23 +230,7 @@ pub async fn payment_method_update_api( )) .await } -/// Payment Method - Delete -/// -/// Delete payment method -#[utoipa::path( - delete, - path = "/payment_methods/{method_id}", - params ( - ("method_id" = String, Path, description = "The unique identifier for the Payment Method"), - ), - responses( - (status = 200, description = "Payment Method deleted", body = PaymentMethodDeleteResponse), - (status = 404, description = "Payment Method does not exist in records") - ), - tag = "Payment Methods", - operation_id = "Delete a Payment method", - security(("api_key" = [])) -)] + #[instrument(skip_all, fields(flow = ?Flow::PaymentMethodsDelete))] pub async fn payment_method_delete_api( state: web::Data, diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs index 379cd4f2f1..b822e6d4e6 100644 --- a/crates/router/src/routes/payments.rs +++ b/crates/router/src/routes/payments.rs @@ -17,12 +17,6 @@ use crate::{ payments::{self, PaymentRedirectFlow}, utils as core_utils, }, - // openapi::examples::{ - // PAYMENTS_CREATE, PAYMENTS_CREATE_MINIMUM_FIELDS, PAYMENTS_CREATE_WITH_ADDRESS, - // PAYMENTS_CREATE_WITH_CUSTOMER_DATA, PAYMENTS_CREATE_WITH_FORCED_3DS, - // PAYMENTS_CREATE_WITH_MANUAL_CAPTURE, PAYMENTS_CREATE_WITH_NOON_ORDER_CATETORY, - // PAYMENTS_CREATE_WITH_ORDER_DETAILS, - // }, routes::lock_utils, services::{api, authentication as auth}, types::{ @@ -1153,7 +1147,7 @@ where ("payment_id" = String, Path, description = "The identifier for payment") ), responses( - (status = 200, description = "Payment authorized amount incremented"), + (status = 200, description = "Payment authorized amount incremented", body = PaymentsResponse), (status = 400, description = "Missing mandatory fields") ), tag = "Payments", diff --git a/crates/router/src/routes/routing.rs b/crates/router/src/routes/routing.rs index e7e31cb36a..0f139e9361 100644 --- a/crates/router/src/routes/routing.rs +++ b/crates/router/src/routes/routing.rs @@ -113,7 +113,7 @@ pub async fn routing_retrieve_config( #[cfg(feature = "olap")] #[instrument(skip_all)] -pub async fn routing_retrieve_dictionary( +pub async fn list_routing_configs( state: web::Data, req: HttpRequest, #[cfg(feature = "business_profile_routing")] query: web::Query, diff --git a/crates/router_derive/src/lib.rs b/crates/router_derive/src/lib.rs index 109003e0cc..c4b6bf3f47 100644 --- a/crates/router_derive/src/lib.rs +++ b/crates/router_derive/src/lib.rs @@ -505,7 +505,10 @@ pub fn operation_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStre /// } /// ``` -#[proc_macro_derive(PolymorphicSchema, attributes(mandatory_in, generate_schemas))] +#[proc_macro_derive( + PolymorphicSchema, + attributes(mandatory_in, generate_schemas, remove_in) +)] pub fn polymorphic_schema(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let input = syn::parse_macro_input!(input as syn::DeriveInput); diff --git a/crates/router_derive/src/macros/generate_schema.rs b/crates/router_derive/src/macros/generate_schema.rs index 05d5b2919e..4dd6db5d60 100644 --- a/crates/router_derive/src/macros/generate_schema.rs +++ b/crates/router_derive/src/macros/generate_schema.rs @@ -1,7 +1,7 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use indexmap::IndexMap; -use syn::{self, parse_quote, punctuated::Punctuated, Token}; +use syn::{self, parse::Parse, parse_quote, punctuated::Punctuated, Token}; use crate::macros::helpers; @@ -19,6 +19,74 @@ fn get_inner_path_ident(attribute: &syn::Attribute) -> syn::Result>()) } +#[allow(dead_code)] +/// Get the type of field +fn get_field_type(field_type: syn::Type) -> syn::Result { + if let syn::Type::Path(path) = field_type { + path.path + .segments + .last() + .map(|last_path_segment| last_path_segment.ident.to_owned()) + .ok_or(syn::Error::new( + proc_macro2::Span::call_site(), + "Atleast one ident must be specified", + )) + } else { + Err(syn::Error::new( + proc_macro2::Span::call_site(), + "Only path fields are supported", + )) + } +} + +#[allow(dead_code)] +/// Get the inner type of option +fn get_inner_option_type(field: &syn::Type) -> syn::Result { + if let syn::Type::Path(ref path) = &field { + if let Some(segment) = path.path.segments.last() { + if let syn::PathArguments::AngleBracketed(ref args) = &segment.arguments { + if let Some(syn::GenericArgument::Type(ty)) = args.args.first() { + return get_field_type(ty.clone()); + } + } + } + } + + Err(syn::Error::new( + proc_macro2::Span::call_site(), + "Only path fields are supported", + )) +} + +mod schema_keyword { + use syn::custom_keyword; + + custom_keyword!(schema); +} + +#[derive(Debug, Clone)] +pub struct SchemaMeta { + struct_name: syn::Ident, + type_ident: syn::Ident, +} + +/// parse #[mandatory_in(PaymentsCreateRequest = u64)] +impl Parse for SchemaMeta { + fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { + let struct_name = input.parse::()?; + input.parse::()?; + let type_ident = input.parse::()?; + Ok(Self { + struct_name, + type_ident, + }) + } +} + +impl quote::ToTokens for SchemaMeta { + fn to_tokens(&self, _: &mut proc_macro2::TokenStream) {} +} + pub fn polymorphic_macro_derive_inner( input: syn::DeriveInput, ) -> syn::Result { @@ -30,12 +98,21 @@ pub fn polymorphic_macro_derive_inner( // Go through all the fields and create a mapping of required fields for a schema // PaymentsCreate -> ["amount","currency"] - // This will be stored in a hashset + // This will be stored in the hashmap with key as // required_fields -> ((amount, PaymentsCreate), (currency, PaymentsCreate)) - let mut required_fields = HashSet::<(syn::Ident, syn::Ident)>::new(); + // and values as the type + // + // (amount, PaymentsCreate) -> Amount + let mut required_fields = HashMap::<(syn::Ident, syn::Ident), syn::Ident>::new(); + + // These fields will be removed in the schema + // PaymentsUpdate -> ["client_secret"] + // This will be stored in a hashset + // hide_fields -> ((client_secret, PaymentsUpdate)) + let mut hide_fields = HashSet::<(syn::Ident, syn::Ident)>::new(); let mut all_fields = IndexMap::>::new(); - fields.iter().for_each(|field| { + for field in fields { // Partition the attributes of a field into two vectors // One with #[mandatory_in] attributes present // Rest of the attributes ( include only the schema attribute, serde is not required) @@ -44,6 +121,12 @@ pub fn polymorphic_macro_derive_inner( .iter() .partition::, _>(|attribute| attribute.path().is_ident("mandatory_in")); + let hidden_fields = field + .attrs + .iter() + .filter(|attribute| attribute.path().is_ident("remove_in")) + .collect::>(); + // Other attributes ( schema ) are to be printed as is other_attributes .iter() @@ -68,7 +151,31 @@ pub fn polymorphic_macro_derive_inner( // ("currency", PaymentsConfirmRequest) // // For these attributes, we need to later add #[schema(required = true)] attribute - _ = mandatory_attribute + let field_ident = field.ident.ok_or(syn::Error::new( + proc_macro2::Span::call_site(), + "Cannot use `mandatory_in` on unnamed fields", + ))?; + + // Parse the #[mandatory_in(PaymentsCreateRequest = u64)] and insert into hashmap + // key -> ("amount", PaymentsCreateRequest) + // value -> u64 + if let Some(mandatory_in_attribute) = + helpers::get_metadata_inner::("mandatory_in", mandatory_attribute)?.first() + { + let key = ( + field_ident.clone(), + mandatory_in_attribute.struct_name.clone(), + ); + let value = mandatory_in_attribute.type_ident.clone(); + required_fields.insert(key, value); + } + + // Hidden fields are to be inserted in the Hashset + // The hashset will store it in this format + // ("client_secret", PaymentsUpdate) + // + // These fields will not be added to the struct + _ = hidden_fields .iter() // Filter only #[mandatory_in] attributes .map(|&attribute| get_inner_path_ident(attribute)) @@ -76,40 +183,59 @@ pub fn polymorphic_macro_derive_inner( let res = schemas .map_err(|error| syn::Error::new(proc_macro2::Span::call_site(), error))? .iter() - .filter_map(|schema| field.ident.to_owned().zip(Some(schema.to_owned()))) + .map(|schema| (field_ident.clone(), schema.to_owned())) .collect::>(); - required_fields.extend(res); + hide_fields.extend(res); Ok::<_, syn::Error>(()) }); - }); + } + // iterate over the schemas and build them with their fields let schemas = schemas_to_create .iter() .map(|schema| { let fields = all_fields .iter() - .flat_map(|(field, value)| { - let mut attributes = value - .iter() - .map(|attribute| quote::quote!(#attribute)) - .collect::>(); + .filter_map(|(field, attributes)| { + let mut final_attributes = attributes.clone(); - // If the field is required for this schema, then add - // #[schema(required = true)] for this field - let required_attribute: syn::Attribute = - parse_quote!(#[schema(required = true)]); + if let Some(field_ident) = field.ident.to_owned() { + // If the field is required for this schema, then add + // #[schema(value_type = type)] for this field + if let Some(required_field_type) = + required_fields.get(&(field_ident.clone(), schema.to_owned())) + { + // This is a required field in the Schema + // Add the value type and remove original value type ( if present ) + let attribute_without_schema_type = attributes + .iter() + .filter(|attribute| !attribute.path().is_ident("schema")) + .map(Clone::clone) + .collect::>(); - // Can be none, because tuple fields have no ident - field.ident.to_owned().and_then(|field_ident| { - required_fields - .contains(&(field_ident, schema.to_owned())) - .then(|| attributes.push(quote::quote!(#required_attribute))) - }); + final_attributes = attribute_without_schema_type; - quote::quote! { - #(#attributes)* - #field, + let value_type_attribute: syn::Attribute = + parse_quote!(#[schema(value_type = #required_field_type)]); + final_attributes.push(value_type_attribute); + } + } + + // If the field is to be not shown then + let is_hidden_field = field + .ident + .clone() + .map(|field_ident| hide_fields.contains(&(field_ident, schema.to_owned()))) + .unwrap_or(false); + + if is_hidden_field { + None + } else { + Some(quote::quote! { + #(#final_attributes)* + #field, + }) } }) .collect::>(); diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index 135ca63810..7858029961 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -11,7 +11,7 @@ "license": { "name": "Apache-2.0" }, - "version": "0.2.0" + "version": "0.1.0" }, "servers": [ { @@ -26,7 +26,7 @@ "Payment Methods" ], "summary": "List payment methods for a Merchant", - "description": "List payment methods for a Merchant\n\nTo filter and list the applicable payment methods for a particular Merchant ID", + "description": "List payment methods for a Merchant\n\nLists the applicable payment methods for a particular Merchant ID.\nUse the client secret and publishable key authorization to list all relevant payment methods of the merchant for the payment corresponding to the client secret.", "operationId": "List all Payment Methods for a Merchant", "parameters": [ { @@ -75,7 +75,7 @@ { "name": "maximum_amount", "in": "query", - "description": "The maximum amount amount accepted for processing by the particular payment method.", + "description": "The maximum amount accepted for processing by the particular payment method.", "required": true, "schema": { "type": "integer", @@ -129,6 +129,481 @@ ] } }, + "/account/{account_id}/business_profile": { + "get": { + "tags": [ + "Business Profile" + ], + "summary": "Business Profile - List", + "description": "Business Profile - List\n\nLists all the *business profiles* under a merchant", + "operationId": "List Business Profiles", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "Merchant Identifier", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Business profiles Retrieved", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BusinessProfileResponse" + } + } + } + } + } + }, + "security": [ + { + "api_key": [] + } + ] + }, + "post": { + "tags": [ + "Business Profile" + ], + "summary": "Business Profile - Create", + "description": "Business Profile - Create\n\nCreates a new *business profile* for a merchant", + "operationId": "Create A Business Profile", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BusinessProfileCreate" + }, + "examples": { + "Create a business profile with minimal fields": { + "value": {} + }, + "Create a business profile with profile name": { + "value": { + "profile_name": "shoe_business" + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Business Account Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BusinessProfileResponse" + } + } + } + }, + "400": { + "description": "Invalid data" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, + "/account/{account_id}/business_profile/{profile_id}": { + "get": { + "tags": [ + "Business Profile" + ], + "summary": "Business Profile - Retrieve", + "description": "Business Profile - Retrieve\n\nRetrieve existing *business profile*", + "operationId": "Retrieve a Business Profile", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "profile_id", + "in": "path", + "description": "The unique identifier for the business profile", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Business Profile Updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BusinessProfileResponse" + } + } + } + }, + "400": { + "description": "Invalid data" + } + }, + "security": [ + { + "api_key": [] + } + ] + }, + "post": { + "tags": [ + "Business Profile" + ], + "summary": "Business Profile - Update", + "description": "Business Profile - Update\n\nUpdate the *business profile*", + "operationId": "Update a Business Profile", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "profile_id", + "in": "path", + "description": "The unique identifier for the business profile", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BusinessProfileCreate" + }, + "examples": { + "Update business profile with profile name fields": { + "value": { + "profile_name": "shoe_business" + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Business Profile Updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BusinessProfileResponse" + } + } + } + }, + "400": { + "description": "Invalid data" + } + }, + "security": [ + { + "api_key": [] + } + ] + }, + "delete": { + "tags": [ + "Business Profile" + ], + "summary": "Business Profile - Delete", + "description": "Business Profile - Delete\n\nDelete the *business profile*", + "operationId": "Delete the Business Profile", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "profile_id", + "in": "path", + "description": "The unique identifier for the business profile", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Business profiles Deleted", + "content": { + "text/plain": { + "schema": { + "type": "boolean" + } + } + } + }, + "400": { + "description": "Invalid data" + } + }, + "security": [ + { + "api_key": [] + } + ] + } + }, + "/accounts": { + "post": { + "tags": [ + "Merchant Account" + ], + "summary": "Merchant Account - Create", + "description": "Merchant Account - Create\n\nCreate a new account for a *merchant* and the *merchant* could be a seller or retailer or client who likes to receive and send payments.", + "operationId": "Create a Merchant Account", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MerchantAccountCreate" + }, + "examples": { + "Create a merchant account with minimal fields": { + "value": { + "merchant_id": "merchant_abc" + } + }, + "Create a merchant account with return url": { + "value": { + "merchant_id": "merchant_abc", + "return_url": "https://example.com" + } + }, + "Create a merchant account with webhook url": { + "value": { + "merchant_id": "merchant_abc", + "webhook_details": { + "webhook_url": "https://webhook.site/a5c54f75-1f7e-4545-b781-af525b7e37a0" + } + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Merchant Account Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MerchantAccountResponse" + } + } + } + }, + "400": { + "description": "Invalid data" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, + "/accounts/{account_id}": { + "get": { + "tags": [ + "Merchant Account" + ], + "summary": "Merchant Account - Retrieve", + "description": "Merchant Account - Retrieve\n\nRetrieve a *merchant* account details.", + "operationId": "Retrieve a Merchant Account", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Merchant Account Retrieved", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MerchantAccountResponse" + } + } + } + }, + "404": { + "description": "Merchant account not found" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + }, + "post": { + "tags": [ + "Merchant Account" + ], + "summary": "Merchant Account - Update", + "description": "Merchant Account - Update\n\nUpdates details of an existing merchant account. Helpful in updating merchant details such as email, contact details, or other configuration details like webhook, routing algorithm etc", + "operationId": "Update a Merchant Account", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MerchantAccountUpdate" + }, + "examples": { + "Update merchant name": { + "value": { + "merchant_id": "merchant_abc", + "merchant_name": "merchant_name" + } + }, + "Update return url": { + "value": { + "merchant_id": "merchant_abc", + "return_url": "https://example.com" + } + }, + "Update webhook url": { + "value": { + "merchant_id": "merchant_abc", + "webhook_details": { + "webhook_url": "https://webhook.site/a5c54f75-1f7e-4545-b781-af525b7e37a0" + } + } + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Merchant Account Updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MerchantAccountResponse" + } + } + } + }, + "404": { + "description": "Merchant account not found" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + }, + "delete": { + "tags": [ + "Merchant Account" + ], + "summary": "Merchant Account - Delete", + "description": "Merchant Account - Delete\n\nDelete a *merchant* account", + "operationId": "Delete a Merchant Account", + "parameters": [ + { + "name": "account_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Merchant Account Deleted", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MerchantAccountDeleteResponse" + } + } + } + }, + "404": { + "description": "Merchant account not found" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, "/accounts/{account_id}/connectors": { "get": { "tags": [ @@ -180,13 +655,50 @@ "Merchant Connector Account" ], "summary": "Merchant Connector - Create", - "description": "Merchant Connector - Create\n\nCreate a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc.\"", + "description": "Merchant Connector - Create\n\nCreates a new Merchant Connector for the merchant account. The connector could be a payment processor/facilitator/acquirer or a provider of specialized services like Fraud/Accounting etc.", "operationId": "Create a Merchant Connector", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MerchantConnectorCreate" + }, + "examples": { + "Create a merchant account with custom connector label": { + "value": { + "connector_account_details": { + "api_key": "{{adyen-api-key}}", + "auth_type": "BodyKey", + "key1": "{{adyen_merchant_account}}" + }, + "connector_label": "EU_adyen", + "connector_name": "adyen", + "connector_type": "fiz_operations" + } + }, + "Create a merchant connector account under a specific business profile": { + "value": { + "connector_account_details": { + "api_key": "{{adyen-api-key}}", + "auth_type": "BodyKey", + "key1": "{{adyen_merchant_account}}" + }, + "connector_name": "adyen", + "connector_type": "fiz_operations", + "profile_id": "{{profile_id}}" + } + }, + "Create a merchant connector account with minimal fields": { + "value": { + "connector_account_details": { + "api_key": "{{adyen-api-key}}", + "auth_type": "BodyKey", + "key1": "{{adyen_merchant_account}}" + }, + "connector_name": "adyen", + "connector_type": "fiz_operations" + } + } } } }, @@ -220,7 +732,7 @@ "Merchant Connector Account" ], "summary": "Merchant Connector - Retrieve", - "description": "Merchant Connector - Retrieve\n\nRetrieve Merchant Connector Details", + "description": "Merchant Connector - Retrieve\n\nRetrieves details of a Connector account", "operationId": "Retrieve a Merchant Connector", "parameters": [ { @@ -272,7 +784,7 @@ "Merchant Connector Account" ], "summary": "Merchant Connector - Update", - "description": "Merchant Connector - Update\n\nTo update an existing Merchant Connector. Helpful in enabling / disabling different payment methods and other settings for the connector etc.", + "description": "Merchant Connector - Update\n\nTo update an existing Merchant Connector account. Helpful in enabling/disabling different payment methods and other settings for the connector", "operationId": "Update a Merchant Connector", "parameters": [ { @@ -300,6 +812,25 @@ "application/json": { "schema": { "$ref": "#/components/schemas/MerchantConnectorUpdate" + }, + "examples": { + "Enable card payment method": { + "value": { + "connector_type": "fiz_operations", + "payment_methods_enabled": [ + { + "payment_method": "card" + } + ] + } + }, + "Update webhook secret": { + "value": { + "connector_webhook_details": { + "merchant_secret": "{{webhook_secret}}" + } + } + } } } }, @@ -382,6 +913,215 @@ ] } }, + "/api_keys/{merchant_id)": { + "post": { + "tags": [ + "API Key" + ], + "summary": "API Key - Create", + "description": "API Key - Create\n\nCreate a new API Key for accessing our APIs from your servers. The plaintext API Key will be\ndisplayed only once on creation, so ensure you store it securely.", + "operationId": "Create an API Key", + "parameters": [ + { + "name": "merchant_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateApiKeyRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "API Key created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateApiKeyResponse" + } + } + } + }, + "400": { + "description": "Invalid data" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, + "/api_keys/{merchant_id)/{key_id}": { + "delete": { + "tags": [ + "API Key" + ], + "summary": "API Key - Revoke", + "description": "API Key - Revoke\n\nRevoke the specified API Key. Once revoked, the API Key can no longer be used for\nauthenticating with our APIs.", + "operationId": "Revoke an API Key", + "parameters": [ + { + "name": "merchant_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "key_id", + "in": "path", + "description": "The unique identifier for the API Key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "API Key revoked", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RevokeApiKeyResponse" + } + } + } + }, + "404": { + "description": "API Key not found" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, + "/api_keys/{merchant_id}/{key_id}": { + "get": { + "tags": [ + "API Key" + ], + "summary": "API Key - Retrieve", + "description": "API Key - Retrieve\n\nRetrieve information about the specified API Key.", + "operationId": "Retrieve an API Key", + "parameters": [ + { + "name": "merchant_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "key_id", + "in": "path", + "description": "The unique identifier for the API Key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "API Key retrieved", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RetrieveApiKeyResponse" + } + } + } + }, + "404": { + "description": "API Key not found" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + }, + "post": { + "tags": [ + "API Key" + ], + "summary": "API Key - Update", + "description": "API Key - Update\n\nUpdate information for the specified API Key.", + "operationId": "Update an API Key", + "parameters": [ + { + "name": "merchant_id", + "in": "path", + "description": "The unique identifier for the merchant account", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "key_id", + "in": "path", + "description": "The unique identifier for the API Key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateApiKeyRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "API Key updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RetrieveApiKeyResponse" + } + } + } + }, + "404": { + "description": "API Key not found" + } + }, + "security": [ + { + "admin_api_key": [] + } + ] + } + }, "/blocklist": { "get": { "tags": [ @@ -498,14 +1238,22 @@ "tags": [ "Customers" ], - "summary": "Create Customer", - "description": "Create Customer\n\nCreate a customer object and store the customer details to be reused for future payments. Incase the customer already exists in the system, this API will respond with the customer details.", + "summary": "Customers - Create", + "description": "Customers - Create\n\nCreates a customer object and stores the customer details to be reused for future payments.\nIncase the customer already exists in the system, this API will respond with the customer details.", "operationId": "Create a Customer", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CustomerRequest" + }, + "examples": { + "Update name and email of a customer": { + "value": { + "email": "guest@example.com", + "name": "John Doe" + } + } } } }, @@ -538,8 +1286,8 @@ "tags": [ "Customers List" ], - "summary": "List customers for a merchant", - "description": "List customers for a merchant\n\nTo filter and list the customers for a particular merchant id", + "summary": "Customers - List", + "description": "Customers - List\n\nLists all the customers for a particular merchant id.", "operationId": "List all Customers for a Merchant", "responses": { "200": { @@ -571,14 +1319,23 @@ "tags": [ "Payment Methods" ], - "summary": "List payment methods for a Customer", - "description": "List payment methods for a Customer\n\nTo filter and list the applicable payment methods for a particular Customer ID", + "summary": "List payment methods for a Payment", + "description": "List payment methods for a Payment\n\nLists all the applicable payment methods for a particular payment tied to the `client_secret`.", "operationId": "List all Payment Methods for a Customer", "parameters": [ { "name": "client-secret", "in": "path", - "description": "A secret known only to your application and the authorization server", + "description": "A secret known only to your client and the authorization server. Used for client side authentication", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "customer_id", + "in": "path", + "description": "The unique identifier for the customer account", "required": true, "schema": { "type": "string" @@ -621,7 +1378,7 @@ { "name": "maximum_amount", "in": "query", - "description": "The maximum amount amount accepted for processing by the particular payment method.", + "description": "The maximum amount accepted for processing by the particular payment method.", "required": true, "schema": { "type": "integer", @@ -677,8 +1434,8 @@ "tags": [ "Customers" ], - "summary": "Retrieve Customer", - "description": "Retrieve Customer\n\nRetrieve a customer's details.", + "summary": "Customers - Retrieve", + "description": "Customers - Retrieve\n\nRetrieves a customer's details.", "operationId": "Retrieve a Customer", "parameters": [ { @@ -719,8 +1476,8 @@ "tags": [ "Customers" ], - "summary": "Update Customer", - "description": "Update Customer\n\nUpdates the customer's details in a customer object.", + "summary": "Customers - Update", + "description": "Customers - Update\n\nUpdates the customer's details in a customer object.", "operationId": "Update a Customer", "parameters": [ { @@ -738,6 +1495,14 @@ "application/json": { "schema": { "$ref": "#/components/schemas/CustomerRequest" + }, + "examples": { + "Update name and email of a customer": { + "value": { + "email": "guest@example.com", + "name": "John Doe" + } + } } } }, @@ -768,8 +1533,8 @@ "tags": [ "Customers" ], - "summary": "Delete Customer", - "description": "Delete Customer\n\nDelete a customer record.", + "summary": "Customers - Delete", + "description": "Customers - Delete\n\nDelete a customer record.", "operationId": "Delete a Customer", "parameters": [ { @@ -810,9 +1575,18 @@ "Payment Methods" ], "summary": "List payment methods for a Customer", - "description": "List payment methods for a Customer\n\nTo filter and list the applicable payment methods for a particular Customer ID", + "description": "List payment methods for a Customer\n\nLists all the applicable payment methods for a particular Customer ID.", "operationId": "List all Payment Methods for a Customer", "parameters": [ + { + "name": "customer_id", + "in": "path", + "description": "The unique identifier for the customer account", + "required": true, + "schema": { + "type": "string" + } + }, { "name": "accepted_country", "in": "query", @@ -850,7 +1624,7 @@ { "name": "maximum_amount", "in": "query", - "description": "The maximum amount amount accepted for processing by the particular payment method.", + "description": "The maximum amount accepted for processing by the particular payment method.", "required": true, "schema": { "type": "integer", @@ -907,7 +1681,7 @@ "Disputes" ], "summary": "Disputes - List Disputes", - "description": "Disputes - List Disputes", + "description": "Disputes - List Disputes\nLists all the Disputes for a merchant", "operationId": "List Disputes", "parameters": [ { @@ -1056,7 +1830,7 @@ "Disputes" ], "summary": "Disputes - Retrieve Dispute", - "description": "Disputes - Retrieve Dispute", + "description": "Disputes - Retrieve Dispute\nRetrieves a dispute", "operationId": "Retrieve a Dispute", "parameters": [ { @@ -1097,7 +1871,7 @@ "Gsm" ], "summary": "Gsm - Create", - "description": "Gsm - Create\n\nTo create a Gsm Rule", + "description": "Gsm - Create\n\nCreates a GSM (Global Status Mapping) Rule. A GSM rule is used to map a connector's error message/error code combination during a particular payments flow/sub-flow to Hyperswitch's unified status/error code/error message combination. It is also used to decide the next action in the flow - retry/requeue/do_default", "operationId": "Create Gsm Rule", "requestBody": { "content": { @@ -1137,7 +1911,7 @@ "Gsm" ], "summary": "Gsm - Delete", - "description": "Gsm - Delete\n\nTo delete a Gsm Rule", + "description": "Gsm - Delete\n\nDeletes a Gsm Rule", "operationId": "Delete Gsm Rule", "requestBody": { "content": { @@ -1177,7 +1951,7 @@ "Gsm" ], "summary": "Gsm - Get", - "description": "Gsm - Get\n\nTo get a Gsm Rule", + "description": "Gsm - Get\n\nRetrieves a Gsm Rule", "operationId": "Retrieve Gsm Rule", "requestBody": { "content": { @@ -1217,7 +1991,7 @@ "Gsm" ], "summary": "Gsm - Update", - "description": "Gsm - Update\n\nTo update a Gsm Rule", + "description": "Gsm - Update\n\nUpdates a Gsm Rule", "operationId": "Update Gsm Rule", "requestBody": { "content": { @@ -1257,13 +2031,13 @@ "Mandates" ], "summary": "Mandates - Revoke Mandate", - "description": "Mandates - Revoke Mandate\n\nRevoke a mandate", + "description": "Mandates - Revoke Mandate\n\nRevokes a mandate created using the Payments/Create API", "operationId": "Revoke a Mandate", "parameters": [ { "name": "mandate_id", "in": "path", - "description": "The identifier for mandate", + "description": "The identifier for a mandate", "required": true, "schema": { "type": "string" @@ -1298,7 +2072,7 @@ "Mandates" ], "summary": "Mandates - Retrieve Mandate", - "description": "Mandates - Retrieve Mandate\n\nRetrieve a mandate", + "description": "Mandates - Retrieve Mandate\n\nRetrieves a mandate created using the Payments/Create API", "operationId": "Retrieve a Mandate", "parameters": [ { @@ -1393,13 +2167,29 @@ "Payment Methods" ], "summary": "PaymentMethods - Create", - "description": "PaymentMethods - Create\n\nTo create a payment method against a customer object. In case of cards, this API could be used only by PCI compliant merchants", + "description": "PaymentMethods - Create\n\nCreates and stores a payment method against a customer.\nIn case of cards, this API should be used only by PCI compliant merchants.", "operationId": "Create a Payment Method", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentMethodCreate" + }, + "examples": { + "Save a card": { + "value": { + "card": { + "card_exp_month": "11", + "card_exp_year": "25", + "card_holder_name": "John Doe", + "card_number": "4242424242424242" + }, + "customer_id": "{{customer_id}}", + "payment_method": "card", + "payment_method_issuer": "Visa", + "payment_method_type": "credit" + } + } } } }, @@ -1433,7 +2223,7 @@ "Payment Methods" ], "summary": "Payment Method - Retrieve", - "description": "Payment Method - Retrieve\n\nTo retrieve a payment method", + "description": "Payment Method - Retrieve\n\nRetrieves a payment method of a customer.", "operationId": "Retrieve a Payment method", "parameters": [ { @@ -1472,7 +2262,7 @@ "Payment Methods" ], "summary": "Payment Method - Update", - "description": "Payment Method - Update\n\nTo update an existing payment method attached to a customer object. This API is useful for use cases such as updating the card number for expired cards to prevent discontinuity in recurring payments", + "description": "Payment Method - Update\n\nUpdate an existing payment method of a customer.\nThis API is useful for use cases such as updating the card number for expired cards to prevent discontinuity in recurring payments.", "operationId": "Update a Payment method", "parameters": [ { @@ -1521,7 +2311,7 @@ "Payment Methods" ], "summary": "Payment Method - Delete", - "description": "Payment Method - Delete\n\nDelete payment method", + "description": "Payment Method - Delete\n\nDeletes a payment method of a customer.", "operationId": "Delete a Payment method", "parameters": [ { @@ -1562,13 +2352,152 @@ "Payments" ], "summary": "Payments - Create", - "description": "Payments - Create\n\nTo process a payment you will have to create a payment, attach a payment method and confirm. Depending on the user journey you wish to achieve, you may opt to all the steps in a single request or in a sequence of API request using following APIs: (i) Payments - Update, (ii) Payments - Confirm, and (iii) Payments - Capture", + "description": "Payments - Create\n\n**Creates a payment object when amount and currency are passed.** This API is also used to create a mandate by passing the `mandate_object`.\n\nTo completely process a payment you will have to create a payment, attach a payment method, confirm and capture funds.\n\nDepending on the user journey you wish to achieve, you may opt to complete all the steps in a single request by attaching a payment method, setting `confirm=true` and `capture_method = automatic` in the *Payments/Create API* request or you could use the following sequence of API requests to achieve the same:\n\n1. Payments - Create\n\n2. Payments - Update\n\n3. Payments - Confirm\n\n4. Payments - Capture.\n\nUse the client secret returned in this API along with your publishable key to make subsequent API calls from your client", "operationId": "Create a Payment", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentsCreateRequest" + }, + "examples": { + "Create a 3DS payment": { + "value": { + "amount": 6540, + "authentication_type": "three_ds", + "currency": "USD" + } + }, + "Create a manual capture payment": { + "value": { + "amount": 6540, + "billing": { + "address": { + "city": "San Fransico", + "country": "US", + "first_name": "joseph", + "last_name": "Doe", + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "state": "California", + "zip": "94122" + }, + "phone": { + "country_code": "+91", + "number": "8056594427" + } + }, + "currency": "USD", + "customer": { + "id": "cus_abcdefgh" + } + } + }, + "Create a payment and save the card": { + "value": { + "amount": 6540, + "authentication_type": "no_three_ds", + "confirm": true, + "currency": "USD", + "customer_id": "StripeCustomer123", + "payment_method": "card", + "payment_method_data": { + "card": { + "card_cvc": "123", + "card_exp_month": "10", + "card_exp_year": "25", + "card_holder_name": "joseph Doe", + "card_number": "4242424242424242" + } + }, + "setup_future_usage": "off_session" + } + }, + "Create a payment using an already saved card's token": { + "value": { + "amount": 6540, + "card_cvc": "123", + "client_secret": "{{client_secret}}", + "confirm": true, + "currency": "USD", + "payment_method": "card", + "payment_token": "{{payment_token}}" + } + }, + "Create a payment with customer details and metadata": { + "value": { + "amount": 6540, + "currency": "USD", + "customer": { + "email": "john@example.com", + "id": "cus_abcdefgh", + "name": "John Dough", + "phone": "9999999999" + }, + "description": "Its my first payment request", + "metadata": { + "udf1": "some-value", + "udf2": "some-value" + }, + "payment_id": "abcdefghijklmnopqrstuvwxyz", + "statement_descriptor_name": "joseph", + "statement_descriptor_suffix": "JS" + } + }, + "Create a payment with minimal fields": { + "value": { + "amount": 6540, + "currency": "USD" + } + }, + "Create a recurring payment with mandate_id": { + "value": { + "amount": 6540, + "authentication_type": "no_three_ds", + "confirm": true, + "currency": "USD", + "customer_id": "StripeCustomer", + "mandate_id": "{{mandate_id}}", + "off_session": true + } + }, + "Create a setup mandate payment": { + "value": { + "amount": 6540, + "authentication_type": "no_three_ds", + "confirm": true, + "currency": "USD", + "customer_id": "StripeCustomer123", + "mandate_data": { + "customer_acceptance": { + "acceptance_type": "offline", + "accepted_at": "1963-05-03T04:07:52.723Z", + "online": { + "ip_address": "127.0.0.1", + "user_agent": "amet irure esse" + } + }, + "mandate_type": { + "single_use": { + "amount": 6540, + "currency": "USD" + } + } + }, + "payment_method": "card", + "payment_method_data": { + "card": { + "card_cvc": "123", + "card_exp_month": "10", + "card_exp_year": "25", + "card_holder_name": "joseph Doe", + "card_number": "4242424242424242" + } + }, + "setup_future_usage": "off_session" + } + } } } }, @@ -1602,7 +2531,7 @@ "Payments" ], "summary": "Payments - List", - "description": "Payments - List\n\nTo list the payments", + "description": "Payments - List\n\nTo list the *payments*", "operationId": "List all Payments", "parameters": [ { @@ -1695,7 +2624,17 @@ ], "responses": { "200": { - "description": "Received payment list" + "description": "Successfully retrieved a payment list", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PaymentListResponse" + } + } + } + } }, "404": { "description": "No payments found" @@ -1714,7 +2653,7 @@ "Payments" ], "summary": "Payments - Session token", - "description": "Payments - Session token\n\nTo create the session object or to get session token for wallets", + "description": "Payments - Session token\n\nCreates a session object or a session token for wallets like Apple Pay, Google Pay, etc. These tokens are used by Hyperswitch's SDK to initiate these wallets' SDK.", "operationId": "Create Session tokens for a Payment", "requestBody": { "content": { @@ -1754,7 +2693,7 @@ "Payments" ], "summary": "Payments - Retrieve", - "description": "Payments - Retrieve\n\nTo retrieve the properties of a Payment. This may be used to get the status of a previously initiated payment or next action for an ongoing payment", + "description": "Payments - Retrieve\n\nRetrieves a Payment. This API can also be used to get the status of a previously initiated payment or next action for an ongoing payment", "operationId": "Retrieve a Payment", "parameters": [ { @@ -1806,7 +2745,7 @@ "Payments" ], "summary": "Payments - Update", - "description": "Payments - Update\n\nTo update the properties of a PaymentIntent object. This may include attaching a payment method, or attaching customer object or metadata fields after the Payment is created", + "description": "Payments - Update\n\nTo update the properties of a *PaymentIntent* object. This may include attaching a payment method, or attaching customer object or metadata fields after the Payment is created", "operationId": "Update a Payment", "parameters": [ { @@ -1823,7 +2762,35 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PaymentsRequest" + "$ref": "#/components/schemas/PaymentsUpdateRequest" + }, + "examples": { + "Update the payment amount": { + "value": { + "amount": 7654 + } + }, + "Update the shipping address": { + "value": { + "shipping": { + "address": { + "city": "San Fransico", + "country": "US", + "first_name": "joseph", + "last_name": "Doe", + "line1": "1467", + "line2": "Harrison Street", + "line3": "Harrison Street", + "state": "California", + "zip": "94122" + }, + "phone": { + "country_code": "+91", + "number": "8056594427" + } + } + } + } } } }, @@ -1860,7 +2827,7 @@ "Payments" ], "summary": "Payments - Cancel", - "description": "Payments - Cancel\n\nA Payment could can be cancelled when it is in one of these statuses: requires_payment_method, requires_capture, requires_confirmation, requires_customer_action", + "description": "Payments - Cancel\n\nA Payment could can be cancelled when it is in one of these statuses: `requires_payment_method`, `requires_capture`, `requires_confirmation`, `requires_customer_action`.", "operationId": "Cancel a Payment", "parameters": [ { @@ -1878,6 +2845,16 @@ "application/json": { "schema": { "$ref": "#/components/schemas/PaymentsCancelRequest" + }, + "examples": { + "Cancel the payment with cancellation reason": { + "value": { + "cancellation_reason": "requested_by_customer" + } + }, + "Cancel the payment with minimal fields": { + "value": {} + } } } }, @@ -1922,6 +2899,16 @@ "application/json": { "schema": { "$ref": "#/components/schemas/PaymentsCaptureRequest" + }, + "examples": { + "Capture partial amount": { + "value": { + "amount_to_capture": 654 + } + }, + "Capture the full amount": { + "value": {} + } } } }, @@ -1955,7 +2942,7 @@ "Payments" ], "summary": "Payments - Confirm", - "description": "Payments - Confirm\n\nThis API is to confirm the payment request and forward payment to the payment processor. This API provides more granular control upon when the API is forwarded to the payment processor. Alternatively you can confirm the payment within the Payments Create API", + "description": "Payments - Confirm\n\n**Use this API to confirm the payment and forward the payment to the payment processor.**\n\nAlternatively you can confirm the payment within the *Payments/Create* API by setting `confirm=true`. After confirmation, the payment could either:\n\n1. fail with `failed` status or\n\n2. transition to a `requires_customer_action` status with a `next_action` block or\n\n3. succeed with either `succeeded` in case of automatic capture or `requires_capture` in case of manual capture", "operationId": "Confirm a Payment", "parameters": [ { @@ -1972,7 +2959,24 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PaymentsRequest" + "$ref": "#/components/schemas/PaymentsConfirmRequest" + }, + "examples": { + "Confirm a payment with payment method data": { + "value": { + "payment_method": "card", + "payment_method_data": { + "card": { + "card_cvc": "123", + "card_exp_month": "10", + "card_exp_year": "25", + "card_holder_name": "joseph Doe", + "card_number": "4242424242424242" + } + }, + "payment_method_type": "credit" + } + } } } }, @@ -2003,6 +3007,57 @@ ] } }, + "/payments/{payment_id}/incremental_authorization": { + "post": { + "tags": [ + "Payments" + ], + "summary": "Payments - Incremental Authorization", + "description": "Payments - Incremental Authorization\n\nAuthorized amount for a payment can be incremented if it is in status: requires_capture", + "operationId": "Increment authorized amount for a Payment", + "parameters": [ + { + "name": "payment_id", + "in": "path", + "description": "The identifier for payment", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaymentsIncrementalAuthorizationRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Payment authorized amount incremented", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PaymentsResponse" + } + } + } + }, + "400": { + "description": "Missing mandatory fields" + } + }, + "security": [ + { + "api_key": [] + } + ] + } + }, "/payouts/create": { "post": { "tags": [ @@ -2241,13 +3296,36 @@ "Refunds" ], "summary": "Refunds - Create", - "description": "Refunds - Create\n\nTo create a refund against an already processed payment", + "description": "Refunds - Create\n\nCreates a refund against an already processed payment. In case of some processors, you can even opt to refund only a partial amount multiple times until the original charge amount has been refunded", "operationId": "Create a Refund", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RefundRequest" + }, + "examples": { + "Create an instant refund to refund partial amount": { + "value": { + "amount": 654, + "payment_id": "{{payment_id}}", + "refund_type": "instant" + } + }, + "Create an instant refund to refund the whole amount": { + "value": { + "payment_id": "{{payment_id}}", + "refund_type": "instant" + } + }, + "Create an instant refund with reason": { + "value": { + "amount": 6540, + "payment_id": "{{payment_id}}", + "reason": "Customer returned product", + "refund_type": "instant" + } + } } } }, @@ -2281,7 +3359,7 @@ "Refunds" ], "summary": "Refunds - List", - "description": "Refunds - List\n\nTo list the refunds associated with a payment_id or with the merchant, if payment_id is not provided", + "description": "Refunds - List\n\nLists all the refunds associated with the merchant or a payment_id if payment_id is not provided", "operationId": "List all Refunds", "requestBody": { "content": { @@ -2317,8 +3395,8 @@ "tags": [ "Refunds" ], - "summary": "Refunds - Retrieve (GET)", - "description": "Refunds - Retrieve (GET)\n\nTo retrieve the properties of a Refund. This may be used to get the status of a previously initiated payment or next action for an ongoing payment", + "summary": "Refunds - Retrieve", + "description": "Refunds - Retrieve\n\nRetrieves a Refund. This may be used to get the status of a previously initiated refund", "operationId": "Retrieve a Refund", "parameters": [ { @@ -2357,7 +3435,7 @@ "Refunds" ], "summary": "Refunds - Update", - "description": "Refunds - Update\n\nTo update the properties of a Refund object. This may include attaching a reason for the refund or metadata fields", + "description": "Refunds - Update\n\nUpdates the properties of a Refund object. This API can be used to attach a reason for the refund or metadata fields", "operationId": "Update a Refund", "parameters": [ { @@ -2375,6 +3453,13 @@ "application/json": { "schema": { "$ref": "#/components/schemas/RefundUpdateRequest" + }, + "examples": { + "Update refund reason": { + "value": { + "reason": "Paid by mistake" + } + } } } }, @@ -2401,12 +3486,535 @@ } ] } + }, + "/routing": { + "get": { + "tags": [ + "Routing" + ], + "summary": "Routing - List", + "description": "Routing - List\n\nList all routing configs", + "operationId": "List routing configs", + "parameters": [ + { + "name": "limit", + "in": "query", + "description": "The number of records to be returned", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "nullable": true, + "minimum": 0 + } + }, + { + "name": "offset", + "in": "query", + "description": "The record offset from which to start gathering of results", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "nullable": true, + "minimum": 0 + } + }, + { + "name": "profile_id", + "in": "query", + "description": "The unique identifier for a merchant profile", + "required": false, + "schema": { + "type": "string", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "Successfully fetched routing configs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RoutingKind" + } + } + } + }, + "404": { + "description": "Resource missing" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + }, + "post": { + "tags": [ + "Routing" + ], + "summary": "Routing - Create", + "description": "Routing - Create\n\nCreate a routing config", + "operationId": "Create a routing config", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RoutingConfigRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Routing config created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RoutingDictionaryRecord" + } + } + } + }, + "400": { + "description": "Request body is malformed" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Resource missing" + }, + "422": { + "description": "Unprocessable request" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + } + }, + "/routing/active": { + "get": { + "tags": [ + "Routing" + ], + "summary": "Routing - Retrieve Config", + "description": "Routing - Retrieve Config\n\nRetrieve active config", + "operationId": "Retrieve active config", + "parameters": [ + { + "name": "profile_id", + "in": "query", + "description": "The unique identifier for a merchant profile", + "required": false, + "schema": { + "type": "string", + "nullable": true + } + } + ], + "responses": { + "200": { + "description": "Successfully retrieved active config", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LinkedRoutingConfigRetrieveResponse" + } + } + } + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Resource missing" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + } + }, + "/routing/deactivate": { + "post": { + "tags": [ + "Routing" + ], + "summary": "Routing - Deactivate", + "description": "Routing - Deactivate\n\nDeactivates a routing config", + "operationId": "Deactivate a routing config", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RoutingConfigRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successfully deactivated routing config", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RoutingDictionaryRecord" + } + } + } + }, + "400": { + "description": "Malformed request" + }, + "403": { + "description": "Malformed request" + }, + "422": { + "description": "Unprocessable request" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + } + }, + "/routing/default": { + "get": { + "tags": [ + "Routing" + ], + "summary": "Routing - Retrieve Default Config", + "description": "Routing - Retrieve Default Config\n\nRetrieve default fallback config", + "operationId": "Retrieve default fallback config", + "responses": { + "200": { + "description": "Successfully retrieved default config", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + } + } + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + }, + "post": { + "tags": [ + "Routing" + ], + "summary": "Routing - Update Default Config", + "description": "Routing - Update Default Config\n\nUpdate default fallback config", + "operationId": "Update default fallback config", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successfully updated default config", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + } + } + }, + "400": { + "description": "Malformed request" + }, + "422": { + "description": "Unprocessable request" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + } + }, + "/routing/default/profile": { + "get": { + "tags": [ + "Routing" + ], + "summary": "Routing - Retrieve Default For Profile", + "description": "Routing - Retrieve Default For Profile\n\nRetrieve default config for profiles", + "operationId": "Retrieve default configs for all profiles", + "responses": { + "200": { + "description": "Successfully retrieved default config", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProfileDefaultRoutingConfig" + } + } + } + }, + "404": { + "description": "Resource missing" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + } + }, + "/routing/default/profile/{profile_id}": { + "post": { + "tags": [ + "Routing" + ], + "summary": "Routing - Update Default For Profile", + "description": "Routing - Update Default For Profile\n\nUpdate default config for profiles", + "operationId": "Update default configs for all profiles", + "parameters": [ + { + "name": "profile_id", + "in": "path", + "description": "The unique identifier for a profile", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successfully updated default config for profile", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProfileDefaultRoutingConfig" + } + } + } + }, + "400": { + "description": "Malformed request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Resource missing" + }, + "422": { + "description": "Unprocessable request" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + } + }, + "/routing/{algorithm_id}": { + "get": { + "tags": [ + "Routing" + ], + "summary": "Routing - Retrieve", + "description": "Routing - Retrieve\n\nRetrieve a routing algorithm", + "operationId": "Retrieve a routing config", + "parameters": [ + { + "name": "algorithm_id", + "in": "path", + "description": "The unique identifier for a config", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Successfully fetched routing config", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MerchantRoutingAlgorithm" + } + } + } + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Resource missing" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + } + }, + "/routing/{algorithm_id}/activate": { + "post": { + "tags": [ + "Routing" + ], + "summary": "Routing - Activate config", + "description": "Routing - Activate config\n\nActivate a routing config", + "operationId": "Activate a routing config", + "parameters": [ + { + "name": "algorithm_id", + "in": "path", + "description": "The unique identifier for a config", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Routing config activated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RoutingDictionaryRecord" + } + } + } + }, + "400": { + "description": "Bad request" + }, + "404": { + "description": "Resource missing" + }, + "500": { + "description": "Internal server error" + } + }, + "security": [ + { + "api_key": [] + }, + { + "jwt_key": [] + } + ] + } } }, "components": { "schemas": { "AcceptanceType": { "type": "string", + "description": "This is used to indicate if the mandate was accepted online or offline", "enum": [ "online", "offline" @@ -2471,6 +4079,7 @@ } } ], + "description": "Object to filter the customer countries for which the payment method is displayed", "discriminator": { "propertyName": "type" } @@ -2639,6 +4248,7 @@ }, "AddressDetails": { "type": "object", + "description": "Address details", "properties": { "city": { "type": "string", @@ -4253,6 +5863,70 @@ } } }, + "BrowserInformation": { + "type": "object", + "description": "Browser information to be used for 3DS 2.0", + "properties": { + "color_depth": { + "type": "integer", + "format": "int32", + "description": "Color depth supported by the browser", + "nullable": true, + "minimum": 0 + }, + "java_enabled": { + "type": "boolean", + "description": "Whether java is enabled in the browser", + "nullable": true + }, + "java_script_enabled": { + "type": "boolean", + "description": "Whether javascript is enabled in the browser", + "nullable": true + }, + "language": { + "type": "string", + "description": "Language supported", + "nullable": true + }, + "screen_height": { + "type": "integer", + "format": "int32", + "description": "The screen height in pixels", + "nullable": true, + "minimum": 0 + }, + "screen_width": { + "type": "integer", + "format": "int32", + "description": "The screen width in pixels", + "nullable": true, + "minimum": 0 + }, + "time_zone": { + "type": "integer", + "format": "int32", + "description": "Time zone of the client", + "nullable": true + }, + "ip_address": { + "type": "string", + "description": "Ip address of the client", + "nullable": true + }, + "accept_header": { + "type": "string", + "description": "List of headers that are accepted", + "example": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "nullable": true + }, + "user_agent": { + "type": "string", + "description": "User-agent of the browser", + "nullable": true + } + } + }, "BusinessPaymentLinkConfig": { "allOf": [ { @@ -4269,6 +5943,216 @@ } ] }, + "BusinessProfileCreate": { + "type": "object", + "properties": { + "profile_name": { + "type": "string", + "description": "The name of business profile", + "nullable": true, + "maxLength": 64 + }, + "return_url": { + "type": "string", + "description": "The URL to redirect after the completion of the operation", + "example": "https://www.example.com/success", + "nullable": true, + "maxLength": 255 + }, + "enable_payment_response_hash": { + "type": "boolean", + "description": "A boolean value to indicate if payment response hash needs to be enabled", + "default": true, + "example": true, + "nullable": true + }, + "payment_response_hash_key": { + "type": "string", + "description": "Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used.", + "nullable": true + }, + "redirect_to_merchant_with_http_post": { + "type": "boolean", + "description": "A boolean value to indicate if redirect to merchant with http post needs to be enabled", + "default": false, + "example": true, + "nullable": true + }, + "webhook_details": { + "allOf": [ + { + "$ref": "#/components/schemas/WebhookDetails" + } + ], + "nullable": true + }, + "metadata": { + "type": "object", + "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", + "nullable": true + }, + "routing_algorithm": { + "type": "object", + "description": "The routing algorithm to be used for routing payments to desired connectors", + "nullable": true + }, + "intent_fulfillment_time": { + "type": "integer", + "format": "int32", + "description": "Will be used to expire client secret after certain amount of time to be supplied in seconds\n(900) for 15 mins", + "example": 900, + "nullable": true, + "minimum": 0 + }, + "frm_routing_algorithm": { + "type": "object", + "description": "The frm routing algorithm to be used for routing payments to desired FRM's", + "nullable": true + }, + "payout_routing_algorithm": { + "allOf": [ + { + "$ref": "#/components/schemas/RoutingAlgorithm" + } + ], + "nullable": true + }, + "applepay_verified_domains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Verified applepay domains for a particular profile", + "nullable": true + }, + "session_expiry": { + "type": "integer", + "format": "int32", + "description": "Client Secret Default expiry for all payments created under this business profile", + "example": 900, + "nullable": true, + "minimum": 0 + }, + "payment_link_config": { + "allOf": [ + { + "$ref": "#/components/schemas/BusinessPaymentLinkConfig" + } + ], + "nullable": true + } + } + }, + "BusinessProfileResponse": { + "type": "object", + "required": [ + "merchant_id", + "profile_id", + "profile_name", + "enable_payment_response_hash", + "redirect_to_merchant_with_http_post" + ], + "properties": { + "merchant_id": { + "type": "string", + "description": "The identifier for Merchant Account", + "example": "y3oqhf46pyzuxjbcn2giaqnb44", + "maxLength": 64 + }, + "profile_id": { + "type": "string", + "description": "The default business profile that must be used for creating merchant accounts and payments", + "example": "pro_abcdefghijklmnopqrstuvwxyz", + "maxLength": 64 + }, + "profile_name": { + "type": "string", + "description": "Name of the business profile", + "maxLength": 64 + }, + "return_url": { + "type": "string", + "description": "The URL to redirect after the completion of the operation", + "example": "https://www.example.com/success", + "nullable": true, + "maxLength": 255 + }, + "enable_payment_response_hash": { + "type": "boolean", + "description": "A boolean value to indicate if payment response hash needs to be enabled", + "default": true, + "example": true + }, + "payment_response_hash_key": { + "type": "string", + "description": "Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used.", + "nullable": true + }, + "redirect_to_merchant_with_http_post": { + "type": "boolean", + "description": "A boolean value to indicate if redirect to merchant with http post needs to be enabled", + "default": false, + "example": true + }, + "webhook_details": { + "allOf": [ + { + "$ref": "#/components/schemas/WebhookDetails" + } + ], + "nullable": true + }, + "metadata": { + "type": "object", + "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", + "nullable": true + }, + "routing_algorithm": { + "type": "object", + "description": "The routing algorithm to be used for routing payments to desired connectors", + "nullable": true + }, + "intent_fulfillment_time": { + "type": "integer", + "format": "int64", + "description": "Will be used to expire client secret after certain amount of time to be supplied in seconds\n(900) for 15 mins", + "example": 900, + "nullable": true + }, + "frm_routing_algorithm": { + "type": "object", + "description": "The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom'", + "nullable": true + }, + "payout_routing_algorithm": { + "allOf": [ + { + "$ref": "#/components/schemas/RoutingAlgorithm" + } + ], + "nullable": true + }, + "applepay_verified_domains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Verified applepay domains for a particular profile", + "nullable": true + }, + "session_expiry": { + "type": "integer", + "format": "int64", + "description": "Client Secret Default expiry for all payments created under this business profile", + "example": 900, + "nullable": true + }, + "payment_link_config": { + "description": "Default Payment Link config for all payment links created under this business profile", + "nullable": true + } + } + }, "CaptureMethod": { "type": "string", "enum": [ @@ -4516,6 +6400,7 @@ }, "CardNetwork": { "type": "string", + "description": "Indicates the card network.", "enum": [ "Visa", "Mastercard", @@ -4599,16 +6484,49 @@ "CashappQr": { "type": "object" }, + "Comparison": { + "type": "object", + "description": "Represents a single comparison condition.", + "required": [ + "lhs", + "comparison", + "value", + "metadata" + ], + "properties": { + "lhs": { + "type": "string", + "description": "The left hand side which will always be a domain input identifier like \"payment.method.cardtype\"" + }, + "comparison": { + "$ref": "#/components/schemas/ComparisonType" + }, + "value": { + "$ref": "#/components/schemas/ValueType" + }, + "metadata": { + "type": "object", + "description": "Additional metadata that the Static Analyzer and Backend does not touch.\nThis can be used to store useful information for the frontend and is required for communication\nbetween the static analyzer and the frontend.", + "additionalProperties": {} + } + } + }, + "ComparisonType": { + "type": "string", + "description": "Conditional comparison type", + "enum": [ + "equal", + "not_equal", + "less_than", + "less_than_equal", + "greater_than", + "greater_than_equal" + ] + }, "Connector": { "type": "string", + "description": "A connector is an integration to fulfill payments", "enum": [ - "phonypay", - "fauxpay", - "pretendpay", - "stripe_test", - "adyen_test", - "checkout_test", - "paypal_test", "aci", "adyen", "airwallex", @@ -4692,6 +6610,55 @@ } } }, + "ConnectorSelection": { + "oneOf": [ + { + "type": "object", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "priority" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "volume_split" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConnectorVolumeSplit" + } + } + } + } + ], + "discriminator": { + "propertyName": "type" + } + }, "ConnectorStatus": { "type": "string", "enum": [ @@ -4701,6 +6668,7 @@ }, "ConnectorType": { "type": "string", + "description": "Type of the Connector for the financial use case. Could range from Payments to Accounting to Banking.", "enum": [ "payment_processor", "payment_vas", @@ -4713,6 +6681,23 @@ "payment_method_auth" ] }, + "ConnectorVolumeSplit": { + "type": "object", + "required": [ + "connector", + "split" + ], + "properties": { + "connector": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + }, + "split": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + }, "CountryAlpha2": { "type": "string", "enum": [ @@ -5057,6 +7042,7 @@ }, "Currency": { "type": "string", + "description": "The three letter ISO currency code in uppercase. Eg: 'USD' for the United States Dollar.", "enum": [ "AED", "ALL", @@ -5300,7 +7286,7 @@ "example": "cus_meowerunwiuwiwqw" }, "payment_method": { - "$ref": "#/components/schemas/PaymentMethodType" + "$ref": "#/components/schemas/PaymentMethod" }, "payment_method_type": { "allOf": [ @@ -6474,36 +8460,45 @@ "$ref": "#/components/schemas/Connector" }, "flow": { - "type": "string" + "type": "string", + "description": "The flow in which the code and message occurred for a connector" }, "sub_flow": { - "type": "string" + "type": "string", + "description": "The sub_flow in which the code and message occurred for a connector" }, "code": { - "type": "string" + "type": "string", + "description": "code received from the connector" }, "message": { - "type": "string" + "type": "string", + "description": "message received from the connector" }, "status": { - "type": "string" + "type": "string", + "description": "status provided by the router" }, "router_error": { "type": "string", + "description": "optional error provided by the router", "nullable": true }, "decision": { "$ref": "#/components/schemas/GsmDecision" }, "step_up_possible": { - "type": "boolean" + "type": "boolean", + "description": "indicates if step_up retry is possible" }, "unified_code": { "type": "string", + "description": "error code unified across the connectors", "nullable": true }, "unified_message": { "type": "string", + "description": "error message unified across the connectors", "nullable": true } } @@ -6527,19 +8522,24 @@ ], "properties": { "connector": { - "type": "string" + "type": "string", + "description": "The connector through which payment has gone through" }, "flow": { - "type": "string" + "type": "string", + "description": "The flow in which the code and message occurred for a connector" }, "sub_flow": { - "type": "string" + "type": "string", + "description": "The sub_flow in which the code and message occurred for a connector" }, "code": { - "type": "string" + "type": "string", + "description": "code received from the connector" }, "message": { - "type": "string" + "type": "string", + "description": "message received from the connector" } } }, @@ -6557,16 +8557,20 @@ "type": "boolean" }, "connector": { - "type": "string" + "type": "string", + "description": "The connector through which payment has gone through" }, "flow": { - "type": "string" + "type": "string", + "description": "The flow in which the code and message occurred for a connector" }, "sub_flow": { - "type": "string" + "type": "string", + "description": "The sub_flow in which the code and message occurred for a connector" }, "code": { - "type": "string" + "type": "string", + "description": "code received from the connector" } } }, @@ -6584,39 +8588,50 @@ ], "properties": { "connector": { - "type": "string" + "type": "string", + "description": "The connector through which payment has gone through" }, "flow": { - "type": "string" + "type": "string", + "description": "The flow in which the code and message occurred for a connector" }, "sub_flow": { - "type": "string" + "type": "string", + "description": "The sub_flow in which the code and message occurred for a connector" }, "code": { - "type": "string" + "type": "string", + "description": "code received from the connector" }, "message": { - "type": "string" + "type": "string", + "description": "message received from the connector" }, "status": { - "type": "string" + "type": "string", + "description": "status provided by the router" }, "router_error": { "type": "string", + "description": "optional error provided by the router", "nullable": true }, "decision": { - "type": "string" + "type": "string", + "description": "decision to be taken for auto retries flow" }, "step_up_possible": { - "type": "boolean" + "type": "boolean", + "description": "indicates if step_up retry is possible" }, "unified_code": { "type": "string", + "description": "error code unified across the connectors", "nullable": true }, "unified_message": { "type": "string", + "description": "error message unified across the connectors", "nullable": true } } @@ -6635,16 +8650,20 @@ "$ref": "#/components/schemas/Connector" }, "flow": { - "type": "string" + "type": "string", + "description": "The flow in which the code and message occurred for a connector" }, "sub_flow": { - "type": "string" + "type": "string", + "description": "The sub_flow in which the code and message occurred for a connector" }, "code": { - "type": "string" + "type": "string", + "description": "code received from the connector" }, "message": { - "type": "string" + "type": "string", + "description": "message received from the connector" } } }, @@ -6659,26 +8678,33 @@ ], "properties": { "connector": { - "type": "string" + "type": "string", + "description": "The connector through which payment has gone through" }, "flow": { - "type": "string" + "type": "string", + "description": "The flow in which the code and message occurred for a connector" }, "sub_flow": { - "type": "string" + "type": "string", + "description": "The sub_flow in which the code and message occurred for a connector" }, "code": { - "type": "string" + "type": "string", + "description": "code received from the connector" }, "message": { - "type": "string" + "type": "string", + "description": "message received from the connector" }, "status": { "type": "string", + "description": "status provided by the router", "nullable": true }, "router_error": { "type": "string", + "description": "optional error provided by the router", "nullable": true }, "decision": { @@ -6691,14 +8717,39 @@ }, "step_up_possible": { "type": "boolean", + "description": "indicates if step_up retry is possible", "nullable": true }, "unified_code": { "type": "string", + "description": "error code unified across the connectors", "nullable": true }, "unified_message": { "type": "string", + "description": "error message unified across the connectors", + "nullable": true + } + } + }, + "IfStatement": { + "type": "object", + "description": "Represents an IF statement with conditions and optional nested IF statements\n\n```text\npayment.method = card {\npayment.method.cardtype = (credit, debit) {\npayment.method.network = (amex, rupay, diners)\n}\n}\n```", + "required": [ + "condition" + ], + "properties": { + "condition": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Comparison" + } + }, + "nested": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IfStatement" + }, "nullable": true } } @@ -6833,6 +8884,19 @@ } } }, + "LinkedRoutingConfigRetrieveResponse": { + "oneOf": [ + { + "$ref": "#/components/schemas/RoutingRetrieveResponse" + }, + { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutingDictionaryRecord" + } + } + ] + }, "ListBlocklistQuery": { "type": "object", "required": [ @@ -7057,7 +9121,7 @@ }, "MandateStatus": { "type": "string", - "description": "The status of the mandate, which indicates whether it can be used to initiate a payment", + "description": "The status of the mandate, which indicates whether it can be used to initiate a payment.", "enum": [ "active", "inactive", @@ -7160,11 +9224,6 @@ ], "nullable": true }, - "routing_algorithm": { - "type": "object", - "description": "The routing algorithm to be used for routing payments to desired connectors", - "nullable": true - }, "payout_routing_algorithm": { "allOf": [ { @@ -7196,7 +9255,7 @@ }, "payment_response_hash_key": { "type": "string", - "description": "Refers to the hash key used for calculating the signature for webhooks and redirect response\nIf the value is not provided, a default value is used", + "description": "Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used.", "nullable": true }, "redirect_to_merchant_with_http_post": { @@ -7302,7 +9361,7 @@ }, "payment_response_hash_key": { "type": "string", - "description": "Refers to the Parent Merchant ID if the merchant being created is a sub-merchant", + "description": "Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used.", "example": "xkkdf909012sdjki2dkh5sdf", "nullable": true, "maxLength": 255 @@ -7329,14 +9388,6 @@ ], "nullable": true }, - "routing_algorithm": { - "allOf": [ - { - "$ref": "#/components/schemas/RoutingAlgorithm" - } - ], - "nullable": true - }, "payout_routing_algorithm": { "allOf": [ { @@ -7381,7 +9432,7 @@ "items": { "$ref": "#/components/schemas/PrimaryBusinessDetails" }, - "description": "Default business details for connector routing" + "description": "Details about the primary business unit of the merchant account" }, "frm_routing_algorithm": { "allOf": [ @@ -7457,11 +9508,6 @@ ], "nullable": true }, - "routing_algorithm": { - "type": "object", - "description": "The routing algorithm to be used for routing payments to desired connectors", - "nullable": true - }, "payout_routing_algorithm": { "allOf": [ { @@ -7493,7 +9539,7 @@ }, "payment_response_hash_key": { "type": "string", - "description": "Refers to the hash key used for payment response", + "description": "Refers to the hash key used for calculating the signature for webhooks and redirect response. If the value is not provided, a default value is used.", "nullable": true }, "redirect_to_merchant_with_http_post": { @@ -7525,7 +9571,7 @@ "items": { "$ref": "#/components/schemas/PrimaryBusinessDetails" }, - "description": "Default business details for connector routing", + "description": "Details about the primary business unit of the merchant account", "nullable": true }, "frm_routing_algorithm": { @@ -7546,8 +9592,7 @@ "description": "Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc.\"", "required": [ "connector_type", - "connector_name", - "status" + "connector_name" ], "properties": { "connector_type": { @@ -7558,19 +9603,78 @@ }, "connector_label": { "type": "string", - "description": "Connector label for a connector, this can serve as a field to identify the connector as per business details", + "description": "This is an unique label you can generate and pass in order to identify this connector account on your Hyperswitch dashboard and reports. Eg: if your profile label is `default`, connector label can be `stripe_default`", "example": "stripe_US_travel", "nullable": true }, - "merchant_connector_id": { + "profile_id": { "type": "string", - "description": "Unique ID of the connector", - "example": "mca_5apGeP94tMts6rg3U3kR", + "description": "Identifier for the business profile, if not provided default will be chosen from merchant account", "nullable": true }, "connector_account_details": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorDetails" + } + ], + "nullable": true + }, + "payment_methods_enabled": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PaymentMethodsEnabled" + }, + "description": "An object containing the details about the payment methods that need to be enabled under this merchant connector account", + "example": [ + { + "accepted_countries": { + "list": [ + "FR", + "DE", + "IN" + ], + "type": "disable_only" + }, + "accepted_currencies": { + "list": [ + "USD", + "EUR" + ], + "type": "enable_only" + }, + "installment_payment_enabled": true, + "maximum_amount": 68607706, + "minimum_amount": 1, + "payment_method": "wallet", + "payment_method_issuers": [ + "labore magna ipsum", + "aute" + ], + "payment_method_types": [ + "upi_collect", + "upi_intent" + ], + "payment_schemes": [ + "Discover", + "Discover" + ], + "recurring_enabled": true + } + ], + "nullable": true + }, + "connector_webhook_details": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorWebhookDetails" + } + ], + "nullable": true + }, + "metadata": { "type": "object", - "description": "Account details of the Connector. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Useful for storing additional, structured information on an object.", + "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", "nullable": true }, "test_mode": { @@ -7587,61 +9691,12 @@ "example": false, "nullable": true }, - "payment_methods_enabled": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PaymentMethodsEnabled" - }, - "description": "Refers to the Parent Merchant ID if the merchant being created is a sub-merchant", - "example": [ - { - "payment_method": "wallet", - "payment_method_types": [ - "upi_collect", - "upi_intent" - ], - "payment_method_issuers": [ - "labore magna ipsum", - "aute" - ], - "payment_schemes": [ - "Discover", - "Discover" - ], - "accepted_currencies": { - "type": "enable_only", - "list": [ - "USD", - "EUR" - ] - }, - "accepted_countries": { - "type": "disable_only", - "list": [ - "FR", - "DE", - "IN" - ] - }, - "minimum_amount": 1, - "maximum_amount": 68607706, - "recurring_enabled": true, - "installment_payment_enabled": true - } - ], - "nullable": true - }, - "metadata": { - "type": "object", - "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", - "nullable": true - }, "frm_configs": { "type": "array", "items": { "$ref": "#/components/schemas/FrmConfigs" }, - "description": "contains the frm configs for the merchant connector", + "description": "Contains the frm configs for the merchant connector", "example": "\n[{\"gateway\":\"stripe\",\"payment_methods\":[{\"payment_method\":\"card\",\"payment_method_types\":[{\"payment_method_type\":\"credit\",\"card_networks\":[\"Visa\"],\"flow\":\"pre\",\"action\":\"cancel_txn\"},{\"payment_method_type\":\"debit\",\"card_networks\":[\"Visa\"],\"flow\":\"pre\"}]}]}]\n", "nullable": true }, @@ -7655,32 +9710,31 @@ }, "business_label": { "type": "string", + "description": "The business label to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead", "nullable": true }, "business_sub_label": { "type": "string", - "description": "Business Sub label of the merchant", + "description": "The business sublabel to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead", "example": "chase", "nullable": true }, - "connector_webhook_details": { - "allOf": [ - { - "$ref": "#/components/schemas/MerchantConnectorWebhookDetails" - } - ], - "nullable": true - }, - "profile_id": { + "merchant_connector_id": { "type": "string", - "description": "Identifier for the business profile, if not provided default will be chosen from merchant account", + "description": "Unique ID of the connector", + "example": "mca_5apGeP94tMts6rg3U3kR", "nullable": true }, "pm_auth_config": { "nullable": true }, "status": { - "$ref": "#/components/schemas/ConnectorStatus" + "allOf": [ + { + "$ref": "#/components/schemas/ConnectorStatus" + } + ], + "nullable": true } } }, @@ -7774,24 +9828,88 @@ "$ref": "#/components/schemas/ConnectorType" }, "connector_name": { - "type": "string", - "description": "Name of the Connector", - "example": "stripe" + "$ref": "#/components/schemas/Connector" }, "connector_label": { "type": "string", - "description": "Connector label for a connector, this can serve as a field to identify the connector as per business details", + "description": "A unique label to identify the connector account created under a business profile", "example": "stripe_US_travel", "nullable": true }, "merchant_connector_id": { "type": "string", - "description": "Unique ID of the connector", + "description": "Unique ID of the merchant connector account", "example": "mca_5apGeP94tMts6rg3U3kR" }, + "profile_id": { + "type": "string", + "description": "Identifier for the business profile, if not provided default will be chosen from merchant account", + "nullable": true, + "maxLength": 64 + }, "connector_account_details": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorDetails" + } + ], + "nullable": true + }, + "payment_methods_enabled": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PaymentMethodsEnabled" + }, + "description": "An object containing the details about the payment methods that need to be enabled under this merchant connector account", + "example": [ + { + "accepted_countries": { + "list": [ + "FR", + "DE", + "IN" + ], + "type": "disable_only" + }, + "accepted_currencies": { + "list": [ + "USD", + "EUR" + ], + "type": "enable_only" + }, + "installment_payment_enabled": true, + "maximum_amount": 68607706, + "minimum_amount": 1, + "payment_method": "wallet", + "payment_method_issuers": [ + "labore magna ipsum", + "aute" + ], + "payment_method_types": [ + "upi_collect", + "upi_intent" + ], + "payment_schemes": [ + "Discover", + "Discover" + ], + "recurring_enabled": true + } + ], + "nullable": true + }, + "connector_webhook_details": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorWebhookDetails" + } + ], + "nullable": true + }, + "metadata": { "type": "object", - "description": "Account details of the Connector. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Useful for storing additional, structured information on an object.", + "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", "nullable": true }, "test_mode": { @@ -7808,53 +9926,13 @@ "example": false, "nullable": true }, - "payment_methods_enabled": { + "frm_configs": { "type": "array", "items": { - "$ref": "#/components/schemas/PaymentMethodsEnabled" + "$ref": "#/components/schemas/FrmConfigs" }, - "description": "Refers to the Parent Merchant ID if the merchant being created is a sub-merchant", - "example": [ - { - "payment_method": "wallet", - "payment_method_types": [ - "upi_collect", - "upi_intent" - ], - "payment_method_issuers": [ - "labore magna ipsum", - "aute" - ], - "payment_schemes": [ - "Discover", - "Discover" - ], - "accepted_currencies": { - "type": "enable_only", - "list": [ - "USD", - "EUR" - ] - }, - "accepted_countries": { - "type": "disable_only", - "list": [ - "FR", - "DE", - "IN" - ] - }, - "minimum_amount": 1, - "maximum_amount": 68607706, - "recurring_enabled": true, - "installment_payment_enabled": true - } - ], - "nullable": true - }, - "metadata": { - "type": "object", - "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", + "description": "Contains the frm configs for the merchant connector", + "example": "\n[{\"gateway\":\"stripe\",\"payment_methods\":[{\"payment_method\":\"card\",\"payment_method_types\":[{\"payment_method_type\":\"credit\",\"card_networks\":[\"Visa\"],\"flow\":\"pre\",\"action\":\"cancel_txn\"},{\"payment_method_type\":\"debit\",\"card_networks\":[\"Visa\"],\"flow\":\"pre\"}]}]}]\n", "nullable": true }, "business_country": { @@ -7867,39 +9945,16 @@ }, "business_label": { "type": "string", - "description": "Business Type of the merchant", + "description": "The business label to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead", "example": "travel", "nullable": true }, "business_sub_label": { "type": "string", - "description": "Business Sub label of the merchant", + "description": "The business sublabel to which the connector account is attached. To be deprecated soon. Use the 'profile_id' instead", "example": "chase", "nullable": true }, - "frm_configs": { - "type": "array", - "items": { - "$ref": "#/components/schemas/FrmConfigs" - }, - "description": "contains the frm configs for the merchant connector", - "example": "\n[{\"gateway\":\"stripe\",\"payment_methods\":[{\"payment_method\":\"card\",\"payment_method_types\":[{\"payment_method_type\":\"credit\",\"card_networks\":[\"Visa\"],\"flow\":\"pre\",\"action\":\"cancel_txn\"},{\"payment_method_type\":\"debit\",\"card_networks\":[\"Visa\"],\"flow\":\"pre\"}]}]}]\n", - "nullable": true - }, - "connector_webhook_details": { - "allOf": [ - { - "$ref": "#/components/schemas/MerchantConnectorWebhookDetails" - } - ], - "nullable": true - }, - "profile_id": { - "type": "string", - "description": "The business profile this connector must be created in\ndefault value from merchant account is taken if not passed", - "nullable": true, - "maxLength": 64 - }, "applepay_verified_domains": { "type": "array", "items": { @@ -7929,12 +9984,73 @@ }, "connector_label": { "type": "string", - "description": "Connector label for a connector, this can serve as a field to identify the connector as per business details", + "description": "This is an unique label you can generate and pass in order to identify this connector account on your Hyperswitch dashboard and reports. Eg: if your profile label is `default`, connector label can be `stripe_default`", + "example": "stripe_US_travel", "nullable": true }, "connector_account_details": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorDetails" + } + ], + "nullable": true + }, + "payment_methods_enabled": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PaymentMethodsEnabled" + }, + "description": "An object containing the details about the payment methods that need to be enabled under this merchant connector account", + "example": [ + { + "accepted_countries": { + "list": [ + "FR", + "DE", + "IN" + ], + "type": "disable_only" + }, + "accepted_currencies": { + "list": [ + "USD", + "EUR" + ], + "type": "enable_only" + }, + "installment_payment_enabled": true, + "maximum_amount": 68607706, + "minimum_amount": 1, + "payment_method": "wallet", + "payment_method_issuers": [ + "labore magna ipsum", + "aute" + ], + "payment_method_types": [ + "upi_collect", + "upi_intent" + ], + "payment_schemes": [ + "Discover", + "Discover" + ], + "recurring_enabled": true + } + ], + "nullable": true + }, + "connector_webhook_details": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorWebhookDetails" + } + ], + "nullable": true + }, + "metadata": { "type": "object", - "description": "Account details of the Connector. You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Useful for storing additional, structured information on an object.", + "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", "nullable": true }, "test_mode": { @@ -7951,72 +10067,15 @@ "example": false, "nullable": true }, - "payment_methods_enabled": { - "type": "array", - "items": { - "$ref": "#/components/schemas/PaymentMethodsEnabled" - }, - "description": "Refers to the Parent Merchant ID if the merchant being created is a sub-merchant", - "example": [ - { - "payment_method": "wallet", - "payment_method_types": [ - "upi_collect", - "upi_intent" - ], - "payment_method_issuers": [ - "labore magna ipsum", - "aute" - ], - "payment_schemes": [ - "Discover", - "Discover" - ], - "accepted_currencies": { - "type": "enable_only", - "list": [ - "USD", - "EUR" - ] - }, - "accepted_countries": { - "type": "disable_only", - "list": [ - "FR", - "DE", - "IN" - ] - }, - "minimum_amount": 1, - "maximum_amount": 68607706, - "recurring_enabled": true, - "installment_payment_enabled": true - } - ], - "nullable": true - }, - "metadata": { - "type": "object", - "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", - "nullable": true - }, "frm_configs": { "type": "array", "items": { "$ref": "#/components/schemas/FrmConfigs" }, - "description": "contains the frm configs for the merchant connector", + "description": "Contains the frm configs for the merchant connector", "example": "\n[{\"gateway\":\"stripe\",\"payment_methods\":[{\"payment_method\":\"card\",\"payment_method_types\":[{\"payment_method_type\":\"credit\",\"card_networks\":[\"Visa\"],\"flow\":\"pre\",\"action\":\"cancel_txn\"},{\"payment_method_type\":\"debit\",\"card_networks\":[\"Visa\"],\"flow\":\"pre\"}]}]}]\n", "nullable": true }, - "connector_webhook_details": { - "allOf": [ - { - "$ref": "#/components/schemas/MerchantConnectorWebhookDetails" - } - ], - "nullable": true - }, "pm_auth_config": { "nullable": true }, @@ -8111,6 +10170,55 @@ } } }, + "MerchantRoutingAlgorithm": { + "type": "object", + "description": "Routing Algorithm specific to merchants", + "required": [ + "id", + "name", + "description", + "algorithm", + "created_at", + "modified_at" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "algorithm": { + "$ref": "#/components/schemas/RoutingAlgorithm" + }, + "created_at": { + "type": "integer", + "format": "int64" + }, + "modified_at": { + "type": "integer", + "format": "int64" + } + } + }, + "MetadataValue": { + "type": "object", + "required": [ + "key", + "value" + ], + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "MobilePayRedirection": { "type": "object" }, @@ -8382,6 +10490,23 @@ } } }, + "NumberComparison": { + "type": "object", + "description": "Represents a number comparison for \"NumberComparisonArrayValue\"", + "required": [ + "comparisonType", + "number" + ], + "properties": { + "comparisonType": { + "$ref": "#/components/schemas/ComparisonType" + }, + "number": { + "type": "integer", + "format": "int64" + } + } + }, "OnlineMandate": { "type": "object", "required": [ @@ -8548,6 +10673,7 @@ "oneOf": [ { "type": "object", + "title": "PaymentsResponse", "required": [ "type", "object" @@ -8566,6 +10692,7 @@ }, { "type": "object", + "title": "RefundResponse", "required": [ "type", "object" @@ -8584,6 +10711,7 @@ }, { "type": "object", + "title": "DisputeResponse", "required": [ "type", "object" @@ -8602,6 +10730,7 @@ }, { "type": "object", + "title": "MandateResponse", "required": [ "type", "object" @@ -8913,6 +11042,7 @@ }, "PaymentExperience": { "type": "string", + "description": "To indicate the type of payment experience that the customer would go through", "enum": [ "redirect_to_url", "invoke_sdk_client", @@ -9160,6 +11290,7 @@ }, "PaymentMethod": { "type": "string", + "description": "Indicates the type of payment method. Eg: 'card', 'wallet', etc.", "enum": [ "card", "card_redirect", @@ -9182,7 +11313,7 @@ ], "properties": { "payment_method": { - "$ref": "#/components/schemas/PaymentMethodType" + "$ref": "#/components/schemas/PaymentMethod" }, "payment_method_type": { "allOf": [ @@ -9245,6 +11376,7 @@ "oneOf": [ { "type": "object", + "title": "Card", "required": [ "card" ], @@ -9256,6 +11388,7 @@ }, { "type": "object", + "title": "CardRedirect", "required": [ "card_redirect" ], @@ -9267,6 +11400,7 @@ }, { "type": "object", + "title": "Wallet", "required": [ "wallet" ], @@ -9278,6 +11412,7 @@ }, { "type": "object", + "title": "PayLater", "required": [ "pay_later" ], @@ -9289,6 +11424,7 @@ }, { "type": "object", + "title": "BankRedirect", "required": [ "bank_redirect" ], @@ -9300,6 +11436,7 @@ }, { "type": "object", + "title": "BankDebit", "required": [ "bank_debit" ], @@ -9311,6 +11448,7 @@ }, { "type": "object", + "title": "BankTransfer", "required": [ "bank_transfer" ], @@ -9322,6 +11460,7 @@ }, { "type": "object", + "title": "Crypto", "required": [ "crypto" ], @@ -9333,18 +11472,21 @@ }, { "type": "string", + "title": "MandatePayment", "enum": [ "mandate_payment" ] }, { "type": "string", + "title": "Reward", "enum": [ "reward" ] }, { "type": "object", + "title": "Upi", "required": [ "upi" ], @@ -9356,6 +11498,7 @@ }, { "type": "object", + "title": "Voucher", "required": [ "voucher" ], @@ -9367,6 +11510,7 @@ }, { "type": "object", + "title": "GiftCard", "required": [ "gift_card" ], @@ -9378,6 +11522,7 @@ }, { "type": "object", + "title": "CardToken", "required": [ "card_token" ], @@ -9467,8 +11612,8 @@ "description": "Information about the payment method", "example": [ { - "payment_method": "wallet", "payment_experience": null, + "payment_method": "wallet", "payment_method_issuers": [ "labore magna ipsum", "aute" @@ -9524,7 +11669,7 @@ "example": "card_rGK4Vi5iSW70MY7J2mIy" }, "payment_method": { - "$ref": "#/components/schemas/PaymentMethodType" + "$ref": "#/components/schemas/PaymentMethod" }, "payment_method_type": { "allOf": [ @@ -9587,6 +11732,7 @@ }, "PaymentMethodType": { "type": "string", + "description": "Indicates the sub type of payment method. Eg: 'google_pay' & 'apple_pay' for wallets.", "enum": [ "ach", "affirm", @@ -9762,6 +11908,7 @@ }, "PaymentType": { "type": "string", + "description": "To be used to specify the type of payment. Use 'setup_mandate' in case of zero auth flow.", "enum": [ "normal", "new_mandate", @@ -9771,9 +11918,6 @@ }, "PaymentsCancelRequest": { "type": "object", - "required": [ - "merchant_connector_details" - ], "properties": { "cancellation_reason": { "type": "string", @@ -9781,7 +11925,12 @@ "nullable": true }, "merchant_connector_details": { - "$ref": "#/components/schemas/MerchantConnectorDetailsWrap" + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorDetailsWrap" + } + ], + "nullable": true } } }, @@ -9824,13 +11973,32 @@ } } }, - "PaymentsCreateRequest": { + "PaymentsConfirmRequest": { "type": "object", - "required": [ - "amount", - "currency" - ], "properties": { + "amount": { + "type": "integer", + "format": "int64", + "description": "The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and ¥100 since ¥ is a zero-decimal currency", + "example": 6540, + "nullable": true, + "minimum": 0 + }, + "currency": { + "allOf": [ + { + "$ref": "#/components/schemas/Currency" + } + ], + "nullable": true + }, + "amount_to_capture": { + "type": "integer", + "format": "int64", + "description": "The Amount to be captured / debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc., If not provided, the default amount_to_capture will be the payment amount.", + "example": 6540, + "nullable": true + }, "payment_id": { "type": "string", "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant. This field is auto generated and is returned in the API response.", @@ -9846,18 +12014,10 @@ "nullable": true, "maxLength": 255 }, - "amount": { - "type": "integer", - "format": "int64", - "description": "The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,", - "example": 6540, - "nullable": true, - "minimum": 0 - }, "routing": { "allOf": [ { - "$ref": "#/components/schemas/RoutingAlgorithm" + "$ref": "#/components/schemas/StraightThroughAlgorithm" } ], "nullable": true @@ -9867,21 +12027,13 @@ "items": { "$ref": "#/components/schemas/Connector" }, - "description": "This allows the merchant to manually select a connector with which the payment can go through", + "description": "This allows to manually select a connector with which the payment can go through", "example": [ "stripe", "adyen" ], "nullable": true }, - "currency": { - "allOf": [ - { - "$ref": "#/components/schemas/Currency" - } - ], - "nullable": true - }, "capture_method": { "allOf": [ { @@ -9890,11 +12042,21 @@ ], "nullable": true }, - "amount_to_capture": { - "type": "integer", - "format": "int64", - "description": "The Amount to be captured/ debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,\nIf not provided, the default amount_to_capture will be the payment amount.", - "example": 6540, + "authentication_type": { + "allOf": [ + { + "$ref": "#/components/schemas/AuthenticationType" + } + ], + "default": "three_ds", + "nullable": true + }, + "billing": { + "allOf": [ + { + "$ref": "#/components/schemas/Address" + } + ], "nullable": true }, "capture_on": { @@ -9921,21 +12083,21 @@ }, "customer_id": { "type": "string", - "description": "The identifier for the customer object.\nThis field will be deprecated soon, use the customer object instead", + "description": "The identifier for the customer object. This field will be deprecated soon, use the customer object instead", "example": "cus_y3oqhf46pyzuxjbcn2giaqnb44", "nullable": true, "maxLength": 255 }, "email": { "type": "string", - "description": "The customer's email address\nThis field will be deprecated soon, use the customer object instead", + "description": "The customer's email address This field will be deprecated soon, use the customer object instead", "example": "johntest@test.com", "nullable": true, "maxLength": 255 }, "name": { "type": "string", - "description": "description: The customer's name\nThis field will be deprecated soon, use the customer object instead", + "description": "The customer's name.\nThis field will be deprecated soon, use the customer object instead.", "example": "John Test", "nullable": true, "maxLength": 255 @@ -9956,13 +12118,13 @@ }, "off_session": { "type": "boolean", - "description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. This parameter can only be used with `confirm: true`.", + "description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. When making a recurring payment by passing a mandate_id, this parameter is mandatory", "example": true, "nullable": true }, "description": { "type": "string", - "description": "A description of the payment", + "description": "A description for the payment", "example": "It's my first payment request", "nullable": true }, @@ -9980,15 +12142,6 @@ ], "nullable": true }, - "authentication_type": { - "allOf": [ - { - "$ref": "#/components/schemas/AuthenticationType" - } - ], - "default": "three_ds", - "nullable": true - }, "payment_method_data": { "allOf": [ { @@ -10013,7 +12166,7 @@ }, "card_cvc": { "type": "string", - "description": "This is used when payment is to be confirmed and the card is not saved.\nThis field will be deprecated soon, use the CardToken object instead", + "description": "This is used along with the payment_token field while collecting during saved card payments. This field will be deprecated soon, use the payment_method_data.card_token object instead", "deprecated": true, "nullable": true }, @@ -10025,14 +12178,6 @@ ], "nullable": true }, - "billing": { - "allOf": [ - { - "$ref": "#/components/schemas/Address" - } - ], - "nullable": true - }, "statement_descriptor_name": { "type": "string", "description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.", @@ -10052,8 +12197,8 @@ "items": { "$ref": "#/components/schemas/OrderDetailsWithAmount" }, - "description": "Information about the product , quantity and amount for connectors. (e.g. Klarna)", - "example": "[{\n \"product_name\": \"gillete creme\",\n \"quantity\": 15,\n \"amount\" : 900\n \"product_img_link\" : \"https://dummy-img-link.com\"\n }]", + "description": "Use this object to capture the details about the different products for which the payment is being made. The sum of amount across different products here should be equal to the overall payment amount", + "example": "[{\n \"product_name\": \"Apple iPhone 16\",\n \"quantity\": 1,\n \"amount\" : 69000\n \"product_img_link\" : \"https://dummy-img-link.com\"\n }]", "nullable": true }, "client_secret": { @@ -10072,14 +12217,368 @@ }, "mandate_id": { "type": "string", - "description": "A unique identifier to link the payment to a mandate, can be use instead of payment_method_data", + "description": "A unique identifier to link the payment to a mandate. To do Recurring payments after a mandate has been created, pass the mandate_id instead of payment_method_data", "example": "mandate_iwer89rnjef349dni3", "nullable": true, "maxLength": 255 }, "browser_info": { + "allOf": [ + { + "$ref": "#/components/schemas/BrowserInformation" + } + ], + "nullable": true + }, + "payment_experience": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentExperience" + } + ], + "nullable": true + }, + "payment_method_type": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentMethodType" + } + ], + "nullable": true + }, + "merchant_connector_details": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorDetailsWrap" + } + ], + "nullable": true + }, + "allowed_payment_method_types": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PaymentMethodType" + }, + "description": "Use this parameter to restrict the Payment Method Types to show for a given PaymentIntent", + "nullable": true + }, + "retry_action": { + "allOf": [ + { + "$ref": "#/components/schemas/RetryAction" + } + ], + "nullable": true + }, + "metadata": { "type": "object", - "description": "Additional details required by 3DS 2.0", + "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", + "nullable": true + }, + "connector_metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/ConnectorMetadata" + } + ], + "nullable": true + }, + "feature_metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/FeatureMetadata" + } + ], + "nullable": true + }, + "payment_link": { + "type": "boolean", + "description": "Whether to get the payment link (if applicable)", + "default": false, + "example": true, + "nullable": true + }, + "payment_link_config": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentCreatePaymentLinkConfig" + } + ], + "nullable": true + }, + "payment_type": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentType" + } + ], + "nullable": true + }, + "request_incremental_authorization": { + "type": "boolean", + "description": "Request for an incremental authorization", + "nullable": true + }, + "session_expiry": { + "type": "integer", + "format": "int32", + "description": "Will be used to expire client secret after certain amount of time to be supplied in seconds\n(900) for 15 mins", + "example": 900, + "nullable": true, + "minimum": 0 + }, + "frm_metadata": { + "description": "additional data related to some frm connectors", + "nullable": true + } + } + }, + "PaymentsCreateRequest": { + "type": "object", + "required": [ + "amount", + "currency" + ], + "properties": { + "amount": { + "type": "integer", + "format": "int64", + "description": "The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and ¥100 since ¥ is a zero-decimal currency", + "minimum": 0 + }, + "currency": { + "$ref": "#/components/schemas/Currency" + }, + "amount_to_capture": { + "type": "integer", + "format": "int64", + "description": "The Amount to be captured / debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc., If not provided, the default amount_to_capture will be the payment amount.", + "example": 6540, + "nullable": true + }, + "payment_id": { + "type": "string", + "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant. This field is auto generated and is returned in the API response.", + "example": "pay_mbabizu24mvu3mela5njyhpit4", + "nullable": true, + "maxLength": 30, + "minLength": 30 + }, + "merchant_id": { + "type": "string", + "description": "This is an identifier for the merchant account. This is inferred from the API key\nprovided during the request", + "example": "merchant_1668273825", + "nullable": true, + "maxLength": 255 + }, + "routing": { + "allOf": [ + { + "$ref": "#/components/schemas/StraightThroughAlgorithm" + } + ], + "nullable": true + }, + "connector": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Connector" + }, + "description": "This allows to manually select a connector with which the payment can go through", + "example": [ + "stripe", + "adyen" + ], + "nullable": true + }, + "capture_method": { + "allOf": [ + { + "$ref": "#/components/schemas/CaptureMethod" + } + ], + "nullable": true + }, + "authentication_type": { + "allOf": [ + { + "$ref": "#/components/schemas/AuthenticationType" + } + ], + "default": "three_ds", + "nullable": true + }, + "billing": { + "allOf": [ + { + "$ref": "#/components/schemas/Address" + } + ], + "nullable": true + }, + "capture_on": { + "type": "string", + "format": "date-time", + "description": "A timestamp (ISO 8601 code) that determines when the payment should be captured.\nProviding this field will automatically set `capture` to true", + "example": "2022-09-10T10:11:12Z", + "nullable": true + }, + "confirm": { + "type": "boolean", + "description": "Whether to confirm the payment (if applicable)", + "default": false, + "example": true, + "nullable": true + }, + "customer": { + "allOf": [ + { + "$ref": "#/components/schemas/CustomerDetails" + } + ], + "nullable": true + }, + "customer_id": { + "type": "string", + "description": "The identifier for the customer object. This field will be deprecated soon, use the customer object instead", + "example": "cus_y3oqhf46pyzuxjbcn2giaqnb44", + "nullable": true, + "maxLength": 255 + }, + "email": { + "type": "string", + "description": "The customer's email address This field will be deprecated soon, use the customer object instead", + "example": "johntest@test.com", + "nullable": true, + "maxLength": 255 + }, + "name": { + "type": "string", + "description": "The customer's name.\nThis field will be deprecated soon, use the customer object instead.", + "example": "John Test", + "nullable": true, + "maxLength": 255 + }, + "phone": { + "type": "string", + "description": "The customer's phone number\nThis field will be deprecated soon, use the customer object instead", + "example": "3141592653", + "nullable": true, + "maxLength": 255 + }, + "phone_country_code": { + "type": "string", + "description": "The country code for the customer phone number\nThis field will be deprecated soon, use the customer object instead", + "example": "+1", + "nullable": true, + "maxLength": 255 + }, + "off_session": { + "type": "boolean", + "description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. When making a recurring payment by passing a mandate_id, this parameter is mandatory", + "example": true, + "nullable": true + }, + "description": { + "type": "string", + "description": "A description for the payment", + "example": "It's my first payment request", + "nullable": true + }, + "return_url": { + "type": "string", + "description": "The URL to redirect after the completion of the operation", + "example": "https://hyperswitch.io", + "nullable": true + }, + "setup_future_usage": { + "allOf": [ + { + "$ref": "#/components/schemas/FutureUsage" + } + ], + "nullable": true + }, + "payment_method_data": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentMethodData" + } + ], + "nullable": true + }, + "payment_method": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentMethod" + } + ], + "nullable": true + }, + "payment_token": { + "type": "string", + "description": "Provide a reference to a stored payment method", + "example": "187282ab-40ef-47a9-9206-5099ba31e432", + "nullable": true + }, + "card_cvc": { + "type": "string", + "description": "This is used along with the payment_token field while collecting during saved card payments. This field will be deprecated soon, use the payment_method_data.card_token object instead", + "deprecated": true, + "nullable": true + }, + "shipping": { + "allOf": [ + { + "$ref": "#/components/schemas/Address" + } + ], + "nullable": true + }, + "statement_descriptor_name": { + "type": "string", + "description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.", + "example": "Hyperswitch Router", + "nullable": true, + "maxLength": 255 + }, + "statement_descriptor_suffix": { + "type": "string", + "description": "Provides information about a card payment that customers see on their statements. Concatenated with the prefix (shortened descriptor) or statement descriptor that’s set on the account to form the complete statement descriptor. Maximum 22 characters for the concatenated descriptor.", + "example": "Payment for shoes purchase", + "nullable": true, + "maxLength": 255 + }, + "order_details": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OrderDetailsWithAmount" + }, + "description": "Use this object to capture the details about the different products for which the payment is being made. The sum of amount across different products here should be equal to the overall payment amount", + "example": "[{\n \"product_name\": \"Apple iPhone 16\",\n \"quantity\": 1,\n \"amount\" : 69000\n \"product_img_link\" : \"https://dummy-img-link.com\"\n }]", + "nullable": true + }, + "mandate_data": { + "allOf": [ + { + "$ref": "#/components/schemas/MandateData" + } + ], + "nullable": true + }, + "mandate_id": { + "type": "string", + "description": "A unique identifier to link the payment to a mandate. To do Recurring payments after a mandate has been created, pass the mandate_id instead of payment_method_data", + "example": "mandate_iwer89rnjef349dni3", + "nullable": true, + "maxLength": 255 + }, + "browser_info": { + "allOf": [ + { + "$ref": "#/components/schemas/BrowserInformation" + } + ], "nullable": true }, "payment_experience": { @@ -10108,7 +12607,7 @@ }, "business_label": { "type": "string", - "description": "Business label of the merchant for this payment", + "description": "Business label of the merchant for this payment.\nTo be deprecated soon. Pass the profile_id instead", "example": "food", "nullable": true }, @@ -10125,12 +12624,7 @@ "items": { "$ref": "#/components/schemas/PaymentMethodType" }, - "description": "Allowed Payment Method Types for a given PaymentIntent", - "nullable": true - }, - "business_sub_label": { - "type": "string", - "description": "Business sub label for the payment", + "description": "Use this parameter to restrict the Payment Method Types to show for a given PaymentIntent", "nullable": true }, "retry_action": { @@ -10217,9 +12711,51 @@ } } }, + "PaymentsIncrementalAuthorizationRequest": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "integer", + "format": "int64", + "description": "The total amount including previously authorized amount and additional amount", + "example": 6540 + }, + "reason": { + "type": "string", + "description": "Reason for incremental authorization", + "nullable": true + } + } + }, "PaymentsRequest": { "type": "object", "properties": { + "amount": { + "type": "integer", + "format": "int64", + "description": "The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and ¥100 since ¥ is a zero-decimal currency", + "example": 6540, + "nullable": true, + "minimum": 0 + }, + "currency": { + "allOf": [ + { + "$ref": "#/components/schemas/Currency" + } + ], + "nullable": true + }, + "amount_to_capture": { + "type": "integer", + "format": "int64", + "description": "The Amount to be captured / debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc., If not provided, the default amount_to_capture will be the payment amount.", + "example": 6540, + "nullable": true + }, "payment_id": { "type": "string", "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant. This field is auto generated and is returned in the API response.", @@ -10235,18 +12771,10 @@ "nullable": true, "maxLength": 255 }, - "amount": { - "type": "integer", - "format": "int64", - "description": "The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,", - "example": 6540, - "nullable": true, - "minimum": 0 - }, "routing": { "allOf": [ { - "$ref": "#/components/schemas/RoutingAlgorithm" + "$ref": "#/components/schemas/StraightThroughAlgorithm" } ], "nullable": true @@ -10256,21 +12784,13 @@ "items": { "$ref": "#/components/schemas/Connector" }, - "description": "This allows the merchant to manually select a connector with which the payment can go through", + "description": "This allows to manually select a connector with which the payment can go through", "example": [ "stripe", "adyen" ], "nullable": true }, - "currency": { - "allOf": [ - { - "$ref": "#/components/schemas/Currency" - } - ], - "nullable": true - }, "capture_method": { "allOf": [ { @@ -10279,11 +12799,21 @@ ], "nullable": true }, - "amount_to_capture": { - "type": "integer", - "format": "int64", - "description": "The Amount to be captured/ debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,\nIf not provided, the default amount_to_capture will be the payment amount.", - "example": 6540, + "authentication_type": { + "allOf": [ + { + "$ref": "#/components/schemas/AuthenticationType" + } + ], + "default": "three_ds", + "nullable": true + }, + "billing": { + "allOf": [ + { + "$ref": "#/components/schemas/Address" + } + ], "nullable": true }, "capture_on": { @@ -10310,21 +12840,21 @@ }, "customer_id": { "type": "string", - "description": "The identifier for the customer object.\nThis field will be deprecated soon, use the customer object instead", + "description": "The identifier for the customer object. This field will be deprecated soon, use the customer object instead", "example": "cus_y3oqhf46pyzuxjbcn2giaqnb44", "nullable": true, "maxLength": 255 }, "email": { "type": "string", - "description": "The customer's email address\nThis field will be deprecated soon, use the customer object instead", + "description": "The customer's email address This field will be deprecated soon, use the customer object instead", "example": "johntest@test.com", "nullable": true, "maxLength": 255 }, "name": { "type": "string", - "description": "description: The customer's name\nThis field will be deprecated soon, use the customer object instead", + "description": "The customer's name.\nThis field will be deprecated soon, use the customer object instead.", "example": "John Test", "nullable": true, "maxLength": 255 @@ -10345,13 +12875,13 @@ }, "off_session": { "type": "boolean", - "description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. This parameter can only be used with `confirm: true`.", + "description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. When making a recurring payment by passing a mandate_id, this parameter is mandatory", "example": true, "nullable": true }, "description": { "type": "string", - "description": "A description of the payment", + "description": "A description for the payment", "example": "It's my first payment request", "nullable": true }, @@ -10369,15 +12899,6 @@ ], "nullable": true }, - "authentication_type": { - "allOf": [ - { - "$ref": "#/components/schemas/AuthenticationType" - } - ], - "default": "three_ds", - "nullable": true - }, "payment_method_data": { "allOf": [ { @@ -10402,7 +12923,7 @@ }, "card_cvc": { "type": "string", - "description": "This is used when payment is to be confirmed and the card is not saved.\nThis field will be deprecated soon, use the CardToken object instead", + "description": "This is used along with the payment_token field while collecting during saved card payments. This field will be deprecated soon, use the payment_method_data.card_token object instead", "deprecated": true, "nullable": true }, @@ -10414,14 +12935,6 @@ ], "nullable": true }, - "billing": { - "allOf": [ - { - "$ref": "#/components/schemas/Address" - } - ], - "nullable": true - }, "statement_descriptor_name": { "type": "string", "description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.", @@ -10441,8 +12954,8 @@ "items": { "$ref": "#/components/schemas/OrderDetailsWithAmount" }, - "description": "Information about the product , quantity and amount for connectors. (e.g. Klarna)", - "example": "[{\n \"product_name\": \"gillete creme\",\n \"quantity\": 15,\n \"amount\" : 900\n \"product_img_link\" : \"https://dummy-img-link.com\"\n }]", + "description": "Use this object to capture the details about the different products for which the payment is being made. The sum of amount across different products here should be equal to the overall payment amount", + "example": "[{\n \"product_name\": \"Apple iPhone 16\",\n \"quantity\": 1,\n \"amount\" : 69000\n \"product_img_link\" : \"https://dummy-img-link.com\"\n }]", "nullable": true }, "client_secret": { @@ -10461,14 +12974,17 @@ }, "mandate_id": { "type": "string", - "description": "A unique identifier to link the payment to a mandate, can be use instead of payment_method_data", + "description": "A unique identifier to link the payment to a mandate. To do Recurring payments after a mandate has been created, pass the mandate_id instead of payment_method_data", "example": "mandate_iwer89rnjef349dni3", "nullable": true, "maxLength": 255 }, "browser_info": { - "type": "object", - "description": "Additional details required by 3DS 2.0", + "allOf": [ + { + "$ref": "#/components/schemas/BrowserInformation" + } + ], "nullable": true }, "payment_experience": { @@ -10497,7 +13013,7 @@ }, "business_label": { "type": "string", - "description": "Business label of the merchant for this payment", + "description": "Business label of the merchant for this payment.\nTo be deprecated soon. Pass the profile_id instead", "example": "food", "nullable": true }, @@ -10514,7 +13030,7 @@ "items": { "$ref": "#/components/schemas/PaymentMethodType" }, - "description": "Allowed Payment Method Types for a given PaymentIntent", + "description": "Use this parameter to restrict the Payment Method Types to show for a given PaymentIntent", "nullable": true }, "business_sub_label": { @@ -11211,6 +13727,361 @@ } } }, + "PaymentsUpdateRequest": { + "type": "object", + "properties": { + "amount": { + "type": "integer", + "format": "int64", + "description": "The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and ¥100 since ¥ is a zero-decimal currency", + "example": 6540, + "nullable": true, + "minimum": 0 + }, + "currency": { + "allOf": [ + { + "$ref": "#/components/schemas/Currency" + } + ], + "nullable": true + }, + "amount_to_capture": { + "type": "integer", + "format": "int64", + "description": "The Amount to be captured / debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc., If not provided, the default amount_to_capture will be the payment amount.", + "example": 6540, + "nullable": true + }, + "payment_id": { + "type": "string", + "description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant. This field is auto generated and is returned in the API response.", + "example": "pay_mbabizu24mvu3mela5njyhpit4", + "nullable": true, + "maxLength": 30, + "minLength": 30 + }, + "merchant_id": { + "type": "string", + "description": "This is an identifier for the merchant account. This is inferred from the API key\nprovided during the request", + "example": "merchant_1668273825", + "nullable": true, + "maxLength": 255 + }, + "routing": { + "allOf": [ + { + "$ref": "#/components/schemas/StraightThroughAlgorithm" + } + ], + "nullable": true + }, + "connector": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Connector" + }, + "description": "This allows to manually select a connector with which the payment can go through", + "example": [ + "stripe", + "adyen" + ], + "nullable": true + }, + "capture_method": { + "allOf": [ + { + "$ref": "#/components/schemas/CaptureMethod" + } + ], + "nullable": true + }, + "authentication_type": { + "allOf": [ + { + "$ref": "#/components/schemas/AuthenticationType" + } + ], + "default": "three_ds", + "nullable": true + }, + "billing": { + "allOf": [ + { + "$ref": "#/components/schemas/Address" + } + ], + "nullable": true + }, + "capture_on": { + "type": "string", + "format": "date-time", + "description": "A timestamp (ISO 8601 code) that determines when the payment should be captured.\nProviding this field will automatically set `capture` to true", + "example": "2022-09-10T10:11:12Z", + "nullable": true + }, + "confirm": { + "type": "boolean", + "description": "Whether to confirm the payment (if applicable)", + "default": false, + "example": true, + "nullable": true + }, + "customer": { + "allOf": [ + { + "$ref": "#/components/schemas/CustomerDetails" + } + ], + "nullable": true + }, + "customer_id": { + "type": "string", + "description": "The identifier for the customer object. This field will be deprecated soon, use the customer object instead", + "example": "cus_y3oqhf46pyzuxjbcn2giaqnb44", + "nullable": true, + "maxLength": 255 + }, + "email": { + "type": "string", + "description": "The customer's email address This field will be deprecated soon, use the customer object instead", + "example": "johntest@test.com", + "nullable": true, + "maxLength": 255 + }, + "name": { + "type": "string", + "description": "The customer's name.\nThis field will be deprecated soon, use the customer object instead.", + "example": "John Test", + "nullable": true, + "maxLength": 255 + }, + "phone": { + "type": "string", + "description": "The customer's phone number\nThis field will be deprecated soon, use the customer object instead", + "example": "3141592653", + "nullable": true, + "maxLength": 255 + }, + "phone_country_code": { + "type": "string", + "description": "The country code for the customer phone number\nThis field will be deprecated soon, use the customer object instead", + "example": "+1", + "nullable": true, + "maxLength": 255 + }, + "off_session": { + "type": "boolean", + "description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. When making a recurring payment by passing a mandate_id, this parameter is mandatory", + "example": true, + "nullable": true + }, + "description": { + "type": "string", + "description": "A description for the payment", + "example": "It's my first payment request", + "nullable": true + }, + "return_url": { + "type": "string", + "description": "The URL to redirect after the completion of the operation", + "example": "https://hyperswitch.io", + "nullable": true + }, + "setup_future_usage": { + "allOf": [ + { + "$ref": "#/components/schemas/FutureUsage" + } + ], + "nullable": true + }, + "payment_method_data": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentMethodData" + } + ], + "nullable": true + }, + "payment_method": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentMethod" + } + ], + "nullable": true + }, + "payment_token": { + "type": "string", + "description": "Provide a reference to a stored payment method", + "example": "187282ab-40ef-47a9-9206-5099ba31e432", + "nullable": true + }, + "card_cvc": { + "type": "string", + "description": "This is used along with the payment_token field while collecting during saved card payments. This field will be deprecated soon, use the payment_method_data.card_token object instead", + "deprecated": true, + "nullable": true + }, + "shipping": { + "allOf": [ + { + "$ref": "#/components/schemas/Address" + } + ], + "nullable": true + }, + "statement_descriptor_name": { + "type": "string", + "description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.", + "example": "Hyperswitch Router", + "nullable": true, + "maxLength": 255 + }, + "statement_descriptor_suffix": { + "type": "string", + "description": "Provides information about a card payment that customers see on their statements. Concatenated with the prefix (shortened descriptor) or statement descriptor that’s set on the account to form the complete statement descriptor. Maximum 22 characters for the concatenated descriptor.", + "example": "Payment for shoes purchase", + "nullable": true, + "maxLength": 255 + }, + "order_details": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OrderDetailsWithAmount" + }, + "description": "Use this object to capture the details about the different products for which the payment is being made. The sum of amount across different products here should be equal to the overall payment amount", + "example": "[{\n \"product_name\": \"Apple iPhone 16\",\n \"quantity\": 1,\n \"amount\" : 69000\n \"product_img_link\" : \"https://dummy-img-link.com\"\n }]", + "nullable": true + }, + "mandate_data": { + "allOf": [ + { + "$ref": "#/components/schemas/MandateData" + } + ], + "nullable": true + }, + "browser_info": { + "allOf": [ + { + "$ref": "#/components/schemas/BrowserInformation" + } + ], + "nullable": true + }, + "payment_experience": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentExperience" + } + ], + "nullable": true + }, + "payment_method_type": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentMethodType" + } + ], + "nullable": true + }, + "merchant_connector_details": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantConnectorDetailsWrap" + } + ], + "nullable": true + }, + "allowed_payment_method_types": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PaymentMethodType" + }, + "description": "Use this parameter to restrict the Payment Method Types to show for a given PaymentIntent", + "nullable": true + }, + "retry_action": { + "allOf": [ + { + "$ref": "#/components/schemas/RetryAction" + } + ], + "nullable": true + }, + "metadata": { + "type": "object", + "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.", + "nullable": true + }, + "connector_metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/ConnectorMetadata" + } + ], + "nullable": true + }, + "feature_metadata": { + "allOf": [ + { + "$ref": "#/components/schemas/FeatureMetadata" + } + ], + "nullable": true + }, + "payment_link": { + "type": "boolean", + "description": "Whether to get the payment link (if applicable)", + "default": false, + "example": true, + "nullable": true + }, + "payment_link_config": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentCreatePaymentLinkConfig" + } + ], + "nullable": true + }, + "surcharge_details": { + "allOf": [ + { + "$ref": "#/components/schemas/RequestSurchargeDetails" + } + ], + "nullable": true + }, + "payment_type": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentType" + } + ], + "nullable": true + }, + "request_incremental_authorization": { + "type": "boolean", + "description": "Request for an incremental authorization", + "nullable": true + }, + "session_expiry": { + "type": "integer", + "format": "int32", + "description": "Will be used to expire client secret after certain amount of time to be supplied in seconds\n(900) for 15 mins", + "example": 900, + "nullable": true, + "minimum": 0 + }, + "frm_metadata": { + "description": "additional data related to some frm connectors", + "nullable": true + } + } + }, "PayoutActionRequest": { "type": "object", "required": [ @@ -11743,6 +14614,45 @@ "accommodation" ] }, + "ProfileDefaultRoutingConfig": { + "type": "object", + "required": [ + "profile_id", + "connectors" + ], + "properties": { + "profile_id": { + "type": "string" + }, + "connectors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + } + }, + "ProgramConnectorSelection": { + "type": "object", + "description": "The program, having a default connector selection and\na bunch of rules. Also can hold arbitrary metadata.", + "required": [ + "defaultSelection", + "rules", + "metadata" + ], + "properties": { + "defaultSelection": { + "$ref": "#/components/schemas/ConnectorSelection" + }, + "rules": { + "$ref": "#/components/schemas/RuleConnectorSelection" + }, + "metadata": { + "type": "object", + "additionalProperties": {} + } + } + }, "ReceiverDetails": { "type": "object", "required": [ @@ -11891,18 +14801,18 @@ "payment_id" ], "properties": { - "refund_id": { + "payment_id": { "type": "string", - "description": "Unique Identifier for the Refund. This is to ensure idempotency for multiple partial refund initiated against the same payment. If the identifiers is not defined by the merchant, this filed shall be auto generated and provide in the API response. It is recommended to generate uuid(v4) as the refund_id.", - "example": "ref_mbabizu24mvu3mela5njyhpit4", - "nullable": true, + "description": "The payment id against which refund is to be intiated", + "example": "pay_mbabizu24mvu3mela5njyhpit4", "maxLength": 30, "minLength": 30 }, - "payment_id": { + "refund_id": { "type": "string", - "description": "Total amount for which the refund is to be initiated. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc. If not provided, this will default to the full payment amount", - "example": "pay_mbabizu24mvu3mela5njyhpit4", + "description": "Unique Identifier for the Refund. This is to ensure idempotency for multiple partial refunds initiated against the same payment. If this is not passed by the merchant, this field shall be auto generated and provided in the API response. It is recommended to generate uuid(v4) as the refund_id.", + "example": "ref_mbabizu24mvu3mela5njyhpit4", + "nullable": true, "maxLength": 30, "minLength": 30 }, @@ -11923,7 +14833,7 @@ }, "reason": { "type": "string", - "description": "An arbitrary string attached to the object. Often useful for displaying to users and your customer support executive", + "description": "Reason for the refund. Often useful for displaying to users and your customer support executive. In case the payment went through Stripe, this field needs to be passed with one of these enums: `duplicate`, `fraudulent`, or `requested_by_customer`", "example": "Customer returned the product", "nullable": true, "maxLength": 255 @@ -11965,11 +14875,11 @@ "properties": { "refund_id": { "type": "string", - "description": "The identifier for refund" + "description": "Unique Identifier for the refund" }, "payment_id": { "type": "string", - "description": "The identifier for payment" + "description": "The payment id against which refund is intiated" }, "amount": { "type": "integer", @@ -11980,14 +14890,14 @@ "type": "string", "description": "The three-letter ISO currency code" }, + "status": { + "$ref": "#/components/schemas/RefundStatus" + }, "reason": { "type": "string", "description": "An arbitrary string attached to the object. Often useful for displaying to users and your customer support executive", "nullable": true }, - "status": { - "$ref": "#/components/schemas/RefundStatus" - }, "metadata": { "type": "object", "description": "You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object", @@ -12044,6 +14954,7 @@ }, "RefundType": { "type": "string", + "description": "To indicate whether to refund needs to be instant or scheduled", "enum": [ "scheduled", "instant" @@ -12338,16 +15249,310 @@ } } }, - "RoutingAlgorithm": { + "RoutableChoiceKind": { "type": "string", - "description": "The routing algorithm to be used to process the incoming request from merchant to outgoing payment processor or payment method. The default is 'Custom'", "enum": [ - "round_robin", - "max_conversion", - "min_cost", - "custom" + "OnlyConnector", + "FullStruct" + ] + }, + "RoutableConnectorChoice": { + "type": "object", + "description": "Routable Connector chosen for a payment", + "required": [ + "connector" ], - "example": "custom" + "properties": { + "connector": { + "$ref": "#/components/schemas/RoutableConnectors" + }, + "sub_label": { + "type": "string", + "nullable": true + } + } + }, + "RoutableConnectors": { + "type": "string", + "description": "Connectors eligible for payments routing", + "enum": [ + "aci", + "adyen", + "airwallex", + "authorizedotnet", + "bankofamerica", + "bitpay", + "bambora", + "bluesnap", + "boku", + "braintree", + "cashtocode", + "checkout", + "coinbase", + "cryptopay", + "cybersource", + "dlocal", + "fiserv", + "forte", + "globalpay", + "globepay", + "gocardless", + "helcim", + "iatapay", + "klarna", + "mollie", + "multisafepay", + "nexinets", + "nmi", + "noon", + "nuvei", + "opennode", + "payme", + "paypal", + "payu", + "placetopay", + "powertranz", + "prophetpay", + "rapyd", + "riskified", + "shift4", + "signifyd", + "square", + "stax", + "stripe", + "trustpay", + "tsys", + "volt", + "wise", + "worldline", + "worldpay", + "zen" + ] + }, + "RoutingAlgorithm": { + "oneOf": [ + { + "type": "object", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "single" + ] + }, + "data": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + }, + { + "type": "object", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "priority" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "volume_split" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConnectorVolumeSplit" + } + } + } + }, + { + "type": "object", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "advanced" + ] + }, + "data": { + "$ref": "#/components/schemas/ProgramConnectorSelection" + } + } + } + ], + "description": "Routing Algorithm kind", + "discriminator": { + "propertyName": "type" + } + }, + "RoutingAlgorithmKind": { + "type": "string", + "enum": [ + "single", + "priority", + "volume_split", + "advanced" + ] + }, + "RoutingConfigRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true + }, + "description": { + "type": "string", + "nullable": true + }, + "algorithm": { + "allOf": [ + { + "$ref": "#/components/schemas/RoutingAlgorithm" + } + ], + "nullable": true + }, + "profile_id": { + "type": "string", + "nullable": true + } + } + }, + "RoutingDictionary": { + "type": "object", + "required": [ + "merchant_id", + "records" + ], + "properties": { + "merchant_id": { + "type": "string" + }, + "active_id": { + "type": "string", + "nullable": true + }, + "records": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutingDictionaryRecord" + } + } + } + }, + "RoutingDictionaryRecord": { + "type": "object", + "required": [ + "id", + "name", + "kind", + "description", + "created_at", + "modified_at" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "kind": { + "$ref": "#/components/schemas/RoutingAlgorithmKind" + }, + "description": { + "type": "string" + }, + "created_at": { + "type": "integer", + "format": "int64" + }, + "modified_at": { + "type": "integer", + "format": "int64" + } + } + }, + "RoutingKind": { + "oneOf": [ + { + "$ref": "#/components/schemas/RoutingDictionary" + }, + { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutingDictionaryRecord" + } + } + ] + }, + "RoutingRetrieveResponse": { + "type": "object", + "description": "Response of the retrieved routing configs for a merchant account", + "properties": { + "algorithm": { + "allOf": [ + { + "$ref": "#/components/schemas/MerchantRoutingAlgorithm" + } + ], + "nullable": true + } + } + }, + "RuleConnectorSelection": { + "type": "object", + "description": "Represents a rule\n\n```text\nrule_name: [stripe, adyen, checkout]\n{\npayment.method = card {\npayment.method.cardtype = (credit, debit) {\npayment.method.network = (amex, rupay, diners)\n}\n\npayment.method.cardtype = credit\n}\n}\n```", + "required": [ + "name", + "connectorSelection", + "statements" + ], + "properties": { + "name": { + "type": "string" + }, + "connectorSelection": { + "$ref": "#/components/schemas/ConnectorSelection" + }, + "statements": { + "type": "array", + "items": { + "$ref": "#/components/schemas/IfStatement" + } + } + } }, "SamsungPayWalletData": { "type": "object", @@ -12607,6 +15812,76 @@ } } }, + "StraightThroughAlgorithm": { + "oneOf": [ + { + "type": "object", + "title": "Single", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "single" + ] + }, + "data": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + }, + { + "type": "object", + "title": "Priority", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "priority" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/RoutableConnectorChoice" + } + } + } + }, + { + "type": "object", + "title": "VolumeSplit", + "required": [ + "type", + "data" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "volume_split" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ConnectorVolumeSplit" + } + } + } + } + ], + "discriminator": { + "propertyName": "type" + } + }, "SurchargeDetailsResponse": { "type": "object", "required": [ @@ -12781,6 +16056,157 @@ } } }, + "ValueType": { + "oneOf": [ + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "number" + ] + }, + "value": { + "type": "integer", + "format": "int64", + "description": "Represents a number literal" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "enum_variant" + ] + }, + "value": { + "type": "string", + "description": "Represents an enum variant" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "metadata_variant" + ] + }, + "value": { + "$ref": "#/components/schemas/MetadataValue" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "str_value" + ] + }, + "value": { + "type": "string", + "description": "Represents a arbitrary String value" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "number_array" + ] + }, + "value": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "description": "Represents an array of numbers. This is basically used for\n\"one of the given numbers\" operations\neg: payment.method.amount = (1, 2, 3)" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "enum_variant_array" + ] + }, + "value": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Similar to NumberArray but for enum variants\neg: payment.method.cardtype = (debit, credit)" + } + } + }, + { + "type": "object", + "required": [ + "type", + "value" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "number_comparison_array" + ] + }, + "value": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NumberComparison" + }, + "description": "Like a number array but can include comparisons. Useful for\nconditions like \"500 < amount < 1000\"\neg: payment.amount = (> 500, < 1000)" + } + } + } + ], + "description": "Represents a value in the DSL", + "discriminator": { + "propertyName": "type" + } + }, "VoucherData": { "oneOf": [ { @@ -13278,7 +16704,7 @@ "type": "apiKey", "in": "header", "name": "api-key", - "description": "API keys are the most common method of authentication and can be obtained from the HyperSwitch dashboard." + "description": "Use the API key created under your merchant account from the HyperSwitch dashboard. API key is used to authenticate API requests from your merchant server only. Don't expose this key on a website or embed it in a mobile application." }, "ephemeral_key": { "type": "apiKey", @@ -13327,6 +16753,10 @@ "name": "Disputes", "description": "Manage disputes" }, + { + "name": "API Key", + "description": "Create and manage API Keys" + }, { "name": "Payouts", "description": "Create and manage payouts" @@ -13334,6 +16764,10 @@ { "name": "payment link", "description": "Create payment link" + }, + { + "name": "Routing", + "description": "Create and manage routing configurations" } ] } \ No newline at end of file